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


#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.