Improve perfomance of median calculation in LMedS algorithm
authorMatthew Self <dmz@mself.com>
Sat, 27 Aug 2016 03:39:38 +0000 (20:39 -0700)
committerMatthew Self <dmz@mself.com>
Sat, 27 Aug 2016 03:39:38 +0000 (20:39 -0700)
* 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

index 830fa8a..5e652d4 100644 (file)
@@ -344,10 +344,8 @@ public:
                 else
                     errf = err;
                 CV_Assert( errf.isContinuous() && errf.type() == CV_32F && (int)errf.total() == count );
-                std::sort(errf.ptr<int>(), errf.ptr<int>() + count);
-
-                double median = count % 2 != 0 ?
-                errf.at<float>(count/2) : (errf.at<float>(count/2-1) + errf.at<float>(count/2))*0.5;
+                std::nth_element(errf.ptr<int>(), errf.ptr<int>() + count/2, errf.ptr<int>() + count);
+                double median = errf.at<float>(count/2);
 
                 if( median < minMedian )
                 {