Macro calls to roiManager create exception when Fiji run in headless mode

This is a post of a subsection of a discussion on running Fiji in headless mode How to stop the results window from stealing focus during batch jobs, so that this specific issue can be addressed.
I am successfully running a macro in Fiji headless in Windows, passing parameters from the command line.
All IJ commands seem to be working, with the exceptions of calls to roiManager, including any of the following:

roiManager("reset");
roiManager(("count");
roiManager("select", index);

Any of the above calls to roiManager() throws the following exception. If I can’t call roiManager() then this macro can’t be run headless.
Any help with interpreting what is going wrong or how to diagnosis this problem would be very much appreciated!
The exception text is:

java.awt.HeadlessException
        at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204)
        at java.awt.Window.<init>(Window.java:536)
        at java.awt.Frame.<init>(Frame.java:420)
        at ij.plugin.frame.PlugInFrame.<init>(PlugInFrame.java:13)
        at ij.plugin.frame.RoiManager.<init>(RoiManager.java:90)
        at ij.macro.Functions.roiManager(Functions.java:2748)
        at ij.macro.Functions.getFunctionValue(Functions.java:230)
        at ij.macro.Interpreter.getFactor(Interpreter.java:1385)
        at ij.macro.Interpreter.getTerm(Interpreter.java:1356)
        at ij.macro.Interpreter.getStringExpression(Interpreter.java:1496)
        at ij.macro.Interpreter.getStringTerm(Interpreter.java:1315)
        at ij.macro.Interpreter.getString(Interpreter.java:1272)
        at ij.macro.Interpreter.doStatement(Interpreter.java:281)
        at ij.macro.Interpreter.doBlock(Interpreter.java:608)
        at ij.macro.Interpreter.doStatement(Interpreter.java:272)
        at ij.macro.Interpreter.doFor(Interpreter.java:530)
        at ij.macro.Interpreter.doStatement(Interpreter.java:254)
        at ij.macro.Interpreter.doBlock(Interpreter.java:608)
        at ij.macro.Interpreter.doStatement(Interpreter.java:272)
        at ij.macro.Interpreter.doFor(Interpreter.java:530)
        at ij.macro.Interpreter.doStatement(Interpreter.java:254)
        at ij.macro.Interpreter.doBlock(Interpreter.java:608)
        at ij.macro.Interpreter.doStatement(Interpreter.java:272)
        at ij.macro.Interpreter.doFor(Interpreter.java:530)
        at ij.macro.Interpreter.doStatement(Interpreter.java:254)
        at ij.macro.Interpreter.doStatements(Interpreter.java:218)
        at ij.macro.Interpreter.run(Interpreter.java:115)
        at ij.macro.Interpreter.run(Interpreter.java:85)
        at ij.macro.Interpreter.run(Interpreter.java:96)
        at ij.plugin.Macro_Runner.runMacro(Macro_Runner.java:155)
        at ij.plugin.Macro_Runner.runMacroFile(Macro_Runner.java:139)
        at ij.IJ.runMacroFile(IJ.java:148)
        at net.imagej.legacy.IJ1Helper$4.call(IJ1Helper.java:1056)
        at net.imagej.legacy.IJ1Helper$4.call(IJ1Helper.java:1052)
        at net.imagej.legacy.IJ1Helper.runMacroFriendly(IJ1Helper.java:986)
        at net.imagej.legacy.IJ1Helper.runMacroFile(IJ1Helper.java:1052)
        at net.imagej.legacy.LegacyCommandline$Macro.handle(LegacyCommandline.java:188)
        at org.scijava.console.DefaultConsoleService.processArgs(DefaultConsoleS ervice.java:93)
        at net.imagej.legacy.LegacyConsoleService.processArgs(LegacyConsoleService.java:81)
        at org.scijava.AbstractGateway.launch(AbstractGateway.java:95)
        at net.imagej.Main.launch(Main.java:62)
        at net.imagej.Main.main(Main.java:68)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at net.imagej.launcher.ClassLauncher.launch(ClassLauncher.java:279)
        at net.imagej.launcher.ClassLauncher.run(ClassLauncher.java:186)
        at net.imagej.launcher.ClassLauncher.main(ClassLauncher.java:77)

with many thanks.

1 Like

