From 527d86a93d4183869ec34e1e9f195e3d91c3eb7e Mon Sep 17 00:00:00 2001 From: Maksym Ivashechkin Date: Wed, 19 May 2021 10:09:46 +0100 Subject: [PATCH] Merge pull request #20012 from ivashmak:bugfix_solvepnp * fix inliers in solvePnPRansac * fix inliers in test_usac * fix inliers in test_usac --- modules/calib3d/src/solvepnp.cpp | 9 ++++++++- modules/calib3d/src/usac/ransac_solvers.cpp | 17 ++++++++++------- modules/calib3d/test/test_usac.cpp | 19 ++++++++++++++++--- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/modules/calib3d/src/solvepnp.cpp b/modules/calib3d/src/solvepnp.cpp index b3ce1aa514..1e5591f710 100644 --- a/modules/calib3d/src/solvepnp.cpp +++ b/modules/calib3d/src/solvepnp.cpp @@ -402,7 +402,14 @@ bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints, Ptr ransac_output; if (usac::run(model_params, imagePoints, objectPoints, model_params->getRandomGeneratorState(), ransac_output, cameraMatrix, noArray(), distCoeffs, noArray())) { - usac::saveMask(inliers, ransac_output->getInliersMask()); + if (inliers.needed()) { + const auto &inliers_mask = ransac_output->getInliersMask(); + Mat inliers_; + for (int i = 0; i < (int)inliers_mask.size(); i++) + if (inliers_mask[i]) + inliers_.push_back(i); + inliers_.copyTo(inliers); + } const Mat &model = ransac_output->getModel(); model.col(0).copyTo(rvec); model.col(1).copyTo(tvec); diff --git a/modules/calib3d/src/usac/ransac_solvers.cpp b/modules/calib3d/src/usac/ransac_solvers.cpp index eb7e177678..b7f3e6e0c1 100644 --- a/modules/calib3d/src/usac/ransac_solvers.cpp +++ b/modules/calib3d/src/usac/ransac_solvers.cpp @@ -539,23 +539,26 @@ Mat findEssentialMat (InputArray points1, InputArray points2, InputArray cameraM bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool /*useExtrinsicGuess*/, int max_iters, float thr, double conf, - OutputArray mask, int method) { + OutputArray inliers, int method) { Ptr params; setParameters(method, params, cameraMatrix.empty() ? EstimationMethod ::P6P : EstimationMethod ::P3P, - thr, max_iters, conf, mask.needed()); + thr, max_iters, conf, inliers.needed()); Ptr ransac_output; if (run(params, imagePoints, objectPoints, params->getRandomGeneratorState(), ransac_output, cameraMatrix, noArray(), distCoeffs, noArray())) { - saveMask(mask, ransac_output->getInliersMask()); + if (inliers.needed()) { + const auto &inliers_mask = ransac_output->getInliersMask(); + Mat inliers_; + for (int i = 0; i < (int)inliers_mask.size(); i++) + if (inliers_mask[i]) + inliers_.push_back(i); + inliers_.copyTo(inliers); + } const Mat &model = ransac_output->getModel(); model.col(0).copyTo(rvec); model.col(1).copyTo(tvec); return true; } - if (mask.needed()){ - mask.create(std::max(objectPoints.getMat().rows, objectPoints.getMat().cols), 1, CV_8U); - mask.setTo(Scalar::all(0)); - } return false; } diff --git a/modules/calib3d/test/test_usac.cpp b/modules/calib3d/test/test_usac.cpp index fb5641bd1e..6e6d8cecf3 100644 --- a/modules/calib3d/test/test_usac.cpp +++ b/modules/calib3d/test/test_usac.cpp @@ -345,11 +345,16 @@ TEST(usac_P3P, accuracy) { log(1 - pow(inl_ratio, 3 /* sample size */)); for (auto flag : flags) { + std::vector inliers; cv::Mat rvec, tvec, mask, R, P; CV_Assert(cv::solvePnPRansac(obj_pts, img_pts, K1, cv::noArray(), rvec, tvec, - false, (int)max_iters, (float)thr, conf, mask, flag)); + false, (int)max_iters, (float)thr, conf, inliers, flag)); cv::Rodrigues(rvec, R); cv::hconcat(K1 * R, K1 * tvec, P); + mask.create(pts_size, 1, CV_8U); + mask.setTo(Scalar::all(0)); + for (auto inl : inliers) + mask.at(inl) = true; checkInliersMask(TestSolver ::PnP, inl_size, thr, img_pts, obj_pts, P, mask); } } @@ -416,19 +421,27 @@ TEST(usac_testUsacParams, accuracy) { // CV_Error(cv::Error::StsError, "Essential matrix estimation failed!"); } + std::vector inliers(pts_size); // P3P inl_size = generatePoints(rng, pts1, pts2, K1, K2, false, pts_size, TestSolver::PnP, getInlierRatio(usac_params.maxIterations, 3, usac_params.confidence), 0.01, gt_inliers); - CV_Assert(cv::solvePnPRansac(pts2, pts1, K1, dist_coeff, rvec, tvec, mask, usac_params)); + CV_Assert(cv::solvePnPRansac(pts2, pts1, K1, dist_coeff, rvec, tvec, inliers, usac_params)); cv::Rodrigues(rvec, R); cv::hconcat(K1 * R, K1 * tvec, model); + mask.create(pts_size, 1, CV_8U); + mask.setTo(Scalar::all(0)); + for (auto inl : inliers) + mask.at(inl) = true; checkInliersMask(TestSolver::PnP, inl_size, usac_params.threshold, pts1, pts2, model, mask); // P6P inl_size = generatePoints(rng, pts1, pts2, K1, K2, false, pts_size, TestSolver::PnP, getInlierRatio(usac_params.maxIterations, 6, usac_params.confidence), 0.1, gt_inliers); cv::Mat K_est; - CV_Assert(cv::solvePnPRansac(pts2, pts1, K_est, dist_coeff, rvec, tvec, mask, usac_params)); + CV_Assert(cv::solvePnPRansac(pts2, pts1, K_est, dist_coeff, rvec, tvec, inliers, usac_params)); cv::Rodrigues(rvec, R); cv::hconcat(K_est * R, K_est * tvec, model); + mask.setTo(Scalar::all(0)); + for (auto inl : inliers) + mask.at(inl) = true; checkInliersMask(TestSolver::PnP, inl_size, usac_params.threshold, pts1, pts2, model, mask); // Affine2D -- 2.34.1