Closed ctrueden closed 2 years ago
Where can I find the source code for DefaultRoiConversionTest and IrregularPolylineRoiWrapperTest?
Thanks @rasband for being willing to look at it. I didn't want to report a bug in ImageJ until I knew more about the problem, and I ran out of time to dig, hence this issue.
The code in question is here in this imagej-legacy repository:
And the DefaultRoiWrapper
:
It calls r = roi.getBounds()
and then reports the max as r.x + r.width
and r.y + r.height
respectively, which used to match expectations, but now is off by one as shown above. I briefly looked at the changes to Line
linked above, but didn't fully understand the consequences of the + 0.5
change, or even if that was for sure what causes this change in behavior.
We could change the tests here in imagej-legacy so they pass, but it feels wrong for the max to be off by one, when the x1/y1/x2/y2 use double
and are therefore not necessarily in integer space.
Any insight you could provide would be very helpful.
I looked into this change, made by Michael Schmid, in ImageJ 1.53h and concluded that it's a bug fix, not a regression. The smallest rectangle that encloses a line is the one returned by getBounds() in the current version of ImageJ. For example, this JavaScript, which creates a line and outlines it, works as expected with 1.53s but not with versions of ImageJ prior to 1.53h.
img = IJ.createImage("Untitled", "8-bit noise", 200, 200, 1);
line = new Line(10, 10, 20, 20);
overlay = new Overlay();
overlay.add(line);
img.setOverlay(overlay);
b = line.getBounds();
rect = new Roi(b.x,b.y,b.width,b.height);
img.setRoi(rect);
img.show();
IJ.run(img, "To Selection", "");
There is a bug with getBounds() when used with point selections. It creates a rectangle that is one pixel wider and taller than expected.
Here is example macro that reproduces the problem:
newImage("Untitled", "8-bit ramp", 50, 50, 1);
run("Add Noise"); //makes the pixels visible
makePoint(10, 10);
setKeyDown("shift");
makePoint(11, 10);
Roi.getBounds(x, y, width, height);
print("integer bounds: ",x, y, width, height);
run("Add Selection...");
makeRectangle(x, y, width, height);
run("To Selection");
The ImageJ 1.53s31 daily build fixes the bug that caused getBounds() to return a rectangle one pixel wider and taller than expected with point selections.
The following test macro reproduces the problem. It aborts with the error message "contains() test failed" with versions of ImageJ earlier than 1.53h.
newImage("Points", "8-bit noise", 50, 50, 1);
xp = newArray(7,8,9,10,8,8,7);
yp = newArray(7,6,7,9,10,8,9);
makeSelection("point large red dot", xp, yp);
Roi.getBounds(x, y, width, height);
run("Add Selection...");
makeRectangle(x, y, width, height);
run("To Selection");
for (i=0; i<xp.length; i++) {
if (!selectionContains(xp[i], yp[i]))
exit("contains() test failed");
}
Caused by this change i.e. this version of
Line.java
.More investigation needed to understand the details, but looks like a new bug in ImageJ as of v1.53h. One would expect the max coordinate of lines to be
(r.x + r.width, r.y + r.height)
but it seems the logic is now off by one.