如何使用Python/Opencv连接二值图像中的断线

17

我该如何使这些线连接到目标点?这张图片是通过骨架化过程得到的结果。

骨架化得到的图像

需要连接的点

我正在尝试使用分水岭变换将每条线段分割为区域。


连接轮廓极点以修复断裂的线条/边缘,请查看以下链接:https://dev59.com/NMTra4cB1Zd3GeqPyCKt#71816288 - Jeru Luke
3个回答

21

MikeE的答案很好:在这种情况下,使用膨胀和腐蚀形态学操作可以帮助很多。
我想提出一点改进,利用手头图像的特定结构。不要使用通用卷积核进行膨胀/腐蚀,而是建议使用水平卷积核来连接水平线的端点,但不会将相邻行连接在一起。

这是代码草图(假设输入图像存储在bw numpy 2D数组中):

import cv2, numpy as np

kernel = np.ones((1,20), np.uint8)  # note this is a horizontal kernel
d_im = cv2.dilate(bw, kernel, iterations=1)
e_im = cv2.erode(d_im, kernel, iterations=1) 

你得到的是膨胀后的图像:
enter image description here

请注意,间隙被关闭,同时保留了明显的水平线

还有侵蚀后的图像:
enter image description here

为了消除膨胀/侵蚀造成的伪影,我建议再次提取骨架。
如果进一步对侵蚀后的图像应用骨架形态学操作,则可以得到以下结果:
enter image description here

一旦曲线连接起来,您就不需要使用分水岭分割,而是使用连通组件来标记每条曲线。


1
非常感谢你,Shai! - Thiago Resende

5
由于图像已经是单色的,因此您可以使用形态学转换来关闭断线。
如果您需要示例,请在此处找到文档: http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html#closing 它通过首先扩张图像中的白色区域,然后以相同的量侵蚀回来。有效地关闭了白色区域中的任何孔洞。 更多详细信息和示例可以在这里找到: http://docs.opencv.org/2.4/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html 该策略要求断线中的间隙小于相邻线之间的距离。
如果线条交叉,或者线条彼此太接近,则无法工作。但是我认为在您的示例中它将非常好用。
您还可以使用腐蚀函数 erode 去除第三行以下的伪影。

你计算的时间有多少? - micchr

1
我正在处理一个类似的问题,但它更加复杂,在某些地方线条非常接近,因此形态学变换会将它们合并。如果有其他方法,请建议一下。提前感谢!
针对你的问题,我认为你甚至不需要进行形态学操作。由于你已经将图像骨架化,所以可以简单地设计一个核来检测线条断裂的点,并使用距离和斜率(导数)作为判据来连接这些点。我不知道它是否能够100%工作,但你可以尝试一下。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接