`Roi.setPosition()` can't be set to a position greater than the active image frame numbers

imagej

#1

Here is the snippet that reproduce the issue:

# @Dataset data

# data should be 3D image.
# You can use File > Open Samples > Tracks for TrakMate

from ij.gui import Roi
from ij.plugin.frame import RoiManager

rm = RoiManager.getRoiManager()

roi = Roi(10, 10, 100, 100)

# Set the position to a greater value than the number of frame in data.
roi.setPosition(999)
rm.addRoi(roi)

# Check Properties in the RoiManager window. It is set to 1 instead of 999.

I am pretty sure this behaviour is excepted but here is my use-case. I am populating RoiManager with a list of ROIs for an image that does not exist yet. So that would be convenient if I could set the position of the rois even if this position does not exist in the “active image”.


#2

You can do this using an overlay, which can be moved to the ROI Manager if necessary. Here is a JavaScript example:

   overlay = new Overlay()
   overlay.drawLabels(true)
   for (i=1; i<=1000; i++) {
      roi = new Roi(10+i/10, 10+i/10, 100.0, 100.0)
      roi.setPosition(i)
      overlay.add(roi)
   }
   img = IJ.createImage("Untitled", "8-bit ramp", 256, 256, 1000)
   img.setOverlay(overlay)
   img.show()
   //IJ.run(img, "To ROI Manager", "");

#3

Thank you @Wayne.

Would it be possible to transfer the overlay to the RoiManager without using an image (setOverlay())?


#4

You can add the ROIs directly to the ROI Manager, as in this example:

   rm = RoiManager.getInstance()
   if (rm==null)
       rm = new RoiManager()
   rm.runCommand("reset")
   for (i=1; i<=1000; i++) {
      roi = new Roi(10+i/10, 10+i/10, 100.0, 100.0)
      roi.setPosition(i)
      rm.add(null, roi, i)
   }

#5
rm.add(null, roi, i);

gives me a compilation error in Eclipse:

The method add(ImagePlus, Roi, int) is ambiguous for the type RoiManager

So I tried the following as a workaround:

rm.add(new ImagePlus(), roi, i);

but all the ROI positions are set to None.

That being said, your script works as excepted in Fiji and has the behavior I am looking for so I guess it’s just a Java signature issue with rm.add(null, roi, i);.


#6

I also tried to cast null:

rm.add((RoiManager) null, roi, i);

but this time I get a NullPointerException during execution.


#7

Hm, the method signature probably clashes with

add(Component comp, Object constraints, int index)

from java.awt.Container (a superclass of RoiManager).


#8

Arf that’s a tough one! Any idea for a workaround? roi is still a Roi object so it’s weird Java does not match it to the RoiManager class…


#9

Casting null to ImagePlus works for me:

import ij.ImagePlus;
import ij.gui.*;
import ij.plugin.PlugIn;
import ij.plugin.frame.RoiManager;

public class Roi_PlugIn implements PlugIn {

	@Override
	public void run(String arg) {
		RoiManager rm = RoiManager.getInstance();
		if (rm==null)
			rm = new RoiManager();
		rm.runCommand("reset");
		for (int i=1; i<=1000; i++) {
			Roi roi = new Roi(10+i/10, 10+i/10, 100.0, 100.0);
			roi.setPosition(i);
			rm.add((ImagePlus) null, roi, i);
		}
	}
}

When there are multiple matching method signatures due to usage of null, the solution is to cast the null to the type of the desired method signature.


#10

Ok the NullException was due to a collateral effect of my code modification.

It works like a charm.

Thanks all.


#11

Well I had thought that was a bug !
I similarly populate a set of ROI for an image stack, my workaround was to set the position of the ROI after adding it to the ROI manager. But it means reaccessing the ROI using its index…
The above solution will make my life a bit simpler !

I was actually wondering what the rm.add(imp, roi, n) signature was useful for.
Then I though it is to be able to recover the ImagePlus associated to the roi via the roi.getImage() but for me I always get None.

#@ImagePlus image
from ij.gui           import Roi
from ij.plugin.frame  import RoiManager

# Initialise RM
RM = RoiManager()
rm = RM.getInstance()

# Create ROI
ROI = Roi(100, 100, 100, 100)
ROI.setPosition(5)

# Add to RM
rm.add(image, ROI, 0)

# Recover ROI from RM
newROI = rm.getRoi(0)


print newROI            # indeed get the rectangle
print newROI.getImage() # None ?!