几种方法用来提取图像轮廓的例子

参考了许多博客,自己整理了一下几种方法用来提取图像轮廓的方法,记录一下

#include
#include
#include
#include

using namespace cv;
using namespace std;


//方法1
void Contours1(Mat &image)
{

	//将image由彩色图像转换成灰度图像
	cvtColor(image,image,CV_BGR2GRAY);
	//再通过阈值函数将其转换为二值图像
	threshold(image,image,160,255,THRESH_BINARY);//设置阈值为160,最大像素值为255
	vector> contours;
	//find轮廓
	findContours(image,contours,1,CHAIN_APPROX_SIMPLE);
	//draw轮廓
	Mat result=Mat::zeros(image.size(),CV_8UC1);
	if(!contours.empty())
	{
		//result:存放轮廓,contours:找到的轮廓,-1:将所有轮廓画出,Scalar(255):由白色画,2:画笔粗细
	drawContours(result,contours,-1,Scalar(255),2);
	imshow("处理图",result);
	}
	
}

//方法2
void Contours2(Mat &image)
{
	Mat img1=Mat::zeros(image.size(),CV_8UC1);
	//将image由彩色图像转换成灰度图像
	cvtColor(image,image,CV_RGB2GRAY);
	//通过阈值函数将其转换为二值图像img1(大小与image一样,是单通道)
	threshold(image,img1,160,255,THRESH_BINARY);//设置阈值为160,最大像素值为255
	vector >contours;//contours轮廓
	vector hierarchy;//hierarchy层次
	//查找轮廓findContours
	findContours(img1,contours,hierarchy,CV_RETR_CCOMP,CHAIN_APPROX_SIMPLE);
	//初始化dst
	Mat dst=Mat::zeros(image.size(),CV_8UC1);
	//开始处理
	if(!contours.empty()&&!hierarchy.empty())
	{	//循环轮廓数
		for (int i = 0; i < contours.size(); i++)
		{
			//循环当前轮廓下的每一个点,contours[i].size()是当前轮廓下的总点数
			for (int j = 0; j < contours[i].size(); j++)
			{
				Point p=Point(contours[i][j].x,contours[i][j].y);
				//给当前轮廓下的每个点设置白色
				dst.at(p)=255;
			}
				//drawContours绘制填充当前的轮廓i
			drawContours(img,contours,i,Scalar(255),1,8,hierarchy);

		}
	}
	imshow("处理图",dst);
}

//方法3
void Contours3(Mat &image)
{
	Mat img;
	GaussianBlur(image,img,Size(3,3),0);
	Canny(img,img,100,250);
	//定义点和向量
	vector >contours;//contours轮廓
	vector hierarchy;//hierarchy层次
	//查找轮廓findContours
	//参数1:为二值图像,可以是灰度图像,一般是经过Canny,拉普拉斯等边缘检测算子处理过的二值图像
	//参数2:contours是一个双向的向量,向量内每个元素保存了一组由连续Point点构成的点集合向量,
	//-------每一组点集就是一个轮廓,有多少轮廓contours就有多少元素
	//参数3:hierarchy向量中每一个元素包含了4个int变量:hierarchy[i][0]~hierarchy[i][3]分别表示第i个轮廓的后一个,前一个,父,内嵌轮廓
	//-------hierarchy向量内的元素和contours轮廓向量内的元素是一一对应的,向量的容量相同。
	//参数4:定义轮廓的检索模式
	//参数5:定义轮廓的近似方法
	//参数6:Point偏移量,所有轮廓信息相对于原始图像对应点的偏移量
	findContours(img,contours,hierarchy,CV_RETR_CCOMP,CHAIN_APPROX_SIMPLE);
	//初始化dst
	Mat dst=Mat::zeros(img.size(),CV_8UC1);
	//开始处理
	if(!contours.empty()&&!hierarchy.empty())
	{	
		for (int i = 0; i < contours.size(); i++)
		{
			for (int j = 0; j < contours[i].size(); j++)
			{
			   
				Point p=Point(contours[i][j].x,contours[i][j].y);
				dst.at(p)=255;
			}
				//绘制填充轮廓
			drawContours(img,contours,i,Scalar(255),1,8,hierarchy);

		}
	}
	imshow("处理图",dst);

}

//方法4
void Contours4(Mat &img)
{
    //将image由彩色图像转换成灰度图像
    cvtColor(img,img,CV_RGB2GRAY);
    //通过阈值转换成二值图像 
    Mat bw=(threshval<128)?(imgthreshval);
    vector> contours;
    //find轮廓
    findContours(bw,contours,1,CHAIN_APPROX_SIMPLE);
    //draw轮廓
    Mat result=Mat::zeros(img.size(),CV_8UC1);
    if(!contours.empty())
    {
        //result:存放轮廓,contours:找到的轮廓,-1:将所有轮廓画出,Scalar(255):由白色画,2:画笔粗细
    drawContours(result,contours,-1,Scalar(255),2);
    imshow("处理图",result);
    }
}

int main()
{
	img=imread("img/logo.png",1);
	
	namedWindow("1");
	imshow("1",img);

	//创建处理窗口
	namedWindow("处理图");
	Contours1(img);//方法1 
        Contours2(img);//方法2
        Contours3(img);//方法3
        Contours4(img);//方法4
waitKey();
return 0;
}
 
  

 
  

 
 

你可能感兴趣的:(Opencv)