细化二进制图像中的轮廓线

时间:2012-04-02 16:37:58

标签: python image-processing binary

我有一个带轮廓线的二进制图像,需要净化所有不必要像素的每条轮廓线,留下最小连接线。

有人可以向我提供此类问题的来源,代码示例或更多信息以及在哪里寻求帮助吗?

4 个答案:

答案 0 :(得分:3)

实际上有一种称为Zhang-Suen细化算法的算法。您可以在此处找到其代码:http://rosettacode.org/wiki/Zhang-Suen_thinning_algorithm

此外,我在Python中编写了一个矢量化版本,比该代码快10倍左右。这是代码:

def neighbours_vec(image):
    return image[2:,1:-1], image[2:,2:], image[1:-1,2:], image[:-2,2:], image[:-2,1:-1],     image[:-2,:-2], image[1:-1,:-2], image[2:,:-2]

def transitions_vec(P2, P3, P4, P5, P6, P7, P8, P9):
    return ((P3-P2) > 0).astype(int) + ((P4-P3) > 0).astype(int) + \
    ((P5-P4) > 0).astype(int) + ((P6-P5) > 0).astype(int) + \
    ((P7-P6) > 0).astype(int) + ((P8-P7) > 0).astype(int) + \
    ((P9-P8) > 0).astype(int) + ((P2-P9) > 0).astype(int)

def zhangSuen_vec(image, iterations):
    for iter in range (1, iterations):
        print iter
        # step 1    
        P2,P3,P4,P5,P6,P7,P8,P9 = neighbours_vec(image)
        condition0 = image[1:-1,1:-1]
        condition4 = P4*P6*P8
        condition3 = P2*P4*P6
        condition2 = transitions_vec(P2, P3, P4, P5, P6, P7, P8, P9) == 1
        condition1 = (2 <= P2+P3+P4+P5+P6+P7+P8+P9) * (P2+P3+P4+P5+P6+P7+P8+P9 <= 6)
        cond = (condition0 == 1) * (condition4 == 0) * (condition3 == 0) * (condition2 == 1) * (condition1 == 1)
        changing1 = numpy.where(cond == 1)
        image[changing1[0]+1,changing1[1]+1] = 0
        # step 2
        P2,P3,P4,P5,P6,P7,P8,P9 = neighbours_vec(image)
        condition0 = image[1:-1,1:-1]
        condition4 = P2*P6*P8
        condition3 = P2*P4*P8
        condition2 = transitions_vec(P2, P3, P4, P5, P6, P7, P8, P9) == 1
        condition1 = (2 <= P2+P3+P4+P5+P6+P7+P8+P9) * (P2+P3+P4+P5+P6+P7+P8+P9 <= 6)
        cond = (condition0 == 1) * (condition4 == 0) * (condition3 == 0) * (condition2 == 1) * (condition1 == 1)
        changing2 = numpy.where(cond == 1)
        image[changing2[0]+1,changing2[1]+1] = 0
    return image

答案 1 :(得分:2)

如果您正在寻找python实现,请查看scikit-image

One of their examples基本上就是您的用例。

或者,如果你想坚持“直”scipy,你可以使用连续的erosions and dilations using scipy.ndimage来做到这一点。 (正如@AxezDNyde提到的那样。)

编辑:链接已修复。

答案 2 :(得分:1)

二进制图像上的侵蚀和膨胀(反之亦然)的组合可以帮助摆脱像胡椒一样的盐分,留下完整的小线条。关键字是“排名顺序过滤器”和“形态过滤器”。

答案 3 :(得分:0)

PyPi上有一个名为thinning的软件包你可以直接进行安装。它实现了Guo和Hall的细化算法,用于凹凸阵列/ opencv灰度图像。