Bibi
Bibi

Reputation: 53

How to compute a spatial distance matrix from a given value

I've been looking for a way to (efficiently) compute a distance matrix from a target value and an input matrix.

If you consider an input array as:

[0 0 1 2 5 2 1]  
[0 0 2 3 5 2 1]  
[0 1 1 2 5 4 1]  
[1 1 1 2 5 4 0]

Ho do you compute the spatial distance matrix associated to the target value 0?

i.e. what is the distance from each pixel to the closest 0 value?

Thanks in advance

Upvotes: 1

Views: 457

Answers (1)

Divakar
Divakar

Reputation: 221524

You are looking for scipy.ndimage.morphology.distance_transform_edt. It operates on a binary array and computes euclidean distances on each TRUE position to the nearest background FALSE position. In our case, since we want to find out distances from nearest 0s, so the background is 0. Now, under the hoods, it converts the input to a binary array assuming 0 as the background, so we can just use it with the default parameters. Hence, it would be as simple as -

In [179]: a
Out[179]: 
array([[0, 0, 1, 2, 5, 2, 1],
       [0, 0, 2, 3, 5, 2, 1],
       [0, 1, 1, 2, 5, 4, 1],
       [1, 1, 1, 2, 5, 4, 0]])

In [180]: from scipy import ndimage

In [181]: ndimage.distance_transform_edt(a)
Out[181]: 
array([[0.  , 0.  , 1.  , 2.  , 3.  , 3.16, 3.  ],
       [0.  , 0.  , 1.  , 2.  , 2.83, 2.24, 2.  ],
       [0.  , 1.  , 1.41, 2.24, 2.24, 1.41, 1.  ],
       [1.  , 1.41, 2.24, 2.83, 2.  , 1.  , 0.  ]])

Solving for generic case

Now, let's say we want to find out distances from nearest 1s, then it would be -

In [183]: background = 1 # element from which distances are to be computed

# compare this with original array, a to verify
In [184]: ndimage.distance_transform_edt(a!=background)
Out[184]: 
array([[2.  , 1.  , 0.  , 1.  , 2.  , 1.  , 0.  ],
       [1.41, 1.  , 1.  , 1.41, 2.  , 1.  , 0.  ],
       [1.  , 0.  , 0.  , 1.  , 2.  , 1.  , 0.  ],
       [0.  , 0.  , 0.  , 1.  , 2.  , 1.41, 1.  ]])

Upvotes: 1

Related Questions