LM Anovitz
LM Anovitz

Reputation: 61

distance in 3D binary array to nearest point of other type

I have a 3D numpy array consisting of 1's and zeros defining open versus filled space in a porous solid (it's currently a numpy Int64 array). I want to determine the euclidian distance from each of the "1" points (voxels) to its nearest zero point. Is there a simple way to do this?

Upvotes: 1

Views: 1223

Answers (2)

Jaime
Jaime

Reputation: 67427

What you are asking for is the distance transform, which you can compute using scipy's ndimage package and its distance_transform_edt function:

>>> import numpy as np
>>> import scipy.ndimage as ndi
>>> img = np.random.randint(2, size=(5, 5))
>>> img
array([[0, 0, 1, 1, 1],
       [1, 0, 1, 0, 1],
       [0, 1, 1, 1, 1],
       [0, 0, 0, 1, 1],
       [0, 1, 1, 1, 1]])
>>> ndi.distance_transform_edt(img)
array([[ 0.        ,  0.        ,  1.        ,  1.        ,  1.41421356],
       [ 1.        ,  0.        ,  1.        ,  0.        ,  1.        ],
       [ 0.        ,  1.        ,  1.        ,  1.        ,  1.41421356],
       [ 0.        ,  0.        ,  0.        ,  1.        ,  2.        ],
       [ 0.        ,  1.        ,  1.        ,  1.41421356,  2.23606798]])

Upvotes: 4

Praveen
Praveen

Reputation: 7222

If val contains the value (0 or 1) and pos contains the positions of each of these voxels, then you could use scipy.spatial.distance.cdist to compute all pairwise distances:

import numpy as np
from scipy.spatial.distance import cdist
# Find the points corresponding to zeros and ones
zero_indices = (val == 0)
one_indices = (val == 1)
# Compute all pairwise distances between zero-points and one-points
pairwise_distances = distance.cdist(pos[zero_indices, :], pos[one_indices, :])
# Choose the minimum distance
min_dist = np.min(pairwise_distances, axis=0)

Upvotes: 0

Related Questions