ROI Manager saving error

roi-manager
imagej
macro

#1

Hi there,

I can give more details, but thought I would just ask quickly first:

I’m using the wand tool to draw ROIs and then save them.

The problem is, when i save the ROIs, into a .zip or individual .roi files, (using macro code, or manually) they are completely distorted upon opening.
If I try to open a .zip file containing lots of them, only a few of them open, they are again distorted, and I get the following error message:

(Fiji Is Just) ImageJ 2.0.0-rc-65/1.52a; Java 1.8.0_66 [64-bit]; Windows 7 6.1; 3125MB of 8000MB (39%)
 
java.lang.NegativeArraySizeException
	at ij.io.RoiDecoder.getRoi(RoiDecoder.java:256)
	at ij.plugin.frame.RoiManager.openZip(RoiManager.java:771)
	at ij.plugin.frame.RoiManager.open(RoiManager.java:735)
	at ij.plugin.frame.RoiManager.runCommand(RoiManager.java:2031)
	at ij.macro.Functions.roiManager(Functions.java:2868)
	at ij.macro.Functions.getFunctionValue(Functions.java:231)
	at ij.macro.Interpreter.getFactor(Interpreter.java:1461)
	at ij.macro.Interpreter.getTerm(Interpreter.java:1432)
	at ij.macro.Interpreter.getStringExpression(Interpreter.java:1581)
	at ij.macro.Interpreter.getStringTerm(Interpreter.java:1391)
	at ij.macro.Interpreter.getString(Interpreter.java:1336)
	at ij.macro.Interpreter.doStatement(Interpreter.java:303)
	at ij.macro.Interpreter.doStatements(Interpreter.java:235)
	at ij.macro.Interpreter.run(Interpreter.java:118)
	at ij.macro.Interpreter.run(Interpreter.java:89)
	at ij.macro.Interpreter.run(Interpreter.java:100)
	at ij.plugin.Macro_Runner.runMacro(Macro_Runner.java:161)
	at ij.IJ.runMacro(IJ.java:138)
	at ij.io.Opener.openZip(Opener.java:941)
	at ij.io.Opener.openImage(Opener.java:355)
	at ij.io.Opener.openImage(Opener.java:242)
	at ij.io.Opener.open(Opener.java:109)
	at ij.io.Opener.openAndAddToRecent(Opener.java:291)
	at ij.plugin.DragAndDrop.openFile(DragAndDrop.java:192)
	at ij.plugin.DragAndDrop.run(DragAndDrop.java:159)
	at java.lang.Thread.run(Thread.java:745)

EDIT - ‘simple’ ROIs generated using the wand seem to save fine, its just the more complex ones in my analysis that seem to be the problem.
Also, if I create one of these more complex ROIs, then edit it slightly with the freehand selection tool, it appears to save fine. I’m using this as a workaround for now…

Any ideas whats going on?
thanks in advance,
Isaac


#2

Good day Isaac,

could you please try the following Image-macro on the provided test image?

run("Set Measurements...", "integrated redirect=None decimal=3");
orig = getTitle();
run("Duplicate...", "title=copy");
doWand(64, 64, 17.0, "Legacy");
dir = getDirectory("home");
saveAs("Selection", dir+"Test.roi");
run("Clear Outside");
run("Select None");
selectImage(orig);
open(dir+"Test.roi");
run("Clear Outside");
run("Select None");
imageCalculator("Difference create 32-bit", orig,"copy");
run("Measure");
exit();

Test

Open the above test image in ImageJ.
Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it.

Then, the Results-window should list these values:
screenShot

This result means that the ROI, when saved (in your home directory) and re-opened, gives the same selection as the original one.

HTH

Herbie

PS:
Here is a macro version that uses the ROI-Manager:

run("Set Measurements...", "integrated redirect=None decimal=3");
orig = getTitle();
run("Duplicate...", "title=copy");
doWand(64, 64, 17.0, "Legacy");
dir = getDirectory("home");
roiManager("add");
roiManager("save", dir+"Test.roi");
run("Clear Outside");
run("Select None");
roiManager("reset");
selectImage(orig);
roiManager("open", dir+"Test.roi");
roiManager("Select", 0);
run("Clear Outside");
run("Select None");
imageCalculator("Difference create 32-bit", orig,"copy");
run("Measure");
exit();

#3

Hi Herbie,

I ran both macros, and got the result you indicated there, so in this case the selection was saved fine.
It seems like size has something to do with it. For example:

In the above screen-grab, the top panel shows two separate ROIs drawn and saved to a .zip folder.
The lower panel shows what they looked like when they were loaded again. The smaller left hand ROI is identical.

Thanks,
Isaac


#4

If I try to save a ROI with > 65k points, I get an error:

ROIs with more than 65k points cannot be saved.

It does still save something, but the number of points is truncated (as can be seen in the code).

Might that be the problem, or do you have fewer points even in your largest ROIs?

The following Groovy script might help to check:

import ij.gui.PolygonRoi
import ij.plugin.frame.RoiManager

def roiManager = RoiManager.getInstance()
roiManager.getRoisAsArray().each { roi ->
    ij.IJ.log(roi.getName() + ': ' + roi.getPolygon().npoints)
}

#5

I can confirm this finding.

ROIs with more than 65k points cannot be saved.

This warning is presently output to the log-window but should better appear in an ImageJ-message window and the save-process should not take place.

@Wayne could you please have a look at this issue?

Thanks

Herbie


#6

If this is causing problems, a possible workaround may be to convert any PolygonRoi to a ShapeRoi, since these are handled differently.

The following Groovy script attempts to do this for all ROIs in the ROI Manager that contain too many points. (It seemed to work in my quick test, but since it resets the ROI manager then it might potentially lose even ‘good’ ROIs if something goes terribly wrong - so be sure to check yourself if it works reliably enough before relying on it.)

import ij.gui.PolygonRoi
import ij.gui.ShapeRoi
import ij.plugin.frame.RoiManager

// Get roi manager & original rois
def roiManager = RoiManager.getInstance()
def roisOrig = roiManager.getRoisAsArray()

// Convert PolygonRois to ShapeRois if necessary, i.e. they've got too many points
nUpdated = 0
def roisUpdated = roisOrig.collect { roi ->
    if (!(roi instanceof PolygonRoi) || roi.getPolygon().npoints < 65535)
        return roi
    else {
        nUpdated++
        return new ShapeRoi(roi)
    }
}
if (nUpdated == 0) {
    print 'No ROIs updated!'
    return
}

// Update the ROI manager
print 'Number of updated ROIs: ' + nUpdated
roiManager.runCommand("reset")
roisUpdated.each { roi ->
    roiManager.addRoi(roi)
}

From a quick look at the ShapeRoi code, it looks like there would still be a limit to the number of supported points - but likely a much higher limit.


#7

Hi guys,

Thanks for looking into this!

My biggest ROIs did have more than 65k points, so this must have been the problem.
I guess the workaround I mentioned before of editing the ROI with the freehand selection tool worked because it converted it from a PolygonRoi to a ShapeRoi?

As it stands for me this solution is fine because I have to tweak them normally anyway, but good to know for future reference. @petebankhead I didn’t test the Groovy code as I’m not familiar with that language and the rest of my code is in the IJmacro language, sorry.

best,
Isaac


#8

The latest ImageJ daily build (1.52e57) works around this problem by converting ROIs with more that 65535 points to ShapeRois. View the source code changes at: