3.9.2 凸轮廓和Douglas-Peucker算法

在处理轮廓时,我们可能会遇到各种形状的主体,包括凸形主体。凸形是指在形状中没有两个点的连接线在形状四周边界之外。

OpenCV提供的计算形状的近似边界多边形的第一个工具是cv2.approxPolyDP。这个函数有3个参数:

·轮廓。

·表示原始轮廓和近似多边形之间最大误差的ε值(值越低,近似值越接近原始轮廓)。

·布尔标志。如果是True,则表示多边形是闭合的。

ε值对于获得有用的轮廓非常重要,所以我们要理解它代表什么。ε是近似多边形周长和原始轮廓线周长之差的最大值。差值越小,近似多边形就越接近原始轮廓。

你可能会问自己,已经有精确表示的轮廓时,为什么还需要一个近似的多边形?因为多边形是用一组直线表示的,如果可以定义多边形,那么许多计算机视觉任务将变得简单,这样它们就可以划分区域,以便进一步操作和处理。

既然我们知道了ε是什么,那么需要获得轮廓周长信息作为参考值。这可以通过OpenCV的cv2.arcLength函数获得:

实际上,我们正在指示OpenCV计算一个近似多边形,使其周长与原始轮廓周长之间只相差ε比率,即原弧长的1%。

OpenCV还提供了一个cv2.convexHull函数,用于获取凸形的轮廓处理信息。这是一个简单的一行表达式:

我们将原始轮廓、近似多边形轮廓和凸包放在同一幅图像中以观察它们之间的差异。为了简化,我们将在黑色背景上绘制轮廓,这样原始主体就不可见了,但是它的轮廓可见,如图3-7所示。

图3-7 原始轮廓、近似多边形轮廓和凸包

如你所见,凸包包围了整个主体,近似多边形是最内层的多边形,两者之间是主要由弧线组成的原始轮廓。

通过将上述所有步骤组合到一个脚本中,进而加载文件,寻找轮廓,将轮廓近似为多边形,寻找凸包并显示可视化效果,代码如下:

这样的代码可以很好地处理简单的图像——只有一个或几个对象,而且只有几种颜色,可以很容易地用阈值分割。可是,在包含多个对象或者多种颜色对象的复杂图像中,颜色阈值和轮廓检测的效果较差。对于这些更具挑战性的情况,我们必须考虑更复杂的算法。