imagej / imagej-ops

ImageJ Ops: "Write once, run anywhere" image processing
https://imagej.net/libs/imagej-ops
BSD 2-Clause "Simplified" License
89 stars 42 forks source link

Voxelization op creates artifacts #565

Open imagejan opened 6 years ago

imagejan commented 6 years ago

I tried the following Groovy script with the Bat Cochlea Volume sample image in Fiji:

#@ OpService ops
#@ Img img

import net.imagej.mesh.naive.NaiveDoubleMesh
import net.imagej.mesh.Meshes

bitImg = ops.run("convert.bit", img)

// Img<BitType> => Mesh

fullmesh = new NaiveDoubleMesh()
vertices = fullmesh.vertices()

cursor = bitImg.cursor()
loc = new double[3]

while (cursor.hasNext()) {
    cursor.fwd()
    if (cursor.get().get()) {
        cursor.localize(loc)
        vertices.add(loc[0], loc[1], loc[2])
    }
}
println "Points contained in input image: ${vertices.size()}"

// Mesh => Mesh (convex hull)

convexHull = ops.run("geom.convexHull", fullmesh).get(0)

println "Points contained in convex hull: ${convexHull.vertices().size()}"

convexHull.vertices().each {
    println "${it.x()}, ${it.y()}, ${it.z()}"
}

box = Meshes.boundingBox(convexHull)
println box
println Meshes.center(convexHull)
// Mesh => Mask ?

// Mesh => RAI (voxelization)
ops.run("intervalView", ops.run("translateView", ops.run("extendZeroView", ops.run("geom.voxelization", convexHull, box[3]-box[0], box[4]-box[1], box[5]-box[2])), [box[0], box[1], box[2]]), img)

// ops.run("morphology.floodFill") ? on centroid?

While the coordinates (output of convexHull) make sense to me:

image

The result image looks weird and contains some box artifacts (red = input, green = output):

image

Any idea what might be going wrong here?

imagejan commented 6 years ago

/cc @kephale

imagejan commented 6 years ago

For comparison, this is what I get with the 3D Convex Hull command from https://github.com/mcib3d/mcib3d-plugins:

image

kephale commented 6 years ago

Confirmed.

A couple of points:

  1. imagej-ops convex hull generation of a mesh output behaves properly.
  2. voxelization works for other cases. for example, if you make a mesh from the bat cochlea volume directly, then voxelize it, you get the surface of the bat cochlea again

I wonder about the imagej-mesh data structures (I thought I remembered having voxelized a convex hull with different mesh data structures than those currently used in imagej-mesh). The blockiness at what appear to be bounding vertex coordinates is one of the reasons that I am suspicious.

imagejan commented 4 years ago

Some related discussion on the KNIME forum: 3D convex hull KNIME