Pass RANSAC parameters as function input (#10569)
authorbranka-plateiq <branka@plateiq.com>
Tue, 26 Jun 2018 13:40:28 +0000 (06:40 -0700)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Tue, 26 Jun 2018 13:40:28 +0000 (16:40 +0300)
* Pass RANSAC parameters as function input

* Clean up unnecessary code

* Keep the original function signature

* Clean up based on PR comments

Replace array with vector.

Correct naming convention for input variables.

Add checks on input variables.

* Use vector instead of array for dynamic size

* Revert change.

* Use dynamic array

* Fix wrong syntax in array allocation

* Undo change

* Fix variable name

* Use vector and not array

* fixed compile warning on Windows

modules/video/include/opencv2/video/tracking.hpp
modules/video/src/lkpyramid.cpp

index d397ac7..8e01d16 100644 (file)
@@ -250,7 +250,9 @@ when fullAffine=false.
 @sa
 estimateAffine2D, estimateAffinePartial2D, getAffineTransform, getPerspectiveTransform, findHomography
  */
-CV_EXPORTS_W Mat estimateRigidTransform( InputArray src, InputArray dst, bool fullAffine );
+CV_EXPORTS_W Mat estimateRigidTransform( InputArray src, InputArray dst, bool fullAffine);
+CV_EXPORTS_W Mat estimateRigidTransform( InputArray src, InputArray dst, bool fullAffine, int ransacMaxIters, double ransacGoodRatio,
+                                         int ransacSize0);
 
 
 enum
index 48f896d..353e356 100644 (file)
@@ -1412,7 +1412,7 @@ namespace cv
 {
 
 static void
-getRTMatrix( const Point2f* a, const Point2f* b,
+getRTMatrix( const std::vector<Point2f> a, const std::vector<Point2f> b,
              int count, Mat& M, bool fullAffine )
 {
     CV_Assert( M.isContinuous() );
@@ -1489,15 +1489,18 @@ getRTMatrix( const Point2f* a, const Point2f* b,
 
 cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullAffine )
 {
+    return estimateRigidTransform(src1, src2, fullAffine, 500, 0.5, 3);
+}
+
+cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullAffine, int ransacMaxIters, double ransacGoodRatio,
+                                    const int ransacSize0)
+{
     CV_INSTRUMENT_REGION()
 
     Mat M(2, 3, CV_64F), A = src1.getMat(), B = src2.getMat();
 
     const int COUNT = 15;
     const int WIDTH = 160, HEIGHT = 120;
-    const int RANSAC_MAX_ITERS = 500;
-    const int RANSAC_SIZE0 = 3;
-    const double RANSAC_GOOD_RATIO = 0.5;
 
     std::vector<Point2f> pA, pB;
     std::vector<int> good_idx;
@@ -1509,6 +1512,12 @@ cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullA
     RNG rng((uint64)-1);
     int good_count = 0;
 
+    if( ransacSize0 < 3 )
+        CV_Error( Error::StsBadArg, "ransacSize0 should have value bigger than 2.");
+
+    if( ransacGoodRatio > 1 || ransacGoodRatio < 0)
+        CV_Error( Error::StsBadArg, "ransacGoodRatio should have value between 0 and 1");
+
     if( A.size() != B.size() )
         CV_Error( Error::StsUnmatchedSizes, "Both input images must have the same size" );
 
@@ -1597,23 +1606,23 @@ cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullA
 
     good_idx.resize(count);
 
-    if( count < RANSAC_SIZE0 )
+    if( count < ransacSize0 )
         return Mat();
 
     Rect brect = boundingRect(pB);
 
+    std::vector<Point2f> a(ransacSize0);
+    std::vector<Point2f> b(ransacSize0);
+
     // RANSAC stuff:
     // 1. find the consensus
-    for( k = 0; k < RANSAC_MAX_ITERS; k++ )
+    for( k = 0; k < ransacMaxIters; k++ )
     {
-        int idx[RANSAC_SIZE0];
-        Point2f a[RANSAC_SIZE0];
-        Point2f b[RANSAC_SIZE0];
-
-        // choose random 3 non-coplanar points from A & B
-        for( i = 0; i < RANSAC_SIZE0; i++ )
+        std::vector<int> idx(ransacSize0);
+        // choose random 3 non-complanar points from A & B
+        for( i = 0; i < ransacSize0; i++ )
         {
-            for( k1 = 0; k1 < RANSAC_MAX_ITERS; k1++ )
+            for( k1 = 0; k1 < ransacMaxIters; k1++ )
             {
                 idx[i] = rng.uniform(0, count);
 
@@ -1633,7 +1642,7 @@ cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullA
                 if( j < i )
                     continue;
 
-                if( i+1 == RANSAC_SIZE0 )
+                if( i+1 == ransacSize0 )
                 {
                     // additional check for non-complanar vectors
                     a[0] = pA[idx[0]];
@@ -1657,11 +1666,11 @@ cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullA
                 break;
             }
 
-            if( k1 >= RANSAC_MAX_ITERS )
+            if( k1 >= ransacMaxIters )
                 break;
         }
 
-        if( i < RANSAC_SIZE0 )
+        if( i < ransacSize0 )
             continue;
 
         // estimate the transformation using 3 points
@@ -1675,11 +1684,11 @@ cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullA
                 good_idx[good_count++] = i;
         }
 
-        if( good_count >= count*RANSAC_GOOD_RATIO )
+        if( good_count >= count*ransacGoodRatio )
             break;
     }
 
-    if( k >= RANSAC_MAX_ITERS )
+    if( k >= ransacMaxIters )
         return Mat();
 
     if( good_count < count )
@@ -1692,7 +1701,7 @@ cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullA
         }
     }
 
-    getRTMatrix( &pA[0], &pB[0], good_count, M, fullAffine );
+    getRTMatrix( pA, pB, good_count, M, fullAffine );
     M.at<double>(0, 2) /= scale;
     M.at<double>(1, 2) /= scale;