Matlab / Octave bwdist () в Python или C - PullRequest
9 голосов
/ 10 марта 2011

Кто-нибудь знает о замене Python для функции Matlab / Octave bwdist ()?Эта функция возвращает евклидово расстояние каждой ячейки до ближайшей ненулевой ячейки для данной матрицы.Я видел реализацию 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

Я протестировал рекомендуемый вызов distance_transform_edt в Python, который дал такой результат:

import numpy as np from 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.

Ответы [ 3 ]

10 голосов
/ 10 марта 2011

В то время как 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]))

затем для вычисления того же результата нам нужно заменить единицы на нули, а нули на единицы, например, рассмотрим матрицу 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.        ]])
3 голосов
/ 10 марта 2011

Удовлетворяет ли scipy.ndimage.morphology.distance_transform_edt вашим потребностям?

2 голосов
/ 21 февраля 2012

Не нужно делать 1-а

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