Getting selected ROI in ROI manager

Hi,
the user can interactively select rectanglular bounding boxes and add them to a list of ROIs, using the ROI Manager. Unfortunately, Roi roi = roiMng.getRoi(1); returns null although at least one region is selected and added to the list using the add button of the ROI manager.

Here the complete code:

public class roiTest 
{
	public static void main(String[.] args)
	{
		IJ.open();
		ImagePlus testImage = WindowManager.getCurrentImage();
		testImage.show();
		
		RoiManager roiMng = new RoiManager();
		while(roiMng.getCount() != 1); // wait for selection
		Roi roi = roiMng.getRoi(1);
		if(roi == null)
		{
			System.out.println("error");
			System.out.println(roiMng.getCount());
			return;
		}
		roiMng.close();
		ImageProcessor ip = testImage.getProcessor();
		ip.setRoi(roi);
		ImagePlus selection = new ImagePlus(testImage.getTitle()+" - Selection", ip.crop());
		selection.show();
		System.out.println("Finished");
	}
}

Has anyone an idea why the roi is always null? In the ROI manager, all ROIs can be displayed correctly.

Best regards
re342

Hi,

Can you try getRoi(0)? Indexing starts at 0 so perhaps that’s why the roi is null.

Best

Hi,
I already tried that. The same error.
Best
re342

Ah my bad.
You need not to create a new RoiManager object. Instead use the staticethid.

RoiManager roiMng = RoiManager.getInstance();

Then roiMng is null. So I get a NullPointerException.

Now I found at least a solution which works. But I still don’t understand why the solution before didn’t work.

Here my solution:

	public static void main(String[] args)
	{
		IJ.open();
		ImagePlus testImage = WindowManager.getCurrentImage();
		testImage.show();
		
		RoiManager roiMng = RoiManager.getInstance();
		if(roiMng == null) roiMng = new RoiManager();
		
		while(roiMng.getCount() != 1); // wait for selection
		
		int[] indexes = roiMng.getIndexes();
		System.out.println(indexes[0]);
		Roi roi = roiMng.getRoi(indexes[0]);
		
		if(roi == null)
		{
			System.out.println("Error - The selected ROI could not be found!");
			return;
		}
		
		roiMng.close();

		ImageProcessor ip = testImage.getProcessor();
		ip.setRoi(roi);
		ImagePlus selection = new ImagePlus(testImage.getTitle()+" - Selection", ip.crop());
		selection.show();
		
		System.out.println("Finished");
	}

It is strange, that all seems to be dependent on the println statements. For example, without System.out.println(indexes[0]); or with System.err.println("Finished"); instead of System.out.println("Finished"); it doesn’t work any more (roi = null).

But thank you for your help!

Does it work if you use RoiManager.getSelectedRoisAsArray() and access the returned array?

This is also dependent on the println.

For example

System.out.println(roiMng.getSelectedRoisAsArray().length); Roi[ ] rois = roiMng.getSelectedRoisAsArray(); Roi roi = rois[0];
works, but

Roi[ ] rois = roiMng.getSelectedRoisAsArray(); Roi roi = rois[0];
not (roi = null).

Thanks for checking, @re342!

In this case, I’d guess that it is some kind of concurrency issue that stems from selecting ROIs in the UI and accessing them programmatically. Maybe @Wayne has an idea how to properly tackle this issue?

Dear @re342,
I tried using Eclipse (with Maven) to try your code with the difference that I use the WaitForUseDialog (https://imagej.nih.gov/ij/developer/api/ij/gui/WaitForUserDialog.html) class to wait for user roi selection, instead
of while(roiMng.getCount) and it works even without the System.out.println(“print”);

import ij.gui.WaitForUserDialog; _//added by me_
RoiManager roiMng = RoiManager.getInstance();  _//added by me_
WaitForUserDialog wd_roi= new WaitForUserDialog("ROI SELECTION","select a Roi"); _//added by me_
wd_roi.show();

to your code here:

have a nice day,
Emanuele Martini

Hello,
thank you for your help. I also use eclipse and Maven, but RoiManager roiMng = RoiManager.getInstance(); returns null. How interacts the ROI manager with the WaitForUseDialog?
Best
re342

The sense of using the wait for user dialog is like:
0) someway you have some rois in your roimanager

  1. they are on an image
  2. you ask to the user to select a roi with waitforuserdialog then the user clicks ok and
  3. your plugin get the roi selected and do something. with:

But maybe I am not fully getting why you are using a while to do that.

