Matlab / Octave bwdist () in Python or C

Does anyone know of a Python replacement for the Matlab / Octave bwdist () function? This function returns the Euclidean distance of each cell to the nearest non-zero cell for a given matrix. I saw the Octave C implementation, the pure Matlab implementation, and I was wondering if anyone needed to implement this in ANSI C (which does not contain Matlab / Octave headers, so I can easily integrate with Python) or in pure Python.

Both of the links I mentioned are listed below:

C ++

Matlab M-File

As a test, the Matlab code / output looks something like this:

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 

I tested the recommended distance_transform_edt call in Python, which gave this result:

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

This result does not seem to match the output of Octave / Matlab.

+8
python numpy scipy image-processing matlab
source share
3 answers

While Matlab bwdist returns the distance to the nearest non-zero cell, Python distance_transform_edt returns the distance "to the nearest background element". The SciPy documentation is not clear about what it considers to be the “background”; there are some type conversion mechanisms behind it; in practice, 0 is the background; non-zero is the foreground.

So, if we have a matrix 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])) 

then to calculate the same result we need to replace them with zeros and zeros by ones, for example. consider the matrix 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]]) 

In this case, scipy.ndimage.morphology.distance_transform_edt gives the expected results:

 >>> 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. ]]) 
+9
source share
+3
source share

No need to do 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. ]]) 
+1
source share

All Articles