本文首发于“小白学视觉”微信公众号,欢迎关注公众号
本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究!
经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。
图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域,连通域分析是指在图像中寻找出彼此互相独立的连通域并将其标记出来。提取图像中不同的连通域是图像处理中较为常用的方法,例如在车牌识别、文字识别、目标检测等领域对感兴趣区域分割与识别。一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响,连通域分析常处理的是二值化后的图像。
在了解图像连通域分析方法之前,首先需要了解图像邻域的概念。图像中两个像素相邻有两种定义方式,分别是4-邻域和8-邻域,这两种领域的定义方式在图6-7给出。4-邻域的定义方式如图6-7中的左侧所示,在这种定义下,两个像素相邻必须在水平和垂直方向上相邻,相邻的两个像素坐标必须只有一位不同而且只能相差1个像素,例如点${P_0}(x,y)$的4-邻域的4个像素点分别为
、
、
和
。8-邻域的定义方式如图6-7中的右侧所示,这种定义下两个像素相邻允许在对角线方向相邻,相邻的两个像素坐标在X方向和Y方向上的最大差值为1,例如点
的8-邻域的8个像素点分别为
、
、
、
、
、
、
、以及
。根据两个像素相邻的定义方式不同,得到的连通域也不相同,因此在分析连通域的同时,一定要声明是在哪种种邻域条件下分析得到的结果。
图6-7 4-邻域和8-邻域的定义方式示意图
常用的图像邻域分析法有两遍扫描法和种子填充法。两遍扫描法会遍历两次图像,第一次遍历图像时会给每一个非0像素赋予一个数字标签,当某个像素的上方和左侧邻域内的像素已经有数字标签时,取两者中的最小值作为当前像素的标签,否则赋予当前像素一个新的数字标签。第一次遍历图像的时候同一个连通域可能会被赋予一个或者多个不同的标签,如图6-8所示,因此第二次遍历需要将这些属于同一个连通域的不同标签合并,最后实现同一个邻域内的所有像素具有相同的标签。图6-8 两遍扫描法中第一遍扫描的结果
种子填充法源于计算机图像学,常用于对某些图形进行填充。该方法首先将所有非0像素放到一个集合中,之后在集合中随机选出一个像素作为种子像素,根据邻域关系不断扩充种子像素所在的连通域,并在集合中删除掉扩充出的像素,直到种子像素所在的连通域无法扩充,之后再从集合中随机选取一个像素作为新的种子像素,重复上述过程直到集合中没有像素。
OpenCV 4提供了用于提取图像中不同连通域的connectedComponents()函数,该函数有两个函数原型,第一种函数原型在代码清单6-4中给出。
代码清单6-4 connectedComponents()函数原型1
1. int cv::connectedComponents(InputArray image,
2. OutputArray labels,
3. int connectivity,
4. int ltype,
5. int ccltype
6. )image:待标记不同连通域的单通道图像,数据类型必须为CV_8U。
labels:标记不同连通域后的输出图像ÿ