regards,
Emanuele

The wait for user dialog is a good idea for my issue. But unfortunately, your code doesn’t work for me, because RoiManager roiMng = RoiManager.getInstance(); returns null. SoroiMng.getSelectedRoisAsArray(); gives an exception. How can I correctly use the WaitForUserDialog for user roi selection? Gives RoiManager.getInstance(); not a null pointer for you?

Sorry, I did not spot that one earlier: use RoiManager.getRoiManager() instead. This will create a new RoiManager instance if none has been created yet (see RoiManager.java#L1772-L1784 for implementation details).

Dear @re342,
this is a simple implementation of the code it asks you to open an image and then it creates 3 “fake” rois and add them to a roimanager called rm.
Then ask the user to select a roi and it logs out the roi that you have selected.

This is the code, plus the debugging method that I usually use to debug in Eclipse.

    import ij.IJ; //this is for debugging method
    import ij.ImageJ;
    import ij.ImagePlus;
    import ij.gui.Roi;
    import ij.gui.WaitForUserDialog;
    import ij.plugin.PlugIn;
    import ij.plugin.frame.RoiManager;

	public class roiTest_userSelection implements PlugIn {
		@Override
		public void run(String arg) {		
		
		// open an image then put three examples rois
		RoiManager rm = new RoiManager();
		ImagePlus imp = IJ.openImage();
		imp.show();		
		imp.setRoi(290,79,160,131);
		rm.addRoi(imp.getRoi());
		imp.setRoi(103,284,207,62);
		rm.addRoi(imp.getRoi());
		imp.setRoi(300,215,21,30);
		imp.setRoi(100,235,123,67);
		rm.addRoi(imp.getRoi());
		rm.runCommand(imp,"Show All with labels");
		
		// ask user to select a Roi		
		WaitForUserDialog wd_roi= new WaitForUserDialog("USER ROI SELECTION","select a Roi");
		wd_roi.show();
		RoiManager roiMng = RoiManager.getInstance(); //here you get your roi manager, I think you could use also RoiManager.getRoiManager();
		Roi[  ] rois = roiMng.getSelectedRoisAsArray();
		Roi roi = rois[0];
		// print out the selected roi 
		IJ.log("you seleceted the roi : "+ roi.getName());
		
		}


	//** DEBUGGING METHOD
	public static void main(String[] args) {
		// set the plugins.dir property to make the plugin appear in the Plugins menu
		Class<?> clazz = roiTest_userSelection.class;
		String url = clazz.getResource("/" + clazz.getName().replace('.', '/') + ".class").toString();
		String pluginsDir = url.substring(5, url.length() - clazz.getName().length() - 6);
		System.setProperty("plugins.dir", pluginsDir);
		// start ImageJ
		new ImageJ();
		
		// run the plugin
		IJ.runPlugIn(clazz.getName(), "");
	}
	}

I tested it today and it works fine.
You can try also the getRoiManager() suggested by @stelfrich, but I don’t know if you need to create a new roiManager in the case a roiManager doesn’t exist; of course in my little code there is not the management of the case that a RoiManager doesn’t exist when you ask to the user to select a Roi.

I hope this will help,
Emanuele Martini

1 Like

Thank you again for your help! Your code also works for me and is a very good basis for my concrete problem.

Here the working code for exactly one user ROI selection (in this case, the ROI manager can be hidden):

import ij.IJ;
import ij.ImagePlus;
import ij.gui.Roi;
import ij.gui.WaitForUserDialog;
import ij.plugin.frame.RoiManager;
import ij.process.ImageProcessor;

public class roiTest_userSelection
{
	public static void main(String[  ] args)
	{
		ImagePlus testImage = IJ.openImage();
		testImage.show();
		
		RoiManager roiMng = new RoiManager();
		roiMng.setVisible(false);
		
		WaitForUserDialog wd_roi= new WaitForUserDialog("USER ROI SELECTION","Select a Roi");
		wd_roi.show();
		
		roiMng.runCommand(testImage,"add");
		Roi[  ] rois = roiMng.getSelectedRoisAsArray();
		Roi roi = rois[0];
                   
		ImageProcessor ip = testImage.getProcessor();
		ip.setRoi(roi);
		ImagePlus selection = new ImagePlus(testImage.getTitle()+" - Selection", ip.crop());
		selection.show();
		
		System.out.println("Finished");
	}
}
1 Like

I am happy it helped you and thank you also for sharing your code too.
have a nice day
Emanuele Martini