Getting selected ROI in ROI manager

imagej

#1

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


#2

Hi,

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

Best


#3

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


#4

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

RoiManager roiMng = RoiManager.getInstance();

#5

Then roiMng is null. So I get a NullPointerException.


#6

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!


#7

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


#8

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


#9

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?


#10

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


#11

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


#12

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


#13

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?


#14

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


#15

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


#16

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");
	}
}

Retrieving indices of multiple selected ROIs in a macro
#17

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