From 7de2e1e7957075ebbd504b2c9aea256e61b2d547 Mon Sep 17 00:00:00 2001 From: Matthew Self Date: Fri, 26 Aug 2016 20:39:38 -0700 Subject: [PATCH] Improve perfomance of median calculation in LMedS algorithm * Use `nth_element()` to find the median instead of `sort()` in `LMeDSPointSetRegistrator::run()` * Improves performance of this part of LMedS from `n log(n)` to `n` by avoiding doing a full sort. * Makes LMedS 2x faster for 100 points, 4x faster for 5,000 points in `EstimateAffine2D()`. * LMedS is now never more than 2x slower than RANSAC and is faster in some cases. --- modules/calib3d/src/ptsetreg.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/calib3d/src/ptsetreg.cpp b/modules/calib3d/src/ptsetreg.cpp index 830fa8ae1a..5e652d4fd5 100644 --- a/modules/calib3d/src/ptsetreg.cpp +++ b/modules/calib3d/src/ptsetreg.cpp @@ -344,10 +344,8 @@ public: else errf = err; CV_Assert( errf.isContinuous() && errf.type() == CV_32F && (int)errf.total() == count ); - std::sort(errf.ptr(), errf.ptr() + count); - - double median = count % 2 != 0 ? - errf.at(count/2) : (errf.at(count/2-1) + errf.at(count/2))*0.5; + std::nth_element(errf.ptr(), errf.ptr() + count/2, errf.ptr() + count); + double median = errf.at(count/2); if( median < minMedian ) {