Running IJ1 Plugins with Ops/Sanity Check

Hello there,

This is related to my previous post regarding converting to ImagePlus, in that I’m still trying to get this flood fill algorithm working with the code provided to me. Given that the last conversation was quite helpful, I thought I’d try my luck again.

The issue I’m having is that IJ1 plugin that does the 3D flood filling, despite not throwing any errors, is not filling in a voxelized mesh of vasculature while the script is running.

# @Dataset input
# @OpService opService
# @DatasetService DatasetService
# @UIService uiService
# @OUTPUT Dataset volume_edt

from ij import IJ
from net.imglib2.img.display.imagej import ImageJFunctions as IJF
from process3d import Flood_Fill

iHeight = int(input.height)
iWidth = int(input.width)
iDepth = int(input.depth)

thresholded = opService.convert().bit(input)

# Compute our 3D mesh
mesh = opService.geom().marchingCubes(thresholded)
print("Mesh: ", mesh)

# Voxelize the mesh and convert to ImagePlus object for use with IJ1 flood fill
voxelization = opService.geom().voxelization(mesh, iHeight, iWidth, iDepth)
voxelization = IJF.wrap(voxelization, "voxel_image")

# Some coordinate that is interior to the mesh. This is hard coded, and generally needs to be manually determined per image.
interior_coord = [132, 373, 5]

## Call IJ1 flood fill plugin ('process3d.Flood_Fill.fill', x-coord , y-coord, z-coord, fill color) ##

fill_color = 255 
Flood_Fill.fill(voxelization, interior_coord[0], interior_coord[1], interior_coord[2], fill_color)

## More code using voxelization below ##

As a sanity check, I tried to use the 3D flood fill macro on a separate “sphere” mesh that I have saved, and it seems to work.

Essentially, my question is this - am I missing something blatantly obvious that would allow me to run the IJ1 plugin with this intermediate voxelization?

On a related note, I will then need to convert this filled voxelization back to a RandomAccessibleInterval containing the pixel values for use with other Ops further down the pipleine. IJF.wrap() worked quite well for me last time, but I can’t seem to find an "“unwrap” method or anything similar in the documentation - is there an easy way to do this?

As with last time, I can provide more information if needed.


I don’t get why you need to create a mesh, the re-voxelize it, to do the flood fill. The flood fill plugin would just as well run on your thresholded image, no?

It’s wrap in both directions. See the javadoc of ImageJFunctions:

static Img wrap(ImagePlus imp)

static ImagePlus wrap(RandomAccessibleInterval<T> img, String title)
1 Like

An excellent question - one which I don’t have an immediate answer to. Like I said, this is code that was given to me to work with, so I’m still trying to work out the rationale behind certain bits.

In fact, let me get back to you on that. I’ll try flood-filling the thresholded image quickly.

My mistake - I didn’t at all consider whether calling wrap again would convert it back. I assumed that it would be named differently.


Edit: Not sure about this, but I think the mesh is needed to make the voxelization object, which might be necessary for future stages in the pipeline (i.e. determining volume and doing distance transforms). Regardless, I’ve just checked it looks like the thresholded image is completely filled in before the flood fill algorithm anyway.

So, can I take this to mean there’s no issue with how I’m using the plugin?