Skip to content

Commit 100c616

Browse files
committed
WIP: Mesh Visualization document
TODO: Add an image (on media.scijava.org)
1 parent 7ea591f commit 100c616

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

docs/ops/doc/examples/mesh_viz.rst

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
=============================
2+
3D Analysis and Visualization
3+
=============================
4+
5+
In this example, we will use SciJava Ops to construct a 3D mesh from a binary dataset, passing the result into `3D Viewer`_ for visualization. We use the `bat cochlea volume`_ dataset from the ImageJ sample images, which users can either download using the link or open from the ``File → Open Samples → Bat Cochlea Volume`` menu selection within Fiji.
6+
7+
.. TODO: Add image
8+
9+
.. TODO: Update SciJava Ops Image -> imglib2-mesh
10+
11+
The following script accepts the binary dataset as its sole input, and creates the mesh using the `marching cubes`_ algorithm, which is included within SciJava Ops Image. We then use SciJava Ops to compute mesh volume, and then convert the mesh into a ``CustomTriangleMesh`` that can be passed to the 3DViewer.
12+
13+
.. tabs::
14+
15+
.. code-tab:: scijava-groovy
16+
17+
#@ OpEnvironment ops
18+
#@ UIService ui
19+
#@ Dataset image
20+
#@ ImagePlus imp
21+
#@ StatusService status
22+
23+
import java.util.ArrayList
24+
import java.util.List
25+
26+
import net.imagej.mesh.Mesh
27+
import net.imagej.mesh.Triangle
28+
import net.imglib2.RandomAccessibleInterval
29+
import net.imglib2.type.BooleanType
30+
import net.imglib2.util.Util
31+
32+
import org.scijava.vecmath.Point3f
33+
34+
import customnode.CustomTriangleMesh
35+
import ij3d.Image3DUniverse
36+
37+
if (image.getType() instanceof BooleanType) {
38+
// Input image is a binary image.
39+
mask = image
40+
}
41+
else {
42+
// Binarize the image using Otsu's threshold.
43+
status.showStatus("Thresholding...")
44+
bitType = ops.op("create.bit").producer().create()
45+
mask = ops.op("create.img").input(image, bitType).apply()
46+
ops.op("threshold.otsu").input(image).output(mask).compute()
47+
}
48+
println("Mask = $mask [type=${Util.getTypeFromInterval(mask).getClass().getName()}]")
49+
50+
//ui.show(mask)
51+
52+
// Compute surface mesh using marching cubes.
53+
status.showStatus("Computing surface...")
54+
mesh = ops.op("geom.marchingCubes").input(mask).apply()
55+
println("mesh = ${mesh} [${mesh.triangles().size()} triangles, ${mesh.vertices().size()} vertices]")
56+
57+
meshVolume = ops.op("geom.size").input(mesh).apply().getRealDouble()
58+
println("mesh volume = " + meshVolume)
59+
60+
hull = ops.op("geom.convexHull").input(mesh).apply()
61+
println("hull = ${hull} [${hull.triangles().size()} triangles, ${hull.vertices().size()} vertices]")
62+
63+
hullVolume = ops.op("geom.size").input(hull).apply().getRealDouble()
64+
println("hull volume = $hullVolume")
65+
66+
// Display original image and meshes in 3D Viewer.
67+
68+
def opsMeshToCustomMesh(opsMesh) {
69+
points = []
70+
for (t in hull.triangles()) {
71+
points.add(new Point3f(t.v0xf(), t.v0yf(), t.v0zf()))
72+
points.add(new Point3f(t.v1xf(), t.v1yf(), t.v1zf()))
73+
points.add(new Point3f(t.v2xf(), t.v2yf(), t.v2zf()))
74+
}
75+
return new CustomTriangleMesh(points)
76+
}
77+
78+
mesh_hull = opsMeshToCustomMesh(hull)
79+
println("Hull volume according to 3D Viewer: ${mesh_hull.getVolume()}");
80+
81+
univ = new Image3DUniverse()
82+
univ.addVoltex(imp, 1)
83+
univ.addCustomMesh(mesh_hull, "Convex Hull")
84+
univ.show()
85+
86+
.. _3D Viewer: https://imagej.net/plugins/3d-viewer/
87+
.. _bat cochlea volume: https://imagej.net/images/bat-cochlea-volume.zip
88+
.. _marching cubes: https://en.wikipedia.org/wiki/Marching_cubes

docs/ops/doc/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ The combination of these libraries allows declarative image analysis workflows,
3333
examples/deconvolution
3434
examples/flim_analysis
3535
examples/gaussian_subtraction
36+
examples/mesh_viz
3637
examples/opencv_denoise
3738
examples/saca
3839
examples/scyjava

0 commit comments

Comments
 (0)