2011-03-10 12 views
8

¿Alguien sabe de un reemplazo de Python para la función de Matlab/Octave bwdist()? Esta función devuelve la distancia euclidiana de cada celda a la celda no nula más cercana para una matriz dada. Vi una implementación de Octave C, una implementación pura de Matlab, y me preguntaba si alguien tenía que implementar esto en ANSI C (que no incluye ningún encabezado de Matlab/Octave, así que puedo integrar Python fácilmente) o en Python puro.Matlab/Octave bwdist() en Python o C

Ambos enlaces que he mencionado son a continuación:

C++

Matlab M-File

Como prueba, un Matlab/salida de código se ve algo como esto:

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 

Probé un recomendé La llamada distance_transform_edt en Python, que dio este resultado:

numpy

importación como np de ndimage importación scipy

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

no parece coincidir con este resultado a la salida Octave/Matlab.

Respuesta

9

Mientras Matlab bwdist devuelve distancias a la celda no nula más cercana, Python distance_transform_edt devuelve las distancias "al elemento de fondo más cercano". La documentación de SciPy no es clara sobre lo que considera que es el "fondo", detrás hay algún tipo de maquinaria de conversión; en la práctica 0 es el fondo, el primer plano es distinto de cero.

Así que si tenemos la matriz 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])) 

entonces para calcular el mismo resultado tenemos que sustituye a los que tienen ceros y ceros por otras, por ejemplo considerar matriz 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]]) 

En este caso scipy.ndimage.morphology.distance_transform_edt da los resultados esperados:

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

No hay necesidad de hacer la 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.  ]])