Skip to content

Commit

Permalink
feature/multi-target
Browse files Browse the repository at this point in the history
- EcoCheck correctly labels detections now
- Removed getMarkerID() as it is redundant
- Added unit test to catch this bug in the future
  • Loading branch information
lessthanoptimal committed Aug 28, 2023
1 parent f1edf58 commit 89ab68f
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 15 deletions.
@@ -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).
*
Expand All @@ -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;

/**
Expand All @@ -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();

Expand All @@ -66,6 +65,35 @@ public interface DetectMultiFiducialCalibration {
*/
List<Point2D_F64> getLayout( int markerID );

/**
* Returns the layout for all markers as a list.
*/
default List<List<Point2D_F64>> getLayouts() {
var list = new ArrayList<List<Point2D_F64>>();
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<CalibrationObservation> getBestForEachTarget() {
var markerToObservations = new HashMap<Integer, CalibrationObservation>();
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
Expand Down
Expand Up @@ -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;
}
Expand Down
Expand Up @@ -75,10 +75,6 @@ public CalibrationDetectorMultiECoCheck( ECoCheckDetector<GrayF32> 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();
}
Expand All @@ -87,6 +83,7 @@ public CalibrationDetectorMultiECoCheck( ECoCheckDetector<GrayF32> detector,
FastAccess<PointIndex2D_F64> 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());
}
Expand Down
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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<Integer>();
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)
Expand Down

0 comments on commit 89ab68f

Please sign in to comment.