Skip to content

Commit f62d70b

Browse files
committed
MorphometricFeatures2D now populates table in the same order features are specified
1 parent 6fbb363 commit f62d70b

1 file changed

Lines changed: 187 additions & 164 deletions

File tree

‎src/main/java/inra/ijpb/measure/region2d/MorphometricFeatures2D.java‎

Lines changed: 187 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
import java.util.ArrayList;
3131
import java.util.Collection;
3232
import java.util.List;
33+
import java.util.stream.Stream;
3334

35+
import ij.IJ;
3436
import ij.ImagePlus;
3537
import ij.measure.Calibration;
3638
import ij.measure.ResultsTable;
@@ -378,6 +380,7 @@ else if (contains(CENTROID))
378380
results.avgThickness = algo.analyzeRegions(image, labels, calib);
379381
}
380382

383+
this.fireStatusChanged(this, "");
381384
return results;
382385
}
383386

@@ -405,170 +408,190 @@ private ResultsTable populateTable(Results results)
405408
table.addLabel("" + results.labels[i]);
406409
}
407410

408-
if (features.contains(PIXEL_COUNT))
409-
{
410-
addColumnToTable(table, "PixelCount", results.pixelCounts);
411-
}
412-
413-
if (features.contains(AREA))
414-
{
415-
for (int i = 0; i < nLabels; i++)
416-
{
417-
table.setValue("Area", i, results.intrinsicVolumes[i].area);
418-
}
419-
}
420-
421-
if (features.contains(PERIMETER))
422-
{
423-
for (int i = 0; i < nLabels; i++)
424-
{
425-
table.setValue("Perimeter", i, results.intrinsicVolumes[i].perimeter);
426-
}
427-
}
428-
429-
if (features.contains(CIRCULARITY))
430-
{
431-
double[] circularities = IntrinsicVolumes2DUtils.computeCircularities(results.intrinsicVolumes);
432-
addColumnToTable(table, "Circularity", circularities);
433-
}
434-
435-
if (features.contains(EULER_NUMBER))
436-
{
437-
for (int i = 0; i < nLabels; i++)
438-
{
439-
table.setValue("EulerNumber", i, results.intrinsicVolumes[i].eulerNumber);
440-
}
441-
}
442-
443-
if (features.contains(BOUNDING_BOX))
444-
{
445-
for (int i = 0; i < nLabels; i++)
446-
{
447-
Box2D box = results.boundingBoxes[i];
448-
table.setValue("Box.X.Min", i, box.getXMin());
449-
table.setValue("Box.X.Max", i, box.getXMax());
450-
table.setValue("Box.Y.Min", i, box.getYMin());
451-
table.setValue("Box.Y.Max", i, box.getYMax());
452-
}
453-
}
454-
455-
if (features.contains(CENTROID))
456-
{
457-
for (int i = 0; i < nLabels; i++)
458-
{
459-
Point2D center = results.centroids[i];
460-
table.setValue("Centroid.X", i, center.getX());
461-
table.setValue("Centroid.Y", i, center.getY());
462-
}
463-
}
464-
465-
if (features.contains(EQUIVALENT_ELLIPSE))
466-
{
467-
for (int i = 0; i < nLabels; i++)
468-
{
469-
Ellipse elli = results.ellipses[i];
470-
Point2D center = elli.center();
471-
table.setValue("Ellipse.Center.X", i, center.getX());
472-
table.setValue("Ellipse.Center.Y", i, center.getY());
473-
table.setValue("Ellipse.Radius1", i, elli.radius1());
474-
table.setValue("Ellipse.Radius2", i, elli.radius2());
475-
table.setValue("Ellipse.Orientation", i, elli.orientation());
476-
}
477-
}
478-
479-
if (features.contains(ELLIPSE_ELONGATION))
480-
{
481-
double[] elong = new double[nLabels];
482-
for (int i = 0; i < nLabels; i++)
483-
{
484-
Ellipse elli = results.ellipses[i];
485-
elong[i] = elli.radius1() / elli.radius2();
486-
}
487-
addColumnToTable(table, "Ellipse.Elong", elong);
488-
}
489-
490-
if (features.contains(CONVEXITY))
491-
{
492-
for (int i = 0; i < nLabels; i++)
493-
{
494-
table.setValue("ConvexArea", i, results.convexities[i].convexArea);
495-
table.setValue("Convexity", i, results.convexities[i].convexity);
496-
}
497-
}
498-
499-
if (features.contains(MAX_FERET_DIAMETER))
500-
{
501-
for (int i = 0; i < nLabels; i++)
502-
{
503-
table.setValue("MaxFeretDiam", i, results.maxFeretDiams[i].diameter());
504-
table.setValue("MaxFeretDiamAngle", i, Math.toDegrees(results.maxFeretDiams[i].angle()));
505-
}
506-
}
507-
508-
if (features.contains(ORIENTED_BOX))
509-
{
510-
for (int i = 0; i < nLabels; i++)
511-
{
512-
OrientedBox2D obox = results.orientedBoxes[i];
513-
Point2D center = obox.center();
514-
table.setValue("OBox.Center.X", i, center.getX());
515-
table.setValue("OBox.Center.Y", i, center.getY());
516-
table.setValue("OBox.Length", i, obox.length());
517-
table.setValue("OBox.Width", i, obox.width());
518-
table.setValue("OBox.Orientation", i, obox.orientation());
519-
}
520-
}
521-
522-
if (features.contains(GEODESIC_DIAMETER))
523-
{
524-
for (int i = 0; i < nLabels; i++)
525-
{
526-
GeodesicDiameter.Result result = results.geodDiams[i];
527-
table.setValue("GeodesicDiameter", i, result.diameter);
528-
}
529-
}
530-
531-
if (features.contains(TORTUOSITY))
532-
{
533-
double[] tortuosity = new double[nLabels];
534-
for (int i = 0; i < nLabels; i++)
535-
{
536-
tortuosity[i] = results.geodDiams[i].diameter / results.maxFeretDiams[i].diameter();
537-
}
538-
addColumnToTable(table, "Tortuosity", tortuosity);
539-
}
540-
541-
if (features.contains(MAX_INSCRIBED_DISK))
542-
{
543-
for (int i = 0; i < nLabels; i++)
544-
{
545-
Point2D center = results.inscrDiscs[i].getCenter();
546-
table.setValue("InscrDisc.Center.X", i, center.getX());
547-
table.setValue("InscrDisc.Center.Y", i, center.getY());
548-
table.setValue("InscrDisc.Radius", i, results.inscrDiscs[i].getRadius());
549-
}
550-
}
551-
552-
if (features.contains(AVERAGE_THICKNESS))
553-
{
554-
for (int i = 0; i < nLabels; i++)
555-
{
556-
AverageThickness.Result res = results.avgThickness[i];
557-
table.setValue("AverageThickness", i, res.avgThickness);
558-
}
559-
}
560-
561-
if (features.contains(GEODESIC_ELONGATION))
562-
{
563-
double[] elong = new double[nLabels];
564-
for (int i = 0; i < nLabels; i++)
565-
{
566-
elong[i] = results.geodDiams[i].diameter
567-
/ (results.inscrDiscs[i].getRadius() * 2);
568-
}
569-
addColumnToTable(table, "GeodesicElongation", elong);
570-
}
571-
411+
/**
412+
* Iterate over features, in the order they are specified.
413+
*/
414+
for (Feature feature : features)
415+
{
416+
switch (feature)
417+
{
418+
case PIXEL_COUNT:
419+
{
420+
addColumnToTable(table, "PixelCount", results.pixelCounts);
421+
break;
422+
}
423+
case AREA:
424+
{
425+
double[] areas = Stream.of(results.intrinsicVolumes)
426+
.mapToDouble(res -> res.area)
427+
.toArray();
428+
addColumnToTable(table, "Area", areas);
429+
break;
430+
}
431+
case PERIMETER:
432+
{
433+
double[] perimeters = Stream.of(results.intrinsicVolumes)
434+
.mapToDouble(res -> res.perimeter)
435+
.toArray();
436+
addColumnToTable(table, "Perimeter", perimeters);
437+
break;
438+
}
439+
case CIRCULARITY:
440+
{
441+
double[] circularities = IntrinsicVolumes2DUtils.computeCircularities(results.intrinsicVolumes);
442+
addColumnToTable(table, "Circularity", circularities);
443+
break;
444+
}
445+
case EULER_NUMBER:
446+
{
447+
double[] eulerNumbers = Stream.of(results.intrinsicVolumes)
448+
.mapToDouble(res -> res.eulerNumber)
449+
.toArray();
450+
addColumnToTable(table, "EulerNumber", eulerNumbers);
451+
break;
452+
}
453+
case BOUNDING_BOX:
454+
{
455+
for (int i = 0; i < nLabels; i++)
456+
{
457+
Box2D box = results.boundingBoxes[i];
458+
table.setValue("Box.X.Min", i, box.getXMin());
459+
table.setValue("Box.X.Max", i, box.getXMax());
460+
table.setValue("Box.Y.Min", i, box.getYMin());
461+
table.setValue("Box.Y.Max", i, box.getYMax());
462+
}
463+
break;
464+
}
465+
case CENTROID:
466+
{
467+
for (int i = 0; i < nLabels; i++)
468+
{
469+
Point2D center = results.centroids[i];
470+
table.setValue("Centroid.X", i, center.getX());
471+
table.setValue("Centroid.Y", i, center.getY());
472+
}
473+
break;
474+
}
475+
case EQUIVALENT_ELLIPSE:
476+
{
477+
for (int i = 0; i < nLabels; i++)
478+
{
479+
Ellipse elli = results.ellipses[i];
480+
Point2D center = elli.center();
481+
table.setValue("Ellipse.Center.X", i, center.getX());
482+
table.setValue("Ellipse.Center.Y", i, center.getY());
483+
table.setValue("Ellipse.Radius1", i, elli.radius1());
484+
table.setValue("Ellipse.Radius2", i, elli.radius2());
485+
table.setValue("Ellipse.Orientation", i, elli.orientation());
486+
}
487+
break;
488+
}
489+
case ELLIPSE_ELONGATION:
490+
{
491+
double[] elong = new double[nLabels];
492+
for (int i = 0; i < nLabels; i++)
493+
{
494+
Ellipse elli = results.ellipses[i];
495+
elong[i] = elli.radius1() / elli.radius2();
496+
}
497+
addColumnToTable(table, "Ellipse.Elong", elong);
498+
break;
499+
}
500+
case CONVEXITY:
501+
{
502+
for (int i = 0; i < nLabels; i++)
503+
{
504+
table.setValue("ConvexArea", i, results.convexities[i].convexArea);
505+
table.setValue("Convexity", i, results.convexities[i].convexity);
506+
}
507+
break;
508+
}
509+
case MAX_FERET_DIAMETER:
510+
{
511+
for (int i = 0; i < nLabels; i++)
512+
{
513+
table.setValue("MaxFeretDiam", i, results.maxFeretDiams[i].diameter());
514+
table.setValue("MaxFeretDiamAngle", i, Math.toDegrees(results.maxFeretDiams[i].angle()));
515+
}
516+
break;
517+
}
518+
case ORIENTED_BOX:
519+
{
520+
for (int i = 0; i < nLabels; i++)
521+
{
522+
OrientedBox2D obox = results.orientedBoxes[i];
523+
Point2D center = obox.center();
524+
table.setValue("OBox.Center.X", i, center.getX());
525+
table.setValue("OBox.Center.Y", i, center.getY());
526+
table.setValue("OBox.Length", i, obox.length());
527+
table.setValue("OBox.Width", i, obox.width());
528+
table.setValue("OBox.Orientation", i, obox.orientation());
529+
}
530+
break;
531+
}
532+
case ORIENTED_BOX_ELONGATION:
533+
{
534+
double[] elongations = Stream.of(results.orientedBoxes)
535+
.mapToDouble(obox -> obox.length() / obox.width())
536+
.toArray();
537+
addColumnToTable(table, "OBox.Elongation", elongations);
538+
break;
539+
}
540+
case GEODESIC_DIAMETER:
541+
{
542+
double[] diameter = Stream.of(results.geodDiams)
543+
.mapToDouble(gdData -> gdData.diameter)
544+
.toArray();
545+
addColumnToTable(table, "GeodesicDiameter", diameter);
546+
break;
547+
}
548+
case TORTUOSITY:
549+
{
550+
double[] tortuosity = new double[nLabels];
551+
for (int i = 0; i < nLabels; i++)
552+
{
553+
tortuosity[i] = results.geodDiams[i].diameter / results.maxFeretDiams[i].diameter();
554+
}
555+
addColumnToTable(table, "Tortuosity", tortuosity);
556+
break;
557+
}
558+
case MAX_INSCRIBED_DISK:
559+
{
560+
for (int i = 0; i < nLabels; i++)
561+
{
562+
Point2D center = results.inscrDiscs[i].getCenter();
563+
table.setValue("InscrDisc.Center.X", i, center.getX());
564+
table.setValue("InscrDisc.Center.Y", i, center.getY());
565+
table.setValue("InscrDisc.Radius", i, results.inscrDiscs[i].getRadius());
566+
}
567+
break;
568+
}
569+
case AVERAGE_THICKNESS:
570+
{
571+
for (int i = 0; i < nLabels; i++)
572+
{
573+
AverageThickness.Result res = results.avgThickness[i];
574+
table.setValue("AverageThickness", i, res.avgThickness);
575+
}
576+
break;
577+
}
578+
case GEODESIC_ELONGATION:
579+
{
580+
double[] elong = new double[nLabels];
581+
for (int i = 0; i < nLabels; i++)
582+
{
583+
elong[i] = results.geodDiams[i].diameter / (results.inscrDiscs[i].getRadius() * 2);
584+
}
585+
addColumnToTable(table, "GeodesicElongation", elong);
586+
break;
587+
}
588+
default:
589+
{
590+
IJ.log("Unknown feature: " + feature.toString());
591+
}
592+
}
593+
}
594+
572595
this.fireStatusChanged(this, "");
573596
return table;
574597
}

0 commit comments

Comments
 (0)