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学习篇(8)轮廓的查找、表达、绘制、特性及匹配

前言     轮廓是构成任何一个形状的边界或外形线。前面讲了如何根据色彩及色彩的分布(直方图对比和模板匹配)来进行匹配,现在我们来看看如何利用物体的轮廓。包括以下内容:轮廓的查找、表达方式、组织方式...
  • qq_27789527
  • qq_27789527
  • 2015年11月06日 10:53
  • 1470

OpenCV3.0 Examples学习笔记(1)-contours2.cpp-通过findContours 函数实现轮廓提取

简介 这个系列的目的是通过对OpenCV示例,进一步了解OpenCV函数的使用,不涉及具体原理。 示例代码地址:http://docs.opencv.org/3.0.0/examples.html(安...
  • u012566751
  • u012566751
  • 2017年01月04日 12:53
  • 4218

opencv学习(四十二)之多边形包围图像轮廓

首先介绍一个逼近多边形的函数approxPolyDP(),其定义如下:void cv::approxPolyDP ( InputArray curve, ...
  • keith_bb
  • keith_bb
  • 2017年04月16日 12:40
  • 3426

【OpenCV学习笔记 010】提取直线、轮廓及连通区域

  • 2016年10月01日 22:57
  • 2.38MB
  • 下载

opencv学习手势轮廓识别源代码

  • 2015年01月13日 20:53
  • 4.26MB
  • 下载

OpenCV学习笔记(8)—轮廓的匹配

一个跟轮廓相关的最常用到的功能是匹配两个轮廓.如果有两个轮廓,如何比较它们;或者如何比较一个轮廓和另一个抽象模板. 矩 比较两个轮廓最简洁的方式是比较他们的轮廓矩.这里先简短介绍一个矩的含义.简单...
  • cc7829290
  • cc7829290
  • 2013年05月15日 14:57
  • 5068

【OpenCV学习笔记】三十一、轮廓特征属性及应用(八)——颜色物体识别与跟踪

轮廓特征属性及应用(八)——颜色物体识别与跟踪 颜色空间转换——cvtColor() 颜色区间范围筛选——inRange() 先上ppt: ...
  • abc8730866
  • abc8730866
  • 2017年04月07日 15:29
  • 2031

OpenCV学习笔记(19):检测轮廓,直线,圆以及直线拟合

检测轮廓时我们使用canny边沿检测算法,这个算法其实也是基于梯度的。但是,与传统的梯度算法求边沿不同的是: 1.它可以精确的定位边沿的位置。通过沿幅角方向检测模值的极大值点,即边缘点,遍历8个...
  • huangli19870217
  • huangli19870217
  • 2014年03月25日 08:57
  • 1170

opencv学习_10 (图像和轮廓的匹配(hu矩))

图像和轮廓的匹配(hu矩)  (1)hu矩的概念,我也总结了但是我不过多的阐述,因为我也不是太理解,只知道它具有平移,旋转,尺度不变性,详细见别人的这篇 blog:http://blog.csdn.n...
  • Lu597203933
  • Lu597203933
  • 2013年11月08日 20:07
  • 18105

opencv学习——计算轮廓中心点、周长、面积及近似

import cv2 import numpy as np import matplotlib.pylab as plt import scipy.misc as misc'''''' img = c...
  • ei1990
  • ei1990
  • 2017年10月30日 18:42
  • 280
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenCV学习:轮廓
举报原因:
原因补充:

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