That depends on what you are trying to achieve. I guess you can emulate most - if not all - functionality of the RoiManager with an Overlay. So instead of adding ROIs to the RoiManager, you can add them to an Overlay and operate on that Overlay subsequently.

Best,
Stefan

Thank you very much for your suggestion. Based on it, I have discovered Overlay Manager! Unfortunately, the documentation essentially links to roiManager and is not much help.

Below is the relevant code from my macro using roiManager. As you can see, I use Analyze Particles to obtain a set of objects from one image, the dimensions and locations of each is added as an individual region to roiManager. Next, I loop through all the ROIs, transferring each region from one image to another, and measure the mean intensity in the ROI.

roiManager("reset");  // throws an exception   
run("Analyze Particles...", "size=10-Infinity pixel circularity=0.70-1.00 add");  // obtain particles and add each ROI  to roiManager
    xNumber = roiManager("count") ;                        // get number of ROIs to analyze/ this call throws an exception
    selectWindow(SecondImage) ;                          // change focus on SecondImage where so ROIs will be transferred when roiManager("select") is called

    for (j=0; j< xNumber; j++)                                  // loop through each ROI
    	{
    		roiManager("Select", j) ;                    // transfer current ROI to secondImage, throws exception
    		List.setMeasurements ;                    // measure mean intensity
    // more code in this loop
            }

So, now with Overlay Manager:
Using

run("Analyze Particles...", "size=10-Infinity pixel circularity=0.70-1.00 show=Overlay record add");

Particle ROIs are added to roiManager and to the Overlay layer.
However,

  1. Adding particle ROIs from Analyze Particles to the overlay Manager using Overlay Manager>More>Add Particles throws an Unimplemented exception.

  2. Adding particle ROIs to roiManager and then calling
    run("Overlay Manager");
    run("From ROI Manager");
    does not throw an Unimplemented exception, but fails to add any ROIs to the OverlayManager window.

Without a list of ROIs in Overlay Manager, I don’t see how to iterate through the ROIs, let alone measure the mean intensity inside each.

Perhaps I am using OverlayManager incorrectly?
Any thoughts would be very much appreciated,
With thanks.

1 Like

Here is an example macro that adds ROIs to an overlay and then loops through the ROIs, measuring the mean intensity.

  run("Blobs (25K)");
  setAutoThreshold("Default");
  run("Analyze Particles...", "  show=Overlay");
  run("Set Measurements...", "area mean centroid decimal=2");
  for (i=0; i<Overlay.size; i++) {
    Overlay.activateSelection(i);
    run("Measure", "");
  }
1 Like

If that is what you want to do and you want to stick with the macro language, then you might be able to use the redirecting feature that you can activate in Set Measurements…:

Redirect to: The image selected from this popup menu will be used as the target for statistical calculations done by Analyze▷Measure… [m]↑ and Analyze▷Analyze Particles…↑ commands. This feature allows you to outline a structure on one image and measure the intensity of the corresponding region in another image.

I am not sure if you are able to do that manually in the macro language. You could, however, use a scripting language like Groovy or Python (or any other) with full access to the ImageJ API. In that case, you can take every ROI from an Overlay and set it as the active selection on your second ImagePlus and run the Measure… command on that image.

Dear Wayne,
Thank you so much for your help.
Stefan had linked to your post where you had provided some code to control Overlay Manager, but not the specifics for my problem.

I have two small questions:

1, To take the regions in the overlay from one image and apply them to a second image, can I simply select the second image before calling Overlay,activateSelection(i); ?
2. Instead of run("Measure, ") ;, will

List,setMeasurements ;
x = List.getValue(“Mean”) ;

work with Overlay Manager as it does with roiManager?

Thank you again,
Jeremy

Here is an example that adds ROIs to an overlay, transfers the overlay to another image, and then measures the mean of each ROI in the overlay.

  run("Blobs (25K)");
  setAutoThreshold("Default");
  run("Analyze Particles...", "  show=Overlay");
  Overlay.copy
  newImage("Untitled", "8-bit ramp", 256, 254, 1);
  Overlay.paste
  for (i=0; i<Overlay.size; i++) {
    Overlay.activateSelection(i);
    List.setMeasurements;
    mean = List.getValue("Mean");
    print(i+"  "+mean);
  }
3 Likes

I think I’m all set, then.
Thanks so much.

I’ve been trying to so something similar! Thanks!