make GPU version of solvePnPRansac more consistent with CPU one
authorAlexey Spizhevoy <no@email>
Mon, 7 Mar 2011 14:01:18 +0000 (14:01 +0000)
committerAlexey Spizhevoy <no@email>
Mon, 7 Mar 2011 14:01:18 +0000 (14:01 +0000)
modules/gpu/include/opencv2/gpu/gpu.hpp
modules/gpu/src/calib3d.cpp
modules/gpu/test/test_calib3d.cpp
samples/gpu/performance/tests.cpp

index 05c5a7e..33fa3b4 100644 (file)
@@ -868,22 +868,10 @@ namespace cv
                                       const Mat& camera_mat, const Mat& dist_coef, GpuMat& dst,\r
                                       const Stream& stream);\r
 \r
-        struct CV_EXPORTS SolvePnpRansacParams\r
-        {\r
-            SolvePnpRansacParams(): subset_size(4),\r
-                                    use_extrinsic_guess(false),\r
-                                    num_iters(100),\r
-                                    max_dist(2.f),\r
-                                    inliers(NULL) {}\r
-            int subset_size;\r
-            bool use_extrinsic_guess;\r
-            int num_iters;\r
-            float max_dist;\r
-            vector<int>* inliers;\r
-        };\r
-\r
-        CV_EXPORTS void solvePnpRansac(const Mat& object, const Mat& image, const Mat& camera_mat,\r
-                                       const Mat& dist_coef, Mat& rvec, Mat& tvec, SolvePnpRansacParams params);\r
+        CV_EXPORTS void solvePnPRansac(const Mat& object, const Mat& image, const Mat& camera_mat,\r
+                                       const Mat& dist_coef, Mat& rvec, Mat& tvec, bool use_extrinsic_guess=false,\r
+                                       int num_iters=100, float max_dist=8.0, int min_inlier_count=100, \r
+                                       vector<int>* inliers=NULL);\r
 \r
         //////////////////////////////// Filter Engine ////////////////////////////////\r
 \r
index c0374f2..32bbab6 100644 (file)
@@ -56,8 +56,8 @@ void cv::gpu::projectPoints(const GpuMat&, const Mat&, const Mat&,
 void cv::gpu::projectPoints(const GpuMat&, const Mat&, const Mat&,
                             const Mat&, const Mat&, GpuMat&, const Stream&) { throw_nogpu(); }
 
-void cv::gpu::solvePnpRansac(const Mat&, const Mat&, const Mat&, const Mat&,
-                             Mat&, Mat&, SolvePnpRansacParams) { throw_nogpu(); }
+void cv::gpu::solvePnPRansac(const Mat&, const Mat&, const Mat&, const Mat&, \r
+                             Mat&, Mat&, bool, int, float, int, vector<int>*) { throw_nogpu(); }
 
 #else
 
@@ -235,18 +235,21 @@ namespace
     };
 }
 
