OpenCV实现轮廓的发现

  

<强>前言:

  

,,,,,,当我们通过阈值分割提取到图像中的目标物体后,我们就需要通过边缘检测来提取目标物体的轮廓,使用这两种方法基本能够确定物体的边缘或者前景。接下来,我们通常需要做的是拟合这些边缘的前景,如拟合出包含前景或者边缘像素点的最小外包矩形、圆、凸包等几何形状,为计算它们的面积或者模板匹配等操作打下坚实的基础。

  

<强>一、查找,绘制轮廓

  

,,,,,,首先了解一下轮廓的定义。一个轮廓代表一系列的点(像素),这一系列的点构成一个有序的点集,所以可以把一个轮廓理解为一个有序的点集。

  

  

,,,,,,,,在OpenCV中,提供了一个函数返回或者输出一个有序的点集或者有序的点集的集合(指多个有序的点集),函数findContour是从二值图像中来计算轮廓的,它可以使用精明的()函数处理的图像,因为这样的图像含有边缘像素,也可以使用阈值()或者adaptiveThreshold()处理后的图像,其边缘隐含在正负区域的交界处。这个函数的声明如下:

        空白findContours (InputOutputArray形象,OutputArrayOfArrays轮廓,OutputArray层次结构,int模式,int方法,点抵消=点());      

其参数解释如下:

  

(1)图片:单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过精明的,拉普拉斯等边缘检测算子处理过的二值图像;

  

(2)轮廓:vector祝辞类型,是一个向量,并且是一个双重向量,向量内每个元素保存了一组由连续的时候点构成的点的集合的向量,每一组点的点集就是一个轮廓。有多少轮廓,向量轮廓就有多少元素。

  

(3)等级:vector类型,Vec4i是Vec   

(4)模式:int类型的,定义轮廓的检索模式:

  

取值一:CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略;

  

取值二:CV_RETR_LIST,检测所有的轮廓,包括内围,外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所以层次结构向量内所有元素的第3,第4个分量都会被置为1,具体下文会讲到;

  

,取值三:CV_RETR_CCOMP,检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层;

  

,取值四:CV_RETR_TREE,检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。

  

(5)方法:int类型,定义轮廓的近似方法:

  

取值一:CV_CHAIN_APPROX_NONE保存物体边界上所有连续的轮廓点到轮廓向量内,

  

取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入轮廓向量内,拐点与拐点之间直线段上的信息点不予保留;

  

取值三和四:CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl链近似算法;

  

(6)的观点:偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且点还可以是负值。

  

<强>注意事项:

  

显然,从函数名可以看出“寻找轮廓”的意思。我们可以通过边缘检测算法得到边缘二值图或者前景二值图,二值图的边缘像素或者前景像素就可以被看出是由多个轮廓(点集)组成的。函数findContours的作用就是将二值图的边缘像素或者前景像素拆分成多个轮廓,便于分开讨论每一个轮廓,其中参数形象代表一张二值图,轮廓代表输出的多个轮廓。对于该函数的c++ API,对一个轮廓的描述用vector,那么多个轮廓(多个点集)如何表示呢& # 63;即参数轮廓是什么数据结构呢?在c++ API中,用vector在描述多个轮廓,即将多个轮廓存在一个向量中。

  

<强> 1.2 drawContours()函数

OpenCV实现轮廓的发现