Skip to content

Commit b9da758

Browse files
authored
Slice Geometry: Handle ROIs (or lack of them) more gracefully (#346)
Seems like there has been a regression or change of behaviour in IJ, around ROIs and getting bounds. This code change makes ROI handling more explicit and uses only ImagePlus methods (not ImageProcessor or ImageStack). Fixes #345
1 parent af1af29 commit b9da758

File tree

1 file changed

+74
-29
lines changed

1 file changed

+74
-29
lines changed

Legacy/bonej/src/main/java/org/bonej/plugins/SliceGeometry.java

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,16 @@ private double calculateCentroids(final ImagePlus imp, final double min,
462462
final double max)
463463
{
464464
final ImageStack stack = imp.getImageStack();
465-
final Rectangle r = stack.getRoi();
465+
int rx = 0; int ry = 0; int rwidth = 0; int rheight = 0;
466+
if (imp.getRoi() == null) {
467+
rwidth = imp.getWidth();
468+
rheight = imp.getHeight();
469+
} else {
470+
rx = imp.getRoi().getBounds().x;
471+
ry = imp.getRoi().getBounds().y;
472+
rwidth = imp.getRoi().getBounds().width;
473+
rheight = imp.getRoi().getBounds().height;
474+
}
466475
// 2D centroids
467476
sliceCentroids = new double[2][al];
468477
// pixel counters
@@ -473,8 +482,8 @@ private double calculateCentroids(final ImagePlus imp, final double min,
473482
meanDensity = new double[al];
474483
weightedCentroids = new double[2][al];
475484
final double pixelArea = vW * vH;
476-
final int roiXEnd = r.x + r.width;
477-
final int roiYEnd = r.y + r.height;
485+
final int roiXEnd = rx + rwidth;
486+
final int roiYEnd = ry + rheight;
478487
for (int s = startSlice; s <= endSlice; s++) {
479488
IJ.showStatus("Calculating centroids...");
480489
IJ.showProgress(s - startSlice, endSlice);
@@ -486,8 +495,8 @@ private double calculateCentroids(final ImagePlus imp, final double min,
486495
double wSumX = 0;
487496
double wSumY = 0;
488497
final ImageProcessor ip = stack.getProcessor(s);
489-
for (int y = r.y; y < roiYEnd; y++) {
490-
for (int x = r.x; x < roiXEnd; x++) {
498+
for (int y = ry; y < roiYEnd; y++) {
499+
for (int x = rx; x < roiXEnd; x++) {
491500
final double pixel = ip.get(x, y);
492501
if (pixel >= min && pixel <= max) {
493502
count++;
@@ -533,7 +542,16 @@ private void calculateMoments(final ImagePlus imp, final double min,
533542
final double max)
534543
{
535544
final ImageStack stack = imp.getImageStack();
536-
final Rectangle r = stack.getRoi();
545+
int rx = 0; int ry = 0; int rwidth = 0; int rheight = 0;
546+
if (imp.getRoi() == null) {
547+
rwidth = imp.getWidth();
548+
rheight = imp.getHeight();
549+
} else {
550+
rx = imp.getRoi().getBounds().x;
551+
ry = imp.getRoi().getBounds().y;
552+
rwidth = imp.getRoi().getBounds().width;
553+
rheight = imp.getRoi().getBounds().height;
554+
}
537555
theta = new double[al];
538556
for (int s = startSlice; s <= endSlice; s++) {
539557
IJ.showStatus("Calculating Ix and Iy...");
@@ -543,16 +561,16 @@ private void calculateMoments(final ImagePlus imp, final double min,
543561
double sxxs = 0;
544562
double syys = 0;
545563
double sxys = 0;
546-
final int roiXEnd = r.x + r.width;
547-
final int roiYEnd = r.y + r.height;
564+
final int roiXEnd = rx + rwidth;
565+
final int roiYEnd = ry + rheight;
548566
if (emptySlices[s]) {
549567
theta[s] = Double.NaN;
550568
continue;
551569
}
552570
final ImageProcessor ip = stack.getProcessor(s);
553571
double sumAreaFractions = 0;
554-
for (int y = r.y; y < roiYEnd; y++) {
555-
for (int x = r.x; x < roiXEnd; x++) {
572+
for (int y = ry; y < roiYEnd; y++) {
573+
for (int x = rx; x < roiXEnd; x++) {
556574
final double pixel = ip.get(x, y);
557575
if (pixel >= min && pixel <= max) {
558576
final double xVw = x * vW;
@@ -615,7 +633,16 @@ private double[][] calculateAngleMoments(final ImagePlus imp,
615633
final double min, final double max, final double[] angles)
616634
{
617635
final ImageStack stack = imp.getImageStack();
618-
final Rectangle r = stack.getRoi();
636+
int rx = 0; int ry = 0; int rwidth = 0; int rheight = 0;
637+
if (imp.getRoi() == null) {
638+
rwidth = imp.getWidth();
639+
rheight = imp.getHeight();
640+
} else {
641+
rx = imp.getRoi().getBounds().x;
642+
ry = imp.getRoi().getBounds().y;
643+
rwidth = imp.getRoi().getBounds().width;
644+
rheight = imp.getRoi().getBounds().height;
645+
}
619646
final double[] I1 = new double[al];
620647
final double[] I2 = new double[al];
621648
final double[] Ip = new double[al];
@@ -654,15 +681,15 @@ private double[][] calculateAngleMoments(final ImagePlus imp,
654681
double maxRadCentreS = 0;
655682
final double cosTheta = Math.cos(angles[s]);
656683
final double sinTheta = Math.sin(angles[s]);
657-
final int roiYEnd = r.y + r.height;
658-
final int roiXEnd = r.x + r.width;
684+
final int roiYEnd = ry + rheight;
685+
final int roiXEnd = rx + rwidth;
659686
final double xC = sliceCentroids[0][s];
660687
final double yC = sliceCentroids[1][s];
661688
final double cS = cslice[s];
662689
double sumAreaFractions = 0;
663-
for (int y = r.y; y < roiYEnd; y++) {
690+
for (int y = ry; y < roiYEnd; y++) {
664691
final double yYc = y * vH - yC;
665-
for (int x = r.x; x < roiXEnd; x++) {
692+
for (int x = rx; x < roiXEnd; x++) {
666693
final double pixel = ip.get(x, y);
667694
if (pixel >= min && pixel <= max) {
668695
final double areaFraction = doPartialVolume ? filledFraction(
@@ -749,7 +776,16 @@ private void calculateThickness3D(final ImagePlus imp, final double min,
749776
maxCortThick3D = new double[al];
750777
meanCortThick3D = new double[al];
751778
stdevCortThick3D = new double[al];
752-
final Rectangle r = imp.getProcessor().getRoi();
779+
int rx = 0; int ry = 0; int rwidth = 0; int rheight = 0;
780+
if (imp.getRoi() == null) {
781+
rwidth = imp.getWidth();
782+
rheight = imp.getHeight();
783+
} else {
784+
rx = imp.getRoi().getBounds().x;
785+
ry = imp.getRoi().getBounds().y;
786+
rwidth = imp.getRoi().getBounds().width;
787+
rheight = imp.getRoi().getBounds().height;
788+
}
753789

754790
// convert to binary
755791
final ImagePlus binaryImp = convertToBinary(imp, min, max);
@@ -768,10 +804,10 @@ private void calculateThickness3D(final ImagePlus imp, final double min,
768804
double sumPix = 0;
769805
double sliceMax = 0;
770806
double pixCount = 0;
771-
final int roiXEnd = r.x + r.width;
772-
final int roiYEnd = r.y + r.height;
773-
for (int y = r.y; y < roiYEnd; y++) {
774-
for (int x = r.x; x < roiXEnd; x++) {
807+
final int roiXEnd = rx + rwidth;
808+
final int roiYEnd = ry + rheight;
809+
for (int y = ry; y < roiYEnd; y++) {
810+
for (int x = rx; x < roiXEnd; x++) {
775811
final float pixel = Float.intBitsToFloat(ip.get(x, y));
776812
if (pixel > 0) {
777813
pixCount++;
@@ -785,8 +821,8 @@ private void calculateThickness3D(final ImagePlus imp, final double min,
785821
maxCortThick3D[s] = sliceMax;
786822

787823
double sumSquares = 0;
788-
for (int y = r.y; y < roiYEnd; y++) {
789-
for (int x = r.x; x < roiXEnd; x++) {
824+
for (int y = ry; y < roiYEnd; y++) {
825+
for (int x = rx; x < roiXEnd; x++) {
790826
final float pixel = Float.intBitsToFloat(ip.get(x, y));
791827
if (pixel > 0) {
792828
final double d = sliceMean - pixel;
@@ -1035,7 +1071,16 @@ public void run() {
10351071
}
10361072
final ImageProcessor ip = impT.getImageStack().getProcessor(s);
10371073
final ImagePlus sliceImp = new ImagePlus(" " + s, ip);
1038-
final Rectangle r = ip.getRoi();
1074+
int rx = 0; int ry = 0; int rwidth = 0; int rheight = 0;
1075+
if (sliceImp.getRoi() == null) {
1076+
rwidth = sliceImp.getWidth();
1077+
rheight = sliceImp.getHeight();
1078+
} else {
1079+
rx = sliceImp.getRoi().getBounds().x;
1080+
ry = sliceImp.getRoi().getBounds().y;
1081+
rwidth = sliceImp.getRoi().getBounds().width;
1082+
rheight = sliceImp.getRoi().getBounds().height;
1083+
}
10391084
// binarise
10401085
final ImagePlus binaryImp = convertToBinary(sliceImp, min, max);
10411086
final Calibration cal = impT.getCalibration();
@@ -1047,10 +1092,10 @@ public void run() {
10471092
double sumPix = 0;
10481093
double sliceMax = 0;
10491094
double pixCount = 0;
1050-
final double roiXEnd = r.x + r.width;
1051-
final double roiYEnd = r.y + r.height;
1052-
for (int y = r.y; y < roiYEnd; y++) {
1053-
for (int x = r.x; x < roiXEnd; x++) {
1095+
final double roiXEnd = rx + rwidth;
1096+
final double roiYEnd = ry + rheight;
1097+
for (int y = ry; y < roiYEnd; y++) {
1098+
for (int x = rx; x < roiXEnd; x++) {
10541099
final float pixel = Float.intBitsToFloat(thickIp.get(x, y));
10551100
if (pixel > 0) {
10561101
pixCount++;
@@ -1064,8 +1109,8 @@ public void run() {
10641109
maxThick[s] = sliceMax;
10651110

10661111
double sumSquares = 0;
1067-
for (int y = r.y; y < roiYEnd; y++) {
1068-
for (int x = r.x; x < roiXEnd; x++) {
1112+
for (int y = ry; y < roiYEnd; y++) {
1113+
for (int x = rx; x < roiXEnd; x++) {
10691114
final float pixel = Float.intBitsToFloat(thickIp.get(x, y));
10701115
if (pixel > 0) {
10711116
final double d = sliceMean - pixel;

0 commit comments

Comments
 (0)