//load ImageJ
%classpath config resolver scijava.public https://maven.scijava.org/content/groups/public
%classpath add mvn net.imagej imagej 2.0.0-rc-67
//create ImageJ object
ij = new net.imagej.ImageJ()
Added new repo: scijava.public
net.imagej.ImageJ@3baf5137
This op performs morphological closing on any binary image. Let's see how the Op
is called:
ij.op().help("close")
Available operations: (IterableInterval out?) = net.imagej.ops.morphology.close.ListClose( IterableInterval out?, RandomAccessibleInterval in1, List in2)
Note the parameters here:
IterableInterval out
: the output imageRandomAccessibleInterval in1
: the input imageList in2
: this parameter contains all of the Shape
s that the Op
will use to close (i.e. for each Shape
in in2
close the input (or output of the last close
if there are 2+ Shape
s in in2
)).We need to get a binary image to perform any morphological operations. Let's get a grayscale image and then binarize it using the Huang Threshold Op:
input_full = ij.scifio().datasetIO().open("http://imagej.net/images/blobs.gif")
//input_full has 3 channels. We only need one.
input = ij.op().run("hyperSliceView", input_full, 2, 0)
//invert the image so that the blobs are "on" and the background "off"
inverted = ij.op().run("create.img", input)
ij.op().run("invert", inverted, input)
binaryInput = ij.op().run("threshold.huang", inverted)
ij.notebook().display(binaryInput)
[INFO] Verifying GIF format [INFO] Reading dimensions [INFO] Reading data blocks
As it states in the Wikipedia article, closing an image will bridge small gaps between objects. The smaller the gap, the wider the bridge:
import net.imglib2.algorithm.neighborhood.HyperSphereShape
//create the shape that we are going to dilate the image with
shape = new HyperSphereShape(6)
output = ij.op().run("close", null, binaryInput, [shape])
ij.notebook().display(output)
To show the difference, let's stack the images to see the difference:
import net.imglib2.img.Img
list = new ArrayList<Img>()
list.add(binaryInput)
list.add(output)
stacked = ij.op().run("stackView", list)
ij.notebook().display(stacked)
Note the yellow regions denoting the original blobs as well as the green bridges between the blobs.