引言
当我们通过阈值分割提取到图像中的目标物体后,我们就需要通过边缘检测来提取目标物体的轮廓,使用这两种方法基本能够确定物体的边缘或者前景。接下来,我们通常需要做的是拟合这些边缘的前景,如拟合出包含前景或者边缘像素点的最小外包矩形、圆、凸包等几何形状,为计算它们的面积或者模板匹配等操作打下坚实的基础。
轮廓发现是是基于图像边缘提取的基础,寻找对象轮廓的方法,所以边缘提取的阈值选定会影响最终轮廓的发现。
相关函数
首先了解一下轮廓的定义。一个轮廓代表一系列的点(像素),这一系列的点构成一个有序的点集,所以可以把一个轮廓理解为一个有序的点集。
1.1 findContour()函数,发现轮廓
在OpenCV中,提供了一个函数返回或者输出一个有序的点集或者有序的点集的集合(指多个有序的点集),函数findContour是从二值图像中来计算轮廓的,它可以使用Canny()函数处理的图像,因为这样的图像含有边缘像素;也可以使用threshold()或者adaptiveThreshold()处理后的图像,其边缘隐含在正负区域的交界处。这个函数的声明如下:
void findContours(InputOutputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,int method,
Point offset = Point());
其参数解释如下:
(1)image:单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;
(2)contours:vector<vector<Point>>类型,是一个向量,并且是一个双重向量,向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓。有多少轮廓,向量contours就有多少元素。
(3)hierarchy:vector<Vec4i> 类型, Vec4i是Vec<int,4>的别名,即容器内每一个元素都是一个包含了4个int型变量的向量,所以从定义上看,hierarchy也是一个向量,向量内每个元素保存了一个包含4个int整型的数组。向量hiararchy内的元素和轮廓向量contours内的元素是一一对应的,向量的容量相同。hierarchy向量内每一个元素的4个int型变量——hierarchy[i][0] ~hierarchy[i][3],分别表示第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果当前轮廓没有对应的后一个轮廓、前一个轮廓、父轮廓或内嵌轮廓的话,则hierarchy[i][0] ~hierarchy[i][3]