图像的连通域标记算法及工具介绍

注:本文大部分内容来源于网络,尤其是原理部分图片全部非本人所作

简介

之前在CSDN上介绍过一个关于如何使用skimage以及opencv标记二值图像的连通域问题。实际上估计不是太多的人懂得标记连通域的原理,加上在医学图像处理中,我们常常用到3维图像,而上述工具只解决了2维图像上的情况,并不支持3维图像的标记(目前还不支持),因此有必要对这个连通域标记算法进行进一步说明。

本文主要介绍两点,一是介绍一种连通域标记的算法,中文翻译过来我给它叫两阶段法(two pass); 另一个方面在2维连通域标记的基础上介绍一个新的高效的3维连通域标记工具

通过这个简单的原理,相信读者可以根据需求自己去写一个更高效的连通域标记算法。

原理

如图1所示,对于一个二值图像,其前景为1,背景为0,我们希望给其相连的前景部分标记为同一个label,不同的连通域标记为不同的label,我们希望得到的最终结果如图2所示(我是真的不知道简书该怎么并排显示图像…)。
图像的连通域标记算法及工具介绍_第1张图片

图像的连通域标记算法及工具介绍_第2张图片

一种标记连通域的方法叫两阶段法,也就是说,通过遍历两次图像上的点就可以完成标记工作,下面我们主要看看它是怎么工作的。

第一阶段

从图3开始,我们从图像的左上角点遍历整个图像。对于第一个黄点(0,0),我们检查它的上边和左边有没有已经标记好的label,显然没有,因此给其标记为1. 如图3.
图像的连通域标记算法及工具介绍_第3张图片
接下来看第二个像素(0, 1), 继续检查它的左边和上边是否有标记好的像素,由于它左边的一个像素已经标记为1, 因此第二个像素也标记为1. 由于第三个像素(0, 2)是一个背景点,因此直接跳过。再看第4个像素(0, 3),由于其左边是背景,因此认为其左边没有标记,同时上边也没有标记,因此需要给它一个新的label,2. 如图4.
图像的连通域标记算法及工具介绍_第4张图片
接下来同理,直到第一行的最后一个像素,我们有了三个标记。如图5.
图像的连通域标记算法及工具介绍_第5张图片
第二行同理,我们看到目前为止还没有出现什么意外,只要检查一个像素的左边和上边是否有标记,如果有,就给它打上同样的标记即可。如图6.
图像的连通域标记算法及工具介绍_第6张图片
到了第三行的第四个元素(2, 3),我们发现了一个意外情况,就是该像素的上边有了一个label 2,而它的左边同样也有一个label 1,这怎么办呢? 这种情况下,我们给该像素标记为两个label中较小的那个,也就是1,同时还要有另一个操作,就是让label 2隶属于 label 1,如图7.
图像的连通域标记算法及工具介绍_第7张图片

有了上述处理矛盾的情况,我们就可以继续往下标记了。始终坚持以下原则:

  • 如果遇上一个背景点,直接跳过,不做处理。
  • 如果对于一个像素点,其上面和左边都没有标记好的label,那么就从小到达给它一个新的label。
  • 如果对于一个像素点,其上面或者/并且左边已经有了标记好的label,且label不冲突,那就把这个像素也标记成同样的label
  • 如果对于一个像素,其上面和左边都有了label,且两个label冲突了,那么就把该像素标记为较小的那个label,同时记住较大的label隶属于较小的label。

遵循上述原则可以得到图8-12的结果:
图像的连通域标记算法及工具介绍_第8张图片

图像的连通域标记算法及工具介绍_第9张图片

图像的连通域标记算法及工具介绍_第10张图片

图像的连通域标记算法及工具介绍_第11张图片

图像的连通域标记算法及工具介绍_第12张图片
至此我们标记完了图像上的每一个像素,并给他们赋了一个值,唯一的问题在于有些连通域我们看着是一个,但是却给了它两个label,但是好在我们知道他们label的继承关系,因此第二遍就是把具有继承关系的部分给合并成为一个。

第二阶段

依然从左上角点开始遍历,每遍历一个label,都要查查该像素是否具有继承关系。比如第一个像素(0, 0),由于它是1,发现了它有继承关系,但是好在他是父label,因此不用管他;当到了第三个像素(0, 2),是个背景,不需要管它,直接跳过,也不用查继承关系;当到了第四个像素,查到了label 2 具有继承关系,且label 2 隶属于label 1, 不好意思,我们就不要label 2了,直接把它改为label 1,后面的以此类推。图13-16都遵循上述原则。
图像的连通域标记算法及工具介绍_第13张图片

图像的连通域标记算法及工具介绍_第14张图片

图像的连通域标记算法及工具介绍_第15张图片

图像的连通域标记算法及工具介绍_第16张图片
至此,我们第二次遍历完了整个图像,同时也把所有的连通域标记完了。

至此,我们大概了解了两阶段法标记连通域的基本原理,希望能够对读者有所帮助。

工具介绍

这方面的工具很多,我自己常用的有这么3个:一个是scikit image, 一个是opencv3,这两个工具目前只支持2维图像的连通域标记。还有一个是github上的一个开源工具,比较高效的完成了3维图像的连通域标记,也是近期发现的,感谢作者吧,哈哈。

  1. skimage的连通域标记算法
    skimage.messure.label
  2. opencv3的连通域标记算法
    connectedComponents
  3. 一个高效的3d连通域标记算法
    connected-components-3d

参考

1. github-connected-components-3d
2. Connected Component Labelling

你可能感兴趣的:(计算机视觉,python,算法,图像处理)