Can I get to measurements using ImageJ Ops?

imagej

#1

To improve maintainability of analysis code I am playing with converting some code from ImageJ1 to using ImageJ Ops. Like others on this forum mentioned, I found the “Beaker” documentation (http://imagej.github.io/tutorials/[1.02]%20Introduction%20to%20ImageJ%20Ops.bkr.html) very helpful (thanks!). If that “Beaker” is maintained, it would be useful to link to it from the first search hits for “ImageJ Ops”: https://imagej.net/ImageJ_Ops, and https://github.com/imagej/imagej-ops, as it is currently hard to find.

One filter that I found missing is the ImageJ1 rolling ball background subtraction. Is there an Op that implements this, or is it planned to be written?

Also, Ops functionality seem to “end” with a segmented image. How does one proceed to analyze the binary masks (i.e. replacements for the ImageJ1 “Analyze Particles…” and ability to measure given an image and a binary mask)?


#2

The API will probably change in the future (to make it easier to use) but in the meantime you can have a look at the following : http://imagej.net/ImageJ2_Python_Scripts#Retrieve_objects.2Fparticles_from_a_mask

(if anyone has a better code to achieve the same, I’ll take it)


#3

Hi @nicost,

you can measure all kind of stuff with imagej-ops. After you have segmented your image you get a labeling which describes the segmented regions. Based on these regions you can sample the orginal image and calculate features, such as image moments, haralick 2d/3d, zernike, hu-moments, first order statistics, tamura, object geometry 2d, 3d etc. Just check ops().*. If I remember correctly, @bnorthan has an ops example for that somewhere (Brian?! :-)).

Cheers,

Christian


#4

@nicost if you open up the fiji script editor, and go to ‘templates->tutorials’ there is a tutorial called ‘Ops_Threshold_Measure’. It shows how to work with a labeling to loop through regions (objects) and get measurements.

You may have to update imagej-scripting, as this tutorial was added just a few weeks ago.


#5

@hadim: I guess the API changes you mention refer to the discussion here: Implementation plan for Imglib2-rois 2D. Thanks for the link to the python script (which seems to be the same as the one @bnorthan refers to).

Trying to use that example in Java, I get to:

OpService ops = CONTEXT.getService(OpService.class);

Img<ShortType> image = ImageJFunctions.wrap( IJ.getImage() );
image = (Img<ShortType>) ops.filter().gauss(image, 3.0);
RandomAccessibleInterval<BitType> otsu = (RandomAccessibleInterval<BitType>) ops.threshold().otsu(image);
List<Shape> shapes = new ArrayList<Shape>();
HyperSphereShape shape = new HyperSphereShape(1);
shapes.add(shape);
RandomAccessibleInterval<BitType> closed = 
          (RandomAccessibleInterval<BitType>) ops.morphology().close(otsu, shapes);
ops.labeling().cca(closed, ConnectedComponents.StructuringElement.FOUR_CONNECTED);
LabelRegions regions = new LabelRegions(labels);
Iterator rIterator = regions.iterator();
while (rIterator.hasNext()) {
   LabelRegion region = (LabelRegion) rIterator.next();
   DoubleType size = ops.geom().size(region);
   System.out.println("size of object is: " + size);
   System.out.println("center of object is: " + region.getCenterOfMass());
}

This works, but how do I proceed to place these regions on top of my original image and get the intensities under each region?

Why aren’t there structuring elements with less than four connected (i.e. ConnectedComponents.StructuringElement.ONE_CONNECTED)? I want a list of all “particles”, i.e. a list of all groups of pixels where each pixel is connected to one or more neighbors part of that group. I haven’t been able to locate the code executing the cca function, but from the sounds of it I need StructuringElement.ONE_CONNECTED.

It is well possible that I have missed an enlightening piece of documentation, if so, can someone please point me to it?


#6

Hi @nicost

To get intensities of your objects, here is how @dietzc recommended calculating the mean of each object.

for (LabelRegion<?> region : regions) {
	// now get the size of each object....
	System.out.println("size of object is: " + region.size());
	System.out.println("center of object is: " + region.getCenterOfMass());

	double mean= ops.stats().mean(Regions.sample(region,
		imgResidual_n)).getRealDouble();

	System.out.println("mean of object is: "+mean);