Skip to content

Commit 581bed9

Browse files
Add example scripts for geodesic distances
1 parent f7b580a commit 581bed9

5 files changed

Lines changed: 87 additions & 0 deletions

File tree

5.2 KB
Binary file not shown.

examples/distance/geodesic_2d.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import imageio.v3 as imageio
2+
import napari
3+
import numpy as np
4+
5+
from bioimage_cpp.distance import geodesic_distance_field, distance_transform
6+
7+
mask = (imageio.imread("./complex-shape.tif") == 2).astype("uint8")
8+
# compute the most central point --- distance transform maximum
9+
max_point = np.argmax(distance_transform(mask).ravel())
10+
max_point = np.unravel_index(max_point, mask.shape)
11+
12+
sources = np.array([max_point])
13+
distance_field, gradients = geodesic_distance_field(mask, sources, return_gradient=True)
14+
gradients = gradients.transpose((2, 0, 1))
15+
16+
v = napari.Viewer()
17+
v.add_image(distance_field)
18+
v.add_image(gradients)
19+
v.add_labels(mask)
20+
v.add_points([max_point])
21+
napari.run()

examples/distance/geodesic_3d.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import napari
2+
import numpy as np
3+
4+
from bioimage_cpp.distance import geodesic_distance_field, distance_transform
5+
from shape import make_shape
6+
7+
mask = make_shape()
8+
max_point = np.argmax(distance_transform(mask).ravel())
9+
max_point = np.unravel_index(max_point, mask.shape)
10+
11+
sources = np.array([max_point])
12+
distance_field, gradients = geodesic_distance_field(mask, sources, return_gradient=True)
13+
gradients = gradients.transpose((3, 0, 1, 2))
14+
15+
v = napari.Viewer()
16+
v.add_image(distance_field)
17+
v.add_image(gradients)
18+
v.add_labels(mask)
19+
v.add_points([max_point])
20+
napari.run()

examples/distance/geodesic_mesh.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import napari
2+
import numpy as np
3+
from scipy.spatial import cKDTree
4+
from skimage.measure import marching_cubes
5+
6+
from bioimage_cpp.distance import geodesic_distance_field_mesh
7+
from shape import make_shape
8+
9+
# Create the mesh based on our sample shape.
10+
mask = make_shape()
11+
verts, faces, _, _ = marching_cubes(mask, level=0.5)
12+
13+
# Create some points in the volume as sources for the distances.
14+
c = mask.shape[0] / 2.0
15+
angles = np.linspace(0.0, 2.0 * np.pi, num=5, endpoint=False)
16+
points = np.array(
17+
[[c, c + 33.0 * np.sin(a), c + 33.0 * np.cos(a)] for a in angles]
18+
)
19+
20+
# Snap the points to the closest mesh vertex.
21+
_, idx = cKDTree(verts).query(points)
22+
sources = np.unique(idx)
23+
24+
# Compute the distance field on the mesh.
25+
field = geodesic_distance_field_mesh(verts, faces, sources)
26+
27+
# Alternatively, you can also compute the pairwise geodesic distance
28+
# between all the points like this:
29+
# pairwise_distances = geodesic_distances_mesh(verts, faces, sources, number_of_threads=1)
30+
31+
# Display the mesh and points in napari.
32+
# The mesh gets the distance field as values.
33+
v = napari.Viewer()
34+
v.add_surface((verts, faces, field))
35+
v.add_points(points)
36+
napari.run()

examples/distance/shape.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import numpy as np
2+
3+
4+
def make_shape(size=80):
5+
R, r = 24.0, 9.0
6+
c = size / 2.0
7+
zz, yy, xx = np.ogrid[:size, :size, :size]
8+
q = np.sqrt((yy - c) ** 2 + (xx - c) ** 2) - R
9+
mask = (q ** 2 + (zz - c) ** 2 <= r ** 2).astype("uint8")
10+
return mask

0 commit comments

Comments
 (0)