Reputation: 61
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
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
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