用Python或C编写的Matlab / Octave bwdist()

时间:2011-03-10 13:26:43

标签: python matlab image-processing numpy scipy

有没有人知道Matlab / Octave bwdist()函数的Python替换?对于给定矩阵,此函数将每个单元的欧几里德距离返回到最接近的非零单元。我看到了一个Octave C实现,一个纯Matlab实现,我想知道是否有人必须在ANSI C(它不包括任何Matlab / Octave头,因此我可以很容易地从Python集成)或纯Python中实现它。

我提到的两个链接如下:

C++

Matlab M-File

作为测试,Matlab代码/输出看起来像这样:

bw= [0   1   0   0   0;
     1   0   0   0   0;
     0   0   0   0   1;
     0   0   0   0   0;
     0   0   1   0   0]

D = bwdist(bw)

D =

   1.00000   0.00000   1.00000   2.00000   2.00000
   0.00000   1.00000   1.41421   1.41421   1.00000
   1.00000   1.41421   2.00000   1.00000   0.00000
   2.00000   1.41421   1.00000   1.41421   1.00000
   2.00000   1.00000   0.00000   1.00000   2.00000

我在Python中测试了一个推荐的distance_transform_edt调用,它给出了这个结果:

将numpy导入为np 来自scipy import ndimage

a = np.array(([0,1,0,0,0],
              [1,0,0,0,0],
              [0,0,0,0,1],
              [0,0,0,0,0],
              [0,0,1,0,0]))

res = ndimage.distance_transform_edt(a)
print res

[[ 0.  1.  0.  0.  0.]
 [ 1.  0.  0.  0.  0.]
 [ 0.  0.  0.  0.  1.]
 [ 0.  0.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.]]

此结果似乎与Octave / Matlab输出不匹配。

4 个答案:

答案 0 :(得分:10)

当Matlab bwdist返回距离最近的非零单元格的距离时,Python distance_transform_edt会将距离“返回到​​最近的背景元素”。 SciPy文档不清楚它认为是什么“背景”,它背后有一些类型转换机制;实际上0是背景,非零是前景。

所以如果我们有矩阵a

>>> a = np.array(([0,1,0,0,0],
              [1,0,0,0,0],
              [0,0,0,0,1],
              [0,0,0,0,0],
              [0,0,1,0,0]))

然后计算相同的结果,我们需要用零替换零和0。考虑矩阵1-a

>>> a
array([[0, 1, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0]])
>>> 1 - a
array([[1, 0, 1, 1, 1],
       [0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1],
       [1, 1, 0, 1, 1]])

在这种情况下,scipy.ndimage.morphology.distance_transform_edt会给出预期的结果:

>>> distance_transform_edt(1-a)
array([[ 1.        ,  0.        ,  1.        ,  2.        ,  2.        ],
       [ 0.        ,  1.        ,  1.41421356,  1.41421356,  1.        ],
       [ 1.        ,  1.41421356,  2.        ,  1.        ,  0.        ],
       [ 2.        ,  1.41421356,  1.        ,  1.41421356,  1.        ],
       [ 2.        ,  1.        ,  0.        ,  1.        ,  2.        ]])

答案 1 :(得分:3)

答案 2 :(得分:2)

无需进行1-a     

>>> distance_transform_edt(a==0)
    array([[ 1.        ,  0.        ,  1.        ,  2.        ,  2.        ],
           [ 0.        ,  1.        ,  1.41421356,  1.41421356,  1.        ],
           [ 1.        ,  1.41421356,  2.        ,  1.        ,  0.        ],
           [ 2.        ,  1.41421356,  1.        ,  1.41421356,  1.        ],
           [ 2.        ,  1.        ,  0.        ,  1.        ,  2.        ]])
    

答案 3 :(得分:0)

我认为您可以使用 OpenCV 中的distanceTransform()来为源图像的每个像素计算到最接近的零像素的距离。

检查此链接:https://docs.opencv.org/3.4/d7/d1b/group__imgproc__misc.html#ga8a0b7fdfcb7a13dde018988ba3a43042