diff --git a/main/boofcv-geo/src/main/java/boofcv/abst/geo/calibration/DetectMultiFiducialCalibration.java b/main/boofcv-geo/src/main/java/boofcv/abst/geo/calibration/DetectMultiFiducialCalibration.java index 7f983b7a86..81ab777837 100644 --- a/main/boofcv-geo/src/main/java/boofcv/abst/geo/calibration/DetectMultiFiducialCalibration.java +++ b/main/boofcv-geo/src/main/java/boofcv/abst/geo/calibration/DetectMultiFiducialCalibration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Peter Abeles. All Rights Reserved. + * Copyright (c) 2023, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * @@ -24,6 +24,8 @@ import georegression.struct.point.Point2D_F64; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; /** @@ -43,9 +45,6 @@ public interface DetectMultiFiducialCalibration { /** Returns the number of detected markers */ int getDetectionCount(); - /** Returns which marker was seen for a particular detection */ - int getMarkerID( int detectionID ); - /** Returns the number of unique markers that it can detect */ int getTotalUniqueMarkers(); @@ -66,6 +65,35 @@ public interface DetectMultiFiducialCalibration { */ List getLayout( int markerID ); + /** + * Returns the layout for all markers as a list. + */ + default List> getLayouts() { + var list = new ArrayList>(); + for (int i = 0; i < getTotalUniqueMarkers(); i++) { + list.add(getLayout(i)); + } + return list; + } + + /** + * Returns the observations with the most detected landmarks for each specific target + */ + default List getBestForEachTarget() { + var markerToObservations = new HashMap(); + for (int i = 0; i < getDetectionCount(); i++) { + CalibrationObservation o = getDetectedPoints(i); + CalibrationObservation previousBest = markerToObservations.get(o.target); + + // First time it's seen this target ID or if the new observation has more points + if (previousBest == null || previousBest.size() < o.size()) { + markerToObservations.put(o.target, o); + } + } + + return new ArrayList<>(markerToObservations.values()); + } + /** * Explicitly handles lens distortion when detecting image features. If used, features will be found in * undistorted pixel coordinates diff --git a/main/boofcv-geo/src/main/java/boofcv/abst/geo/calibration/MultiToSingleFiducialCalibration.java b/main/boofcv-geo/src/main/java/boofcv/abst/geo/calibration/MultiToSingleFiducialCalibration.java index 74c4338395..3dbe1416b5 100644 --- a/main/boofcv-geo/src/main/java/boofcv/abst/geo/calibration/MultiToSingleFiducialCalibration.java +++ b/main/boofcv-geo/src/main/java/boofcv/abst/geo/calibration/MultiToSingleFiducialCalibration.java @@ -61,7 +61,8 @@ public MultiToSingleFiducialCalibration( int target, DetectMultiFiducialCalibrat detectedIndex = -1; for (int i = 0; i < multi.getDetectionCount(); i++) { - if (multi.getMarkerID(i) == targetMarker) { + CalibrationObservation o = multi.getDetectedPoints(i); + if (o.target == targetMarker) { detectedIndex = i; break; } diff --git a/main/boofcv-recognition/src/main/java/boofcv/abst/fiducial/calib/CalibrationDetectorMultiECoCheck.java b/main/boofcv-recognition/src/main/java/boofcv/abst/fiducial/calib/CalibrationDetectorMultiECoCheck.java index 16c24f71c5..002d70b19e 100644 --- a/main/boofcv-recognition/src/main/java/boofcv/abst/fiducial/calib/CalibrationDetectorMultiECoCheck.java +++ b/main/boofcv-recognition/src/main/java/boofcv/abst/fiducial/calib/CalibrationDetectorMultiECoCheck.java @@ -75,10 +75,6 @@ public CalibrationDetectorMultiECoCheck( ECoCheckDetector detector, return detector.getFound().size; } - @Override public int getMarkerID( int detectionID ) { - return detector.getFound().get(detectionID).markerID; - } - @Override public int getTotalUniqueMarkers() { return detector.getUtils().markers.size(); } @@ -87,6 +83,7 @@ public CalibrationDetectorMultiECoCheck( ECoCheckDetector detector, FastAccess original = detector.getFound().get(detectionID).corners; var found = new CalibrationObservation(); + found.target = detector.getFound().get(detectionID).markerID; for (int i = 0; i < original.size; i++) { found.points.add(original.get(i).copy()); } diff --git a/main/boofcv-recognition/src/test/java/boofcv/abst/fiducial/calib/GenericDetectMultiFiducialCalibrationChecks.java b/main/boofcv-recognition/src/test/java/boofcv/abst/fiducial/calib/GenericDetectMultiFiducialCalibrationChecks.java index d39bfbd38a..8efb9f402a 100644 --- a/main/boofcv-recognition/src/test/java/boofcv/abst/fiducial/calib/GenericDetectMultiFiducialCalibrationChecks.java +++ b/main/boofcv-recognition/src/test/java/boofcv/abst/fiducial/calib/GenericDetectMultiFiducialCalibrationChecks.java @@ -19,6 +19,7 @@ package boofcv.abst.fiducial.calib; import boofcv.abst.geo.calibration.DetectMultiFiducialCalibration; +import boofcv.alg.geo.calibration.CalibrationObservation; import boofcv.gui.image.ShowImages; import boofcv.io.image.UtilImageIO; import boofcv.misc.BoofMiscOps; @@ -33,6 +34,7 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -81,21 +83,27 @@ public abstract class GenericDetectMultiFiducialCalibrationChecks extends BoofSt // BoofMiscOps.sleep(2_000); // Number of markers which are not anonymous - int totalIdentified = 0; + var foundTargets = new HashSet(); for (int i = 0; i < detector.getDetectionCount(); i++) { - if (detector.getMarkerID(i) >= 0) - totalIdentified++; + CalibrationObservation o = detector.getDetectedPoints(i); + if (o.target < 0) + continue; + foundTargets.add(o.target); } - if (visualizeFailures && 2 != totalIdentified) { + // See if each target was found + assertTrue(foundTargets.contains(0)); + assertTrue(foundTargets.contains(1)); + assertEquals(2, foundTargets.size()); + + if (visualizeFailures && 2 != foundTargets.size()) { UtilImageIO.saveImage(simulator.getOutput(), "failed.png"); ShowImages.showWindow(simulator.getOutput(), "Simulated"); BoofMiscOps.sleep(10_000); } - assertEquals(2, totalIdentified); for (int i = 0; i < detector.getDetectionCount(); i++) { - int markerID = detector.getMarkerID(i); + int markerID = detector.getDetectedPoints(i).target; // Ignore anonymous markers if (markerID < 0)