From 7b7a62528f0eeb452d1d685a4ac5afea0cac8904 Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Fri, 12 Jun 2026 17:13:15 +0200 Subject: [PATCH] Get MCC to be deterministic --- modules/objdetect/src/mcc/checker_detector.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/objdetect/src/mcc/checker_detector.cpp b/modules/objdetect/src/mcc/checker_detector.cpp index 0803b73d2e..e89e9fd13f 100644 --- a/modules/objdetect/src/mcc/checker_detector.cpp +++ b/modules/objdetect/src/mcc/checker_detector.cpp @@ -1265,6 +1265,18 @@ void CCheckerDetectorImpl:: void CCheckerDetectorImpl:: removeTooCloseDetections() { + // Provide a deterministic output by sorting the checkers by their cost and + // then by their center coordinates. + std::sort(m_checkers.begin(), m_checkers.end(), + [](const Ptr &a, const Ptr &b) { + if (a->getCost() != b->getCost()) + return a->getCost() < b->getCost(); + Point2f ca = a->getCenter(); + Point2f cb = b->getCenter(); + if (ca.x != cb.x) return ca.x < cb.x; + return ca.y < cb.y; + }); + // Remove these elements which corners are too close to each other. // Eliminate overlaps!!! // First detect candidates for removal: @@ -1306,8 +1318,10 @@ void CCheckerDetectorImpl:: size_t removalIndex; if (p1 < p2) removalIndex = tooNearCandidates[i].second; - else + else if (p2 < p1) removalIndex = tooNearCandidates[i].first; + else + removalIndex = std::max(tooNearCandidates[i].first, tooNearCandidates[i].second); removalMask[removalIndex] = true; } @@ -1322,7 +1336,7 @@ void CCheckerDetectorImpl:: m_checkers.push_back(copy_m_checkers[i]); } - sort( m_checkers.begin(), m_checkers.end(), + std::stable_sort( m_checkers.begin(), m_checkers.end(), [&](const Ptr &a, const Ptr &b) { return a->getCost() < b->getCost();