OpenCV学习:轮廓

原创 2013年02月08日 13:07:58

今天学习下openCV里发现并跟踪图像轮廓的函数。主要函数是cvFindContour,道理不难理解,就是一个比较模糊的点:什么是内轮廓什么是外轮廓。

外轮廓和内轮廓:

连通域:cvFindContour函数输入的图像是二值化的图像,所谓的二值化是指图像矩阵中的所有非零数据都当做1或者255,即函数看待图像时会“非黑即白”。对于这幅二值化的图像,认定所有0值点构成连通域,即这块区域没有黑色区域的阻挡。内轮廓和外轮廓的定义也是基于连通域。

如下图,①④⑤⑥位于连通域的外围,②③位于连通域的内侧,所以①④⑤⑥是图像的外轮廓,②③是图像的内轮廓。


cvFindContour中涉及图像轮廓的存储问题,存储方式由第五个参数决定。当参数设定为CV_RETR_CCOMP,上图存储形式如下

内轮廓是外轮廓的“二级轮廓”。

如下图所示,下面这幅图是上图的“对立图”,此时的外轮廓变为②③,内轮廓是①④⑤⑥。

外轮廓和内轮廓明白后,就能明白cvFindContour中的轮廓了。下面是一段小程序:用红线标出内轮廓,绿线标出外轮廓。

int main()
{
	int height,width,step,channels;
	IplImage *contour_img=cvLoadImage("E:\\test3.jpg",-1);//3通道图像
	if (!contour_img)
	{
		cout<<"File can't be opened"<<endl;
	}
 
	IplImage *band1=cvCreateImage(cvGetSize(contour_img),IPL_DEPTH_8U,1);
	IplImage *dst=  cvCreateImage(cvGetSize(contour_img),IPL_DEPTH_8U,3);
  
	cvCopy(contour_img,dst);
	cvSplit(contour_img,band1,NULL,NULL,NULL);
 
	cvSaveImage("E:\\reverse.jpg",band1);
	
	int i,j;
	height  =dst->height;
	width   =dst->width;
	step    =dst->widthStep;
	channels=dst->nChannels;
	cout<<"height: "<<height<<" width: "<<width<<" step: "<<step<<" channels: "<<channels<<endl;
 
	CvMemStorage *storage=cvCreateMemStorage(0);
	CvSeq *contour=0;

	int NoContours=cvFindContours(band1,storage,&contour,sizeof(CvContour),CV_RETR_CCOMP,CV_CHAIN_APPROX_NONE);
	cout<<"No of contours: "<<NoContours<<endl;
	CvPoint *currentPoint;
	unsigned char *p_band;
	CvSeq *v_list;

	int total;

	for (;contour!=0;contour=contour->h_next)
	{
		total=contour->total;//获得点的个数
		cout<<"total: "<<total<<endl;
		for (i=0;i<total;i++)
		{
			currentPoint=(CvPoint *)cvGetSeqElem(contour,i);
			p_band=(unsigned char *)dst->imageData+currentPoint->y*step+channels*currentPoint->x;
			*p_band=0;
			*(p_band+1)=255;
			*(p_band+2)=0;
		}
		v_list=contour->v_next;
		for (;v_list!=NULL;v_list=v_list->h_next)
		{
			total=v_list->total;
			for (i=0;i<total;i++)
			{
				currentPoint=(CvPoint *)cvGetSeqElem(v_list,i);
				p_band=(unsigned char *)dst->imageData+currentPoint->y*step+channels*currentPoint->x;
				*p_band=0;
				*(p_band+1)=2;
				*(p_band+2)=255;
			}
		}
		
	}
	cvSaveImage("E:\\reverse3.jpg",dst);
	return 0;
}


opencv的轮廓高级应用

参考来自:http://blog.sina.com.cn/s/blog_662c785901011i7z.html
  • shhu1993
  • shhu1993
  • 2014-12-08 21:41:30
  • 360

opencv轮廓高级应用(轮廓匹配,几何直方图)

opencv轮廓高级应用(轮廓匹配,几何直方图)   (2012-07-20 10:40:12) 转载▼ 标签:  机器视觉   opencv   ...
  • xph23
  • xph23
  • 2014-05-04 00:06:02
  • 2431

OpenCv轮廓高级应用(轮廓匹配,几何直方图)

虽然Canny之类的边缘检测算法可以根据像素间的差异检测出轮廓边界的像素,但是它并没有将轮廓作为一个整体。下一步是要将这些边缘像素组装成轮廓。 轮廓是构成任何一个形状的边界或外形线。直方图对比和...
  • u013160060
  • u013160060
  • 2015-03-11 15:34:21
  • 408

Opencv学习之查找并绘制轮廓

Opencv学习之查找并绘制轮廓寻找轮廓–findContours函数一个轮廓一般对应一系列的点,也就是图像中的一条曲线。 void findContours(inputArray,outputAr...
  • qq_31531635
  • qq_31531635
  • 2017-06-23 20:25:59
  • 402

opencv学习心得(六)新版本绘制外形轮廓。

最近在研究opencv2.3.1版本函数,因为函数结构使用C++类型的,所以在一些函数调用上有很多差别,但是在运行速度上提高不少,所以还是新版本好用。其实在新版本发布是,会有相关的使用手册,很多例子会...
  • poiiy333
  • poiiy333
  • 2013-05-16 16:10:40
  • 1828

【opencv】目标识别——轮廓匹配

试了试opencv里面的轮廓匹配来识别物体 //对轮廓按面积降序排列 bool biggerSort(vector v1, vector v2) { return contourA...
  • qq_15947787
  • qq_15947787
  • 2017-05-26 22:03:13
  • 5774

opencv轮廓高级应用(轮廓匹…

原文地址:opencv轮廓高级应用(轮廓匹配,几何直方图)作者:zhliangOpenCv轮廓高级应用(轮廓匹配,几何直方图)     最近再次用到了opencv轮廓,在这里结合作者冰山一角的博客(h...
  • iloveayu
  • iloveayu
  • 2017-08-05 17:43:53
  • 516

opencv学习笔记(三十五)查找轮廓

现在终于可以讨论轮廓的问题了。首先我们需要了解轮廓到底是什么?一个轮廓一般对应一系列的点,也就是图像中的一条曲线。表示方法可能根据不同情况而有所不同。有多种方法可以表示曲线。在OpenCV中一般用序列...
  • u014751607
  • u014751607
  • 2017-03-11 09:48:57
  • 530

Opencv学习笔记 第三篇 轮廓检测(一)

opencv学习笔记 第三篇 轮廓检测的学习虽然Canny之类的边缘检测可以根据像素之间的差异测出轮廓边界像素,但没有作为一个整体,cvFindContours()可以将边缘像素组装成轮廓,我们循序渐...
  • qq1376725255
  • qq1376725255
  • 2015-05-09 09:04:50
  • 598

opencv轮廓高级应用(轮廓匹配,几何直方图)

最近再次用到了opencv轮廓,在这里结合作者冰山一角的博客(http://www.cnblogs.com/slysky/)以及自己的体会在此稍加说明。其程序主要参见冰山一角的Blog,遗憾的是代码是...
  • Yuzhiyuxia
  • Yuzhiyuxia
  • 2013-05-13 19:24:42
  • 2339
收藏助手
不良信息举报
您举报文章:OpenCV学习:轮廓
举报原因:
原因补充:

(最多只允许输入30个字)