Download this file

42 lines (37 with data), 1.5 kB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def findSpheres(mask):
"""Calculates thickness by finding the largest sphere containing each point."""
import numpy as np
from math import floor
from scipy.ndimage import distance_transform_edt
dist = distance_transform_edt(mask)
rads = dist.copy()
a,b,c=np.nonzero(mask)
order = np.argsort(dist[a,b,c])
for n in order:
# For each point, find the thickness radius at that point from the distance map
x=a[n]
y=b[n]
z=c[n]
r=dist[x,y,z]
rf = floor(r)
# Check that ranges are inside boundaries
xr0=min(rf,x)
xr1=min(rf, dist.shape[0]-x-1)
yr0=min(rf,y)
yr1=min(rf, dist.shape[1]-y-1)
zr0=min(rf,z)
zr1=min(rf, dist.shape[2]-z-1)
# Creates a cubic view of the region of interest
roi=rads[x-xr0:x+xr1+1, y-yr0:y+yr1+1, z-zr0:z+zr1+1]
# Creates mask of sphere within radius
i,j,k=np.mgrid[-xr0:xr1+1,-yr0:yr1+1,-zr0:zr1+1]
mask = approxLTE(i**2 + j**2 + k**2, np.full_like(roi, r**2))
mask = np.bitwise_and(mask, roi>0)
# Sets all values inside region of interest and sphere mask to the radius if it is higher than their current value
mask = mask * r
roi[:,:,:] = np.maximum(roi, mask)
return rads[np.nonzero(rads)]
def approxLTE(a, b):
# Peforms array elementwise less than or equal comparisons with some tolerance for floating point values
import numpy as np
return np.bitwise_or(a <= b, np.isclose(a,b))