2011-03-10 2 views
8

Quelqu'un connaît-il un remplacement Python pour la fonction Matlab/Octave bwdist()? Cette fonction renvoie la distance euclidienne de chaque cellule à la cellule non nulle la plus proche pour une matrice donnée. J'ai vu une implémentation d'Octave C, une pure implémentation de Matlab, et je me demandais si quelqu'un devait l'implémenter en ANSI C (qui n'inclut aucun en-tête Matlab/Octave, donc je peux facilement l'intégrer de Python) ou en Python pur.Matlab/Octave bwdist() en Python ou C

Les deux liens que je parlais sont ci-dessous:

C++

Matlab M-File

Comme un test, un code Matlab/sortie ressemble à quelque chose comme ceci:

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 

Je l'ai testé un recommandé distance_transform_edt appel en Python, qui a donné ce résultat:

numpy d'importation comme np de ndimage d'importation 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.]] 

Ce résultat ne semble pas correspondre à la sortie Octave/Matlab.

Répondre

9

Alors que Matlab bwdist renvoie des distances à la cellule non nulle la plus proche, Python distance_transform_edt renvoie des distances "à l'élément d'arrière-plan le plus proche". La documentation de SciPy n'est pas claire sur ce qu'elle considère être le "fond", il y a un mécanisme de conversion de type derrière elle; en pratique 0 est l'arrière-plan, non-zéro est le premier plan.

Donc, si nous avons la matrice 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])) 

puis de calculer le même résultat, nous devons les remplace par des zéros et des zéros avec ceux, par exemple considérer la matrice 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]]) 

Dans ce cas scipy.ndimage.morphology.distance_transform_edt donne les résultats escomptés:

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

Pas besoin de faire le 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.  ]])