《OpenCV二值图绘制轮廓》

示例代码

/************************************************************************
<*@创建者:OYXL
<*@时间:2018/6/20
<*@实现功能:图片或者视频进行二值化,可选择
<*@备注:图片二值化,显示图像必须和二值响应函数放在一块,不然不会执行
<*@备注:on_Threshold( int, void* );不可更改参数
<*@修改:添加了边缘检测和绘制轮廓以及最小包围矩形功能
************************************************************************/
#include "opencv2/opencv.hpp"
#include "iostream"

using namespace std;
using namespace cv;

int Picture();
int Video();
void on_Threshold( int, void* );//回调函数
void ChooseMode();

Mat img,copyImage,gray,binary,imgThresholded;
int thr=100;
int num=0;
int BinaryType=2;
vector<vector<Point>> contours;  
vector<Vec4i> Hierarchy;

int main()
{
	ChooseMode();
	if (num==1)
	{
		Picture();
	}
	else if (num==2)
	{
		Video();
	}
	return 0;
}
//<图片二值化函数
int Picture()
{
	namedWindow("TrackBar", CV_WINDOW_AUTOSIZE); //create a window called "Control"
	createTrackbar("THR", "TrackBar", &thr, 255,on_Threshold); //Hue (0 - 180)
	img=imread("F:\\磊神图片\\9527.png");
	img.copyTo(copyImage);
	if (!img.data)
	{
		cout << "picture failed to load !" << endl;
		return -1;
	}
	cvtColor(img, gray, CV_BGR2GRAY);//<必须先进行二值化操作,不然得到的二值图是彩色的
	GaussianBlur(gray, gray, Size(15, 15), 0, 0);
	on_Threshold(0,0);
	
	//threshold(gray, binary, thr, 255, 4);
	
	waitKey(0);
}
//<视频二值化函数
int Video()
{
	namedWindow("TrackBar", CV_WINDOW_AUTOSIZE); //create a window called "Control"
	createTrackbar("THR", "TrackBar", &thr, 255,0); //Hue (0 - 180)
	VideoCapture capture("F:\\磊神视频\\noglasses.avi");
	while (true)
	{
		capture >> img;
		if (img.empty())	//判断摄像头是否打开  
		{
			cout << "Video failed to load !" << endl;
			return -1;
		}
		cvtColor(img, gray, CV_BGR2GRAY);
		GaussianBlur(gray, gray, Size(15, 15), 0, 0);
		threshold(gray, binary, thr, 255, BinaryType);
		Canny(binary,imgThresholded,3,9,3);  
		findContours(imgThresholded,contours,Hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));   
		vector<RotatedRect> box(contours.size());  
		Point2f vertex[4];  
		if(contours.size()>0)  
		{  
			for (int i=0;i<contours.size();i++)  
			{  
				box[i]=minAreaRect(Mat(contours[i]));  
				box[i].points(vertex);  
				drawContours(img,contours,i,Scalar(0,0,255),2,8,Hierarchy,0,Point(0,0));  
				for (int j=0;j<4;j++)  
				{  
					line(img,vertex[j],vertex[(j+1)%4],Scalar(255,0,255),2,CV_AA);  
				}  
			}  
		}  
		imshow("src", img);
		imshow("binary image", binary);
		waitKey(1);
	}
}
/************************************************************************
<*@阈值回调函数
<*@显示二值图片需要放在这里,响应一次,显示一次
************************************************************************/
void on_Threshold( int, void* )
{
	//<调用阈值函数
	copyImage.copyTo(img);//<绘制轮廓不会消除,需要更换未经处理的图片重新绘制
	threshold(gray,binary,thr,255,BinaryType);
	Canny(binary,imgThresholded,3,9,3);  
	findContours(imgThresholded,contours,Hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));   
	vector<RotatedRect> box(contours.size());  
	Point2f vertex[4];  
	if(contours.size()>0)  
	{  
		for (int i=0;i<contours.size();i++)  
		{  
			box[i]=minAreaRect(Mat(contours[i]));  
			box[i].points(vertex);  
			drawContours(img,contours,i,Scalar(0,0,255),2,8,Hierarchy,0,Point(0,0));  
			for (int j=0;j<4;j++)  
			{  
				line(img,vertex[j],vertex[(j+1)%4],Scalar(255,0,255),2,CV_AA);  
			}  
		}  
	}  
	imshow("binary image", binary);
	imshow("src", img);
	
}
void ChooseMode()
{
	cout<<"Please enter the type you want to select:"<<endl;
	cout<<"0、THRESH_BINARY"<<endl;			//<大于阈值为白,小于为黑
	cout<<"1、THRESH_BINARY_INV"<<endl;		//<大于阈值为黑,小于为白
	cout<<"2、THRESH_TRUNC"<<endl;			//<大于阈值为阈值,小于为原值
	cout<<"3、THRESH_TOZERO"<<endl;			//<大于阈值为原值,小于为黑
	cout<<"4、THRESH_TOZERO_INV"<<endl;		//<小于阈值为原值,于为黑
	cin>>BinaryType;
	cout<<"Please enter the mode you want to select:"<<endl;
	cout<<"1、Picture Mode"<<endl;
	cout<<"2、Video Mode"<<endl;
	cin>>num;
}

代码分析

单轮廓

多轮廓

轮廓矩

轮廓矩中心点

效果图




猜你喜欢

转载自blog.csdn.net/mars_xiaolei/article/details/80777072