15

https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.ndimage.morphology.distance_transform_edt.html

我无法理解欧几里德距离变换函数在 Scipy 中的工作原理。据我了解,它与 Matlab 函数(bwdist)不同。例如,对于输入:

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

scipy.ndimage.distance_transform_edt 函数返回相同的数组:

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

但是 matlab 函数返回这个:

1.4142    1.0000    1.4142    2.2361    3.1623
1.0000         0    1.0000    2.0000    2.2361
1.4142    1.0000    1.4142    1.0000    1.4142
2.2361    2.0000    1.0000         0    1.0000
3.1623    2.2361    1.4142    1.0000    1.4142

这更有意义,因为它将“距离”返回到最近的距离。

4

2 回答 2

20

从文档字符串中不清楚,但distance_transform_edt计算从非零(即非背景)点到最近的零(即背景)点的距离。

例如:

In [42]: x
Out[42]: 
array([[0, 0, 0, 0, 0, 1, 1, 1],
       [0, 1, 1, 1, 0, 1, 1, 1],
       [0, 1, 1, 1, 0, 1, 1, 1],
       [0, 0, 1, 1, 0, 0, 0, 1]])

In [43]: np.set_printoptions(precision=3)  # Easier to read the result with fewer digits.

In [44]: distance_transform_edt(x)
Out[44]: 
array([[ 0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  1.   ,  2.   ,  3.   ],
       [ 0.   ,  1.   ,  1.   ,  1.   ,  0.   ,  1.   ,  2.   ,  2.236],
       [ 0.   ,  1.   ,  1.414,  1.   ,  0.   ,  1.   ,  1.   ,  1.414],
       [ 0.   ,  0.   ,  1.   ,  1.   ,  0.   ,  0.   ,  0.   ,  1.   ]])

bwdist(a)您可以通过应用distance_transform_edt()np.logical_not(a)即反转前景和背景)获得相当于 Matlab 的:

In [71]: a
Out[71]: 
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

In [72]: distance_transform_edt(np.logical_not(a))
Out[72]: 
array([[ 1.414,  1.   ,  1.414,  2.236,  3.162],
       [ 1.   ,  0.   ,  1.   ,  2.   ,  2.236],
       [ 1.414,  1.   ,  1.414,  1.   ,  1.414],
       [ 2.236,  2.   ,  1.   ,  0.   ,  1.   ],
       [ 3.162,  2.236,  1.414,  1.   ,  1.414]])
于 2017-06-27T00:36:42.507 回答
2

沃伦已经解释了它是如何distance_transform_edt工作的。在您的情况下,您可以沿 x 和 y 更改采样单位

ndimage.distance_transform_edt(a)
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

>>> ndimage.distance_transform_edt(a, sampling=[2,2])
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  2.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  2.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

或者

ndimage.distance_transform_edt(a, sampling=[3,3])
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  3.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  3.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])
于 2017-06-27T00:49:34.470 回答