您的位置:首页 > Web前端

利用OpenCV的convexHull和convexityDefects做凸包(凸壳)检测及凸包(凸壳)的缺陷检测

2016-07-04 13:27 726 查看
要理解凸包(凸壳)检测,首无要知道什么是凸包(凸壳),凸包(凸壳)是指如果在集合A内连接任意两个点的直线段都在A的内部,则称集合A是凸形的。简单点理解,就是一个多边型,没有凹的地方。凸包(凸壳)能包含点集中所有的点,凸包检测常应用在物体识别、手势识别及边界检测等领域。

OpenCV中提供了函数convexHull()用于对物体轮廓凸包进行检测,对形状的凸包缺陷分析时使用convexityDefects()函数。下面分别介绍这两个函数。

convexHull函数原型如下:

 void convexHull( InputArray points, OutputArray hull, bool clockwise = false, bool returnPoints = true );

官方解释如下:

points – Input 2D point set, stored in std::vector or Mat. 

hull – Output convex hull. It is either an integer vector of indices or vector of points. In the first case, the hull elements are 0-based indices of the convex hull points in the original array (since the set of convex hull points is a subset of the original
point set). In the second case, hull elements are the convex hull points themselves. 

storage – Output memory storage in the old API (cvConvexHull2 returns a sequence containing the convex hull points or their indices). 

clockwise – Orientation flag. If it is true, the output convex hull is oriented clockwise. Otherwise, it is oriented counter-clockwise. The usual screen coordinate system is assumed so that the origin is at the top-left corner, x axis is oriented to the right,
and y axis is oriented downwards. 

orientation – Convex hull orientation parameter in the old API, CV_CLOCKWISE or CV_COUNTERCLOCKWISE. 

returnPoints – Operation flag. In case of a matrix, when the flag is true, the function returns convex hull points. Otherwise, it returns indices of the convex hull points. When the output array is std::vector, the flag is ignored, and the output depends on
the type of the vector: std::vector<int> implies returnPoints=true, std::vector<Point> implies returnPoints=false. 
翻译如下:

points:输入二维点集(一般为轮廓点集),这些点集被存储在容器vector或Mat中,在下面的源码中,我是强制转化为了Mat类型。

hull:凸包点集输出。类型要么为整型向量,要么为点集向量,如果是整型向量,那么存储的只是索引,索引的对象是输入二维点集(如果不懂这句话的意思,看一遍下面给出的源码就清楚了)。

clockwise:凸包方向的标志位。如果是true,那么是基于顺时针方向,如果是false,那么是基于反时针方向。我测试了下两种结果下输出凸包,结果是没有任何区别。如下面两幅图所示:





但是,官方还补充了一句话,说在常规的图像显示系统中,通常原点是放在左上角的,x轴往右是正方向,y轴往下是正方向。所以我猜测这个参数的真正含义是设置坐标系方向,即如果为true,那么原点在右下角,x轴往左为正方向,y轴往上是正方向。如果为false,即默认值的话,愿点在左上角,x轴往右是正方向,y轴往下是正方向。

returnPoints:函数输出类型,如果OutputArray是一个矩阵变量(MAT),那么returnPoints==true时,输出点坐标,否则,输出坐标索引,索引的对象是输入二维点集(如果不懂这句话的意思,看一遍下面给出的源码就清楚了)。当然,如果你的OutputArray本来就是一个向量了,那这个参数的值会被无视掉,因为向量在定义的时候是有类型的,要么为int型,要么炎point型。

下面讲解convexHull函数:

在解释这个函数各参数的意义前,先要知道什么叫凸包(凸壳)的缺陷检测?要说明这个问题,配图说明是最好的方式,看了下面两幅图你就知道是怎么回事了!

PS:特别鸣QQ号为383890390的大神的解答!我这里只是对他的解答作个整理!





convexHull函数原型如下

void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects );

三个参数说明如下:

contour:一般就是轮廓检测函数findContours的输出

convexhull:convexHull函数的输出,里面存储的是凸包信息,在这里只能是int类型(即vector<vector<int>>类型),而不能是vector<vector<Point>>类型!

convexityDefects :类型为vector<vector<Vec4i>>类型,每一个凸包缺陷由N个Vec4i来描述,直观上来看每一个Vec4i实际上就是一系列点,这些点很难用语言来解释,看下面两幅图吧!


 


上面的黄色数字标的①②③④四个部分实际上就描述了某个凸包缺陷。所以这个凸包缺陷有四个Vec4i,我们以黄色数字标号为①的来说明,两个紫色的圈就表示了这个凸包缺陷的第①部分在检测到的凸包边上的起始点,分别存储在Vec4i的第0号和第1号位上;红色的圈的坐标存储在第2位,表示轮廓最凹处,很明显这个点在轮廓上;Vec4i的第3位表示第2位的坐标距离凸包边的距离。(PS:我自己都感觉说得有点乱,但是结合图相信大家还是能理解的吧)

下面附使用上面这两个函数进行凸包检测及缺陷检测的源码:

源码请移步帖子 http://opencv66.net/thread-40-1-1.html 查看
源码请移步帖子 http://opencv66.net/thread-40-1-1.html 查看
源码请移步帖子 http://opencv66.net/thread-40-1-1.html 查看
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息