轮廓函数基本都在imgproc.hpp文件中,本文统计了13个相关的函数。
1)void findContours( InputOutputArray image, OutputArrayOfArrays contours,OutputArray hierarchy, int mode, int method, Point offset = Point());
这个函数用来对二值图像进行轮廓检测,并且对边界上的轮廓放弃不做检测.
参数1:image,单通道8bit二值图像矩阵,通过compare , inRange , threshold ,
adaptiveThreshold , Canny等函数处理得到二值图像,当mode为 RETR_CCOMP or RETR_FLOODFILL时,可以使用int 图像数据。
参数2:contours,存储为“vector
参数3:hierarchy,类型为“vector
默认值-1。
参数4:int型的mode,定义轮廓的检索模式:
取值一:CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略
取值二:CV_RETR_LIST 检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1。
取值三:CV_RETR_CCOMP 检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层。
取值四:CV_RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
参数5:int型的method,定义轮廓的近似方法:
取值一:CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内。
取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留。
取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法。
参数6:Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且Point还可以是负值!从ROI图像检测处轮廓,转到原图时,这个参数很有用。
2)double pointPolygonTest( InputArray contour, Point2f pt, bool measureDist );
用于测试一个点是否在多边形中;
参数1:输入向量,findcontour中的每个轮廓。
参数2:当前的像素点(x,y)。
参数3:当measureDist设置为true时,返回距离轮廓点的最小值。若返回值为正,表示点在多边形内部,返回值为负,表示在多边形外部,返回值为0,表示在多边形上。
当measureDist设置为false时,返回 -1、0、1三个固定值。若返回值为+1,表示点在多边形内部,返回值为-1,表示在多边形外部,返回值为0,表示在多边形上。
3)contours内部像素的操作
由于contours是不规则的连通区域,所以不会像矩形那样能够准确抠出原图。这种情况可以采用boundingRect找到矩形区域,建立mask 图像,采用二值图的方式将轮廓内的点设置为255,然后and运算;
用点在轮廓内的方式, pointPolygonTest计算。
4)void convexHull( InputArray points, OutputArray hull,
bool clockwise = false, bool returnPoints = true );
得到轮廓的凸多边形函数。
参数1:轮廓点
参数2:凸多边形的点
参数3:凸多边形点顺时针或者逆时针存储
参数4:true,返回坐标点,否则返回索引
5)void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )
绘制轮廓函数参数详解:
参数1:image表示目标图像,
参数2:contours表示输入的轮廓组,每一组轮廓由点vector构成,
参数3:contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓,
参数4:color为轮廓的颜色,
参数5:thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部,
参数6:lineType为线型,
参数7:为轮廓结构信息,
参数8:为maxLevel
6)Rect boundingRect( InputArray points );
轮廓的外接矩形函数,参数为输入的轮廓点。
7)RotatedRect minAreaRect( InputArray points );
轮廓的最小外接矩形函数,参数为输入的轮廓点。
8)void minEnclosingCircle( InputArray points,
CV_OUT Point2f& center, CV_OUT float& radius );
轮廓的外接圆形函数,参数为输入的轮廓点,得到圆心和角度。
9)double minEnclosingTriangle( InputArray points, CV_OUT OutputArray triangle );
轮廓的外接三角形函数,参数为输入的轮廓点,得到三角形的三个坐标点。
10)double contourArea( InputArray contour, bool oriented = false );
轮廓的面积函数,参数为输入的轮廓点。
11)RotatedRect fitEllipse( InputArray points );
轮廓点拟合椭圆的函数,参数为输入的轮廓点。
12)Moments moments( InputArray array, bool binaryImage = false );
轮廓的外接矩形函数,参数为输入的轮廓点。
13)void HuMoments( const Moments& moments, double hu[7] );
轮廓的外接矩形函数,参数为输入的轮廓点。
vector> m_contours;
vector m_hierarchy;
findContours(image, m_contours, m_hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
convexHull(Mat(m_contours[i]), hull[i], false);
double area = round(contourArea(m_contours[i]));
Rect rc = boundingRect(m_contours[i]);
double tarea = minEnclosingTriangle(m_contours[i], triangle);
Point2f center;
float radius;
minEnclosingCircle(m_contours[i], center, radius); // outer circle
RotatedRect box = minAreaRect(m_contours[i]);
box = fitEllipse(m_contours[i]);
Moments mts = moments( m_contours[i], 0 );
double HuMts[7] = {0};
HuMoments( mts, HuMts);
double contourLen = fabs(arcLength(m_contours[i], 0));