1、查找轮廓(转载:http://blog.csdn.net/hitwengqi/article/details/6922051)
轮廓(contour)到底是什么?
一个轮廓对应一系列的店,也就是图像中的一条曲线,OpenCV中一般用序列来存储轮廓信息,序列中的每一个元素是曲线中一个点的位置。
轮廓树?
OpenCV将得到的轮廓聚合成一个轮廓树,把轮廓的包含关系编码到树结构中,保护的轮廓在树中体现为节点。轮廓树有4种拓扑结构,CV_RETR_EXTERNAL、CV_RETR_CCOMP、CV_RETR_TREE、CV_RETR_LIST。
2、表示轮廓
轮廓只是序列所能表示的一种,轮廓类型CvContour是从CvSeq扩展而来,它还含有几个其他的成员,例如颜色、外包矩形区域等。
轮廓时点的序列,可以用来表示图像空间中的曲线,涉及到的几个处理函数如下:
cvFindContours(); //查找到所有轮廓后统一返回轮廓个数
cvStartFindContours(); //每次查找并返回一个轮廓
cvFindNextContour(); //查找剩余的轮廓
cvSubstituteContour(); //替换scannner指向的轮廓
cvEndFindContour(); //结束轮廓查找
cvApproxChains(); //将Freeman链转换为多边形表示,近似拟合。
Freeman链码
在链码中,多边形被表示为一系列的位移,每一个位移有8个方向。
通过以下函数读出每个点:
cvStartReadChainPoints(); //初始化Freeman链CvChainPtReader结构
cvReadChainPoint(); //读取每个点
3、绘制轮廓
在屏幕上绘制检测到的轮廓,用cvDrawContours函数。
例程:根据滑动条参数设置阈值检测轮廓。
--------------------------------------------------------------------------------------------------
FindContours
在二值图像中寻找轮廓
int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,
int header_size=sizeof(CvContour), int mode=CV_RETR_LIST,
int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) );
image
输入的 8-比特、单通道图像. 非零元素被当成 1, 0 象素值保留为 0 - 从而图像被看成二值的。为了从灰度图像中得到这样的二值图像,可以使用 cvThreshold, cvAdaptiveThreshold 或 cvCanny. 本函数改变输入图像内容。
storage
得到的轮廓的存储容器
first_contour
输出参数:包含第一个输出轮廓的指针
header_size
如果 method=CV_CHAIN_CODE,则序列头的大小 >=sizeof(CvChain),否则 >=sizeof(CvContour) .
mode
提取模式.
CV_RETR_EXTERNAL - 只提取最外层的轮廓
CV_RETR_LIST - 提取所有轮廓,并且放置在 list 中
CV_RETR_CCOMP - 提取所有轮廓,并且将其组织为两层的 hierarchy: 顶层为连通域的外围边界,次层为洞的内层边界。
CV_RETR_TREE - 提取所有轮廓,并且重构嵌套轮廓的全部 hierarchy
method
逼近方法 (对所有节点, 不包括使用内部逼近的 CV_RETR_RUNS).
CV_CHAIN_CODE - Freeman 链码的输出轮廓. 其它方法输出多边形(定点序列).
CV_CHAIN_APPROX_NONE - 将所有点由链码形式翻译(转化)为点序列形式
CV_CHAIN_APPROX_SIMPLE - 压缩水平、垂直和对角分割,即函数只保留末端的象素点;
CV_CHAIN_APPROX_TC89_L1,
CV_CHAIN_APPROX_TC89_KCOS - 应用 Teh-Chin 链逼近算法. CV_LINK_RUNS - 通过连接为 1 的水平碎片使用完全不同的轮廓提取算法。仅有 CV_RETR_LIST 提取模式可以在本方法中应用.
offset
每一个轮廓点的偏移量. 当轮廓是从图像 ROI 中提取出来的时候,使用偏移量有用,因为可以从整个图像上下文来对轮廓做分析.
函数 cvFindContours 从二值图像中提取轮廓,并且返回提取轮廓的数目。指针 first_contour 的内容由函数填写。它包含第一个最外层轮廓的指针,如果指针为 NULL,则没有检测到轮廓(比如图像是全黑的)。其它轮廓可以从 first_contour 利用 h_next 和 v_next 链接访问到。 在 cvDrawContours 的样例显示如何使用轮廓来进行连通域的检测。轮廓也可以用来做形状分析和对象识别 - 见CVPR2001 教程中的 squares 样例。该教程可以在 SourceForge 网站上找到。
double cvArcLength();//返回轮廓长多 double cvContourArea();//返回轮廓面积 //包围合和边框 CvRect cvBoundingRect();//包围合 CvBox2D cvMinAreaRect2();//最小包围合 int cvMinEnclosingCircle();//最小保卫圆 CvBox2D cvFitEllipse2();//拟合圆、椭圆 //边框的属性访问 CvRect cvMaxRect();//最小外接矩形 void cvBoxPoints();//求包围合的坐标 double cvPointPolygonTest();//测试点是否在轮廓内 CvSeq* cvPointSeqFromMat();//序列变为矩阵轮廓矩匹配:
我们可以使用cvContoursMoments函数、cvMoments函数方便的得到轮廓的矩集,然后再相应的方法或函数获取各种矩。 特定的矩:cvGetSpatialMoment函数 中心矩:cvGetCentralMoment函数 归一化中心矩:cvGetNormalizedCentralMoment函数 Hu矩:cvGetHuMoments函数7.轮廓的凸包和凸缺陷