From 23416e3db5e8d1cc48a32094176a4d0c5834095e Mon Sep 17 00:00:00 2001 From: Alexey Spizhevoy Date: Mon, 7 Mar 2011 14:01:18 +0000 Subject: [PATCH] make GPU version of solvePnPRansac more consistent with CPU one --- modules/gpu/include/opencv2/gpu/gpu.hpp | 20 ++++------------ modules/gpu/src/calib3d.cpp | 41 ++++++++++++++++++--------------- modules/gpu/test/test_calib3d.cpp | 9 +++----- samples/gpu/performance/tests.cpp | 14 ++++------- 4 files changed, 33 insertions(+), 51 deletions(-) diff --git a/modules/gpu/include/opencv2/gpu/gpu.hpp b/modules/gpu/include/opencv2/gpu/gpu.hpp index 05c5a7e..33fa3b4 100644 --- a/modules/gpu/include/opencv2/gpu/gpu.hpp +++ b/modules/gpu/include/opencv2/gpu/gpu.hpp @@ -868,22 +868,10 @@ namespace cv const Mat& camera_mat, const Mat& dist_coef, GpuMat& dst, const Stream& stream); - struct CV_EXPORTS SolvePnpRansacParams - { - SolvePnpRansacParams(): subset_size(4), - use_extrinsic_guess(false), - num_iters(100), - max_dist(2.f), - inliers(NULL) {} - int subset_size; - bool use_extrinsic_guess; - int num_iters; - float max_dist; - vector* inliers; - }; - - CV_EXPORTS void solvePnpRansac(const Mat& object, const Mat& image, const Mat& camera_mat, - const Mat& dist_coef, Mat& rvec, Mat& tvec, SolvePnpRansacParams params); + CV_EXPORTS void solvePnPRansac(const Mat& object, const Mat& image, const Mat& camera_mat, + const Mat& dist_coef, Mat& rvec, Mat& tvec, bool use_extrinsic_guess=false, + int num_iters=100, float max_dist=8.0, int min_inlier_count=100, + vector* inliers=NULL); //////////////////////////////// Filter Engine //////////////////////////////// diff --git a/modules/gpu/src/calib3d.cpp b/modules/gpu/src/calib3d.cpp index c0374f2..32bbab6 100644 --- a/modules/gpu/src/calib3d.cpp +++ b/modules/gpu/src/calib3d.cpp @@ -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&, + Mat&, Mat&, bool, int, float, int, vector*) { 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, + const Mat& dist_coef, Mat& rvec, Mat& tvec, bool use_extrinsic_guess, + int num_iters, float max_dist, int min_inlier_count, + vector* 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(), transl_vectors.ptr(), - d_object.ptr(), d_image_normalized.ptr(), params.max_dist * params.max_dist, + num_iters, num_points, rot_matrices.ptr(), transl_vectors.ptr(), + d_object.ptr(), d_image_normalized.ptr(), max_dist * max_dist, d_hypothesis_scores.ptr()); // 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(0, i)) < params.max_dist) - params.inliers->push_back(i); + if (norm(p_proj - image_normalized.at(0, i)) < max_dist) + inliers->push_back(i); } } } diff --git a/modules/gpu/test/test_calib3d.cpp b/modules/gpu/test/test_calib3d.cpp index 4ea6da1..d5f6606 100644 --- a/modules/gpu/test/test_calib3d.cpp +++ b/modules/gpu/test/test_calib3d.cpp @@ -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 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); diff --git a/samples/gpu/performance/tests.cpp b/samples/gpu/performance/tests.cpp index 39fc34f..85c5f77 100644 --- a/samples/gpu/performance/tests.cpp +++ b/samples/gpu/performance/tests.cpp @@ -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, - gpu::SolvePnpRansacParams()); + gpu::solvePnPRansac(object, image, Mat::eye(3, 3, CV_32F), Mat(), rvec, tvec); } @@ -811,21 +810,16 @@ TEST(solvePnpRansac) Mat rvec, tvec; const int num_iters = 200; const float max_dist = 2.0f; - vector inliers_cpu; + vector 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 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; } } \ No newline at end of file -- 2.7.4