scipy distance_transform_edt 函数如何工作?

How does the scipy distance_transform_edt function work?

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函数returns同一个数组:

[[ 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函数returns这个:

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

这更有意义,因为它将 "distance" 返回到最近的一个。

从文档字符串中不清楚,但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.   ]])

您可以通过将 distance_transform_edt() 应用于 np.logical_not(a)(即反转前景和背景)来获得与 Matlab 的 bwdist(a) 等效的结果:

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]])

Warren 已经解释了 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.]])