Commit:
84678f9Parent:
693438fAdd RANSAC/match-count diagnostics to exhaustive_matcher
Real-data testing showed near-total geometric verification failure (3/3081 pairs at min_score=0.0, 0/3071 at min_score=0.2 -- getting worse with a stricter threshold rules out "too much noise" as the sole explanation). The pass/fail count against MIN_INLIERS alone can't distinguish "pairs are landing just under the threshold" from "there's a correctness bug upstream of RANSAC", so report the actual best-inlier-count and raw-match-count distributions across all candidate pairs to tell those apart. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
src/exhaustive_matcher.rs
+43
-0
diff --git a/src/exhaustive_matcher.rs b/src/exhaustive_matcher.rs
index 522b90f..1f8443e 100644
@@ -204,6 +204,49 @@ pub fn run(cfg: ExhaustiveMatcherConfig) -> Result<()> {
.collect();
ransac_pb.finish();
// Diagnostics: raising --min_score made verification *worse* rather than better,
// which rules out "too much low-confidence noise" as the sole explanation. Report
// the actual best-inlier-count RANSAC found per pair (not just pass/fail against
// MIN_INLIERS) and raw match counts, so we can see the real shape of the data.
{
let percentile = |sorted: &[usize], p: usize| -> usize {
if sorted.is_empty() {
0
} else {
sorted[(sorted.len() - 1) * p / 100]
}
};
let mut best_inliers: Vec<usize> = ransac_results
.iter()
.map(|r| r.as_ref().map_or(0, |r| r.inliers.len()))
.collect();
best_inliers.sort_unstable();
let no_model_count = ransac_results.iter().filter(|r| r.is_none()).count();
let mut raw_counts: Vec<usize> = pending.iter().map(|p| p.matched.len()).collect();
raw_counts.sort_unstable();
eprintln!(
"[diag] RANSAC found <8 inliers (no model) for {no_model_count}/{} pairs",
ransac_results.len()
);
eprintln!(
"[diag] best inlier count per pair: p10={} p50={} p90={} max={}",
percentile(&best_inliers, 10),
percentile(&best_inliers, 50),
percentile(&best_inliers, 90),
best_inliers.last().copied().unwrap_or(0)
);
eprintln!(
"[diag] raw LightGlue match count per pair: p10={} p50={} p90={} max={}",
percentile(&raw_counts, 10),
percentile(&raw_counts, 50),
percentile(&raw_counts, 90),
raw_counts.last().copied().unwrap_or(0)
);
}
let mut verified_pairs = 0usize;
let mut total_inliers = 0usize;
for (pair, result) in pending.iter().zip(ransac_results.iter()) {