-void cv::gpu::solvePnpRansac(const Mat& object, const Mat& image, const Mat& camera_mat,
-                             const Mat& dist_coef, Mat& rvec, Mat& tvec, SolvePnpRansacParams params)
+void cv::gpu::solvePnPRansac(const Mat& object, const Mat& image, const Mat& camera_mat,\r
+                             const Mat& dist_coef, Mat& rvec, Mat& tvec, bool use_extrinsic_guess,\r
+                             int num_iters, float max_dist, int min_inlier_count, \r
+                             vector<int>* inliers)
 {
     CV_Assert(object.rows == 1 && object.cols > 0 && object.type() == CV_32FC3);
     CV_Assert(image.rows == 1 && image.cols > 0 && image.type() == CV_32FC2);
     CV_Assert(object.cols == image.cols);
     CV_Assert(camera_mat.size() == Size(3, 3) && camera_mat.type() == CV_32F);
-    CV_Assert(!params.use_extrinsic_guess); // We don't support initial guess for now
-    CV_Assert(params.num_iters <= solve_pnp_ransac::maxNumIters());
+    CV_Assert(!use_extrinsic_guess); // We don't support initial guess for now
+    CV_Assert(num_iters <= solve_pnp_ransac::maxNumIters());
 
+    const int subset_size = 4;
     const int num_points = object.cols;
-    CV_Assert(num_points >= params.subset_size);
+    CV_Assert(num_points >= subset_size);
 
     // Unapply distortion and intrinsic camera transformations
     Mat eye_camera_mat = Mat::eye(3, 3, CV_32F);
@@ -255,21 +258,21 @@ void cv::gpu::solvePnpRansac(const Mat& object, const Mat& image, const Mat& cam
     undistortPoints(image, image_normalized, camera_mat, dist_coef, Mat(), eye_camera_mat);
 
     // Hypotheses storage (global)
-    Mat rot_matrices(1, params.num_iters * 9, CV_32F);
-    Mat transl_vectors(1, params.num_iters * 3, CV_32F);
+    Mat rot_matrices(1, num_iters * 9, CV_32F);
+    Mat transl_vectors(1, num_iters * 3, CV_32F);
 
     // Generate set of hypotheses using small subsets of the input data
     TransformHypothesesGenerator body(object, image_normalized, empty_dist_coef, eye_camera_mat, 
-                                      num_points, params.subset_size, rot_matrices, transl_vectors);
-    parallel_for(BlockedRange(0, params.num_iters), body);
+                                      num_points, subset_size, rot_matrices, transl_vectors);
+    parallel_for(BlockedRange(0, num_iters), body);
 
     // Compute scores (i.e. number of inliers) for each hypothesis
     GpuMat d_object(object);
     GpuMat d_image_normalized(image_normalized);
-    GpuMat d_hypothesis_scores(1, params.num_iters, CV_32S);
+    GpuMat d_hypothesis_scores(1, num_iters, CV_32S);
     solve_pnp_ransac::computeHypothesisScores(
-            params.num_iters, num_points, rot_matrices.ptr<float>(), transl_vectors.ptr<float3>(),
-            d_object.ptr<float3>(), d_image_normalized.ptr<float2>(), params.max_dist * params.max_dist, 
+            num_iters, num_points, rot_matrices.ptr<float>(), transl_vectors.ptr<float3>(),
+            d_object.ptr<float3>(), d_image_normalized.ptr<float2>(), max_dist * max_dist, 
             d_hypothesis_scores.ptr<int>());
 
     // Find the best hypothesis index
@@ -288,10 +291,10 @@ void cv::gpu::solvePnpRansac(const Mat& object, const Mat& image, const Mat& cam
     tvec = tvec.reshape(0, 1);
 
     // Build vector of inlier indices
-    if (params.inliers != NULL)
+    if (inliers != NULL)
     {
-        params.inliers->clear();
-        params.inliers->reserve(num_inliers);
+        inliers->clear();
+        inliers->reserve(num_inliers);
 
         Point3f p, p_transf;
         Point2f p_proj;
@@ -306,8 +309,8 @@ void cv::gpu::solvePnpRansac(const Mat& object, const Mat& image, const Mat& cam
             p_transf.z = rot[6] * p.x + rot[7] * p.y + rot[8] * p.z + transl[2];
             p_proj.x = p_transf.x / p_transf.z;
             p_proj.y = p_transf.y / p_transf.z;
-            if (norm(p_proj - image_normalized.at<Point2f>(0, i)) < params.max_dist)
-                params.inliers->push_back(i);
+            if (norm(p_proj - image_normalized.at<Point2f>(0, i)) < max_dist)
+                inliers->push_back(i);
         }
     }
 }
index 4ea6da1..d5f6606 100644 (file)
@@ -107,7 +107,7 @@ TEST(transformPoints, accuracy)
 }
 
 
-TEST(solvePnpRansac, accuracy)
+TEST(solvePnPRansac, accuracy)
 {
     RNG& rng = TS::ptr()->get_rng();
 
@@ -126,12 +126,9 @@ TEST(solvePnpRansac, accuracy)
     projectPoints(object, rvec_gold, tvec_gold, camera_mat, Mat(), image_vec);
     Mat image(1, image_vec.size(), CV_32FC2, &image_vec[0]);
 
-    Mat rvec;
-    Mat tvec;
-    SolvePnpRansacParams params;
+    Mat rvec, tvec;
     vector<int> inliers;
-    params.inliers = &inliers;
-    solvePnpRansac(object, image, camera_mat, Mat(), rvec, tvec, params);
+    gpu::solvePnPRansac(object, image, camera_mat, Mat(), rvec, tvec, false, 200, 2.f, 100, &inliers);
 
     ASSERT_LE(norm(rvec - rvec_gold), 1e-3f);
     ASSERT_LE(norm(tvec - tvec_gold), 1e-3f);
index 39fc34f..85c5f77 100644 (file)
@@ -787,8 +787,7 @@ void InitSolvePnpRansac()
     Mat object; gen(object, 1, 4, CV_32FC3, Scalar::all(0), Scalar::all(100));
     Mat image; gen(image, 1, 4, CV_32FC2, Scalar::all(0), Scalar::all(100));
     Mat rvec, tvec;
-    gpu::solvePnpRansac(object, image, Mat::eye(3, 3, CV_32F), Mat(), rvec, tvec, \r
-                        gpu::SolvePnpRansacParams());\r
+    gpu::solvePnPRansac(object, image, Mat::eye(3, 3, CV_32F), Mat(), rvec, tvec);\r
 }\r
 \r
 \r
@@ -811,21 +810,16 @@ TEST(solvePnpRansac)
         Mat rvec, tvec;
         const int num_iters = 200;
         const float max_dist = 2.0f;
-        vector<int> inliers_cpu;
+        vector<int> inliers_cpu, inliers_gpu;
 
         CPU_ON;
         solvePnPRansac(object, image, camera_mat, Mat(), rvec, tvec, false, num_iters, 
                        max_dist, int(num_points * 0.05), &inliers_cpu);
         CPU_OFF;
 
-        gpu::SolvePnpRansacParams params;
-        params.num_iters = num_iters;
-        params.max_dist = max_dist;
-        vector<int> inliers_gpu;
-        params.inliers = &inliers_gpu;
-
         GPU_ON;
-        gpu::solvePnpRansac(object, image, camera_mat, Mat(), rvec, tvec, params);
+        gpu::solvePnPRansac(object, image, camera_mat, Mat(), rvec, tvec, false, num_iters,
+                            max_dist, int(num_points * 0.05), &inliers_gpu);
         GPU_OFF;\r
     }\r
 }
\ No newline at end of file