Merge pull request #20012 from ivashmak:bugfix_solvepnp

* fix inliers in solvePnPRansac

* fix inliers in test_usac

* fix inliers in test_usac
pull/20130/head
Maksym Ivashechkin 4 years ago committed by GitHub
parent 7d66f1e391
commit 527d86a93d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      modules/calib3d/src/solvepnp.cpp
  2. 17
      modules/calib3d/src/usac/ransac_solvers.cpp
  3. 19
      modules/calib3d/test/test_usac.cpp

@ -402,7 +402,14 @@ bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
Ptr<usac::RansacOutput> ransac_output; Ptr<usac::RansacOutput> ransac_output;
if (usac::run(model_params, imagePoints, objectPoints, model_params->getRandomGeneratorState(), if (usac::run(model_params, imagePoints, objectPoints, model_params->getRandomGeneratorState(),
ransac_output, cameraMatrix, noArray(), distCoeffs, noArray())) { 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(); const Mat &model = ransac_output->getModel();
model.col(0).copyTo(rvec); model.col(0).copyTo(rvec);
model.col(1).copyTo(tvec); model.col(1).copyTo(tvec);

@ -539,23 +539,26 @@ Mat findEssentialMat (InputArray points1, InputArray points2, InputArray cameraM
bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints, bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec,
bool /*useExtrinsicGuess*/, int max_iters, float thr, double conf, bool /*useExtrinsicGuess*/, int max_iters, float thr, double conf,
OutputArray mask, int method) { OutputArray inliers, int method) {
Ptr<Model> params; Ptr<Model> params;
setParameters(method, params, cameraMatrix.empty() ? EstimationMethod ::P6P : EstimationMethod ::P3P, setParameters(method, params, cameraMatrix.empty() ? EstimationMethod ::P6P : EstimationMethod ::P3P,
thr, max_iters, conf, mask.needed()); thr, max_iters, conf, inliers.needed());
Ptr<RansacOutput> ransac_output; Ptr<RansacOutput> ransac_output;
if (run(params, imagePoints, objectPoints, params->getRandomGeneratorState(), if (run(params, imagePoints, objectPoints, params->getRandomGeneratorState(),
ransac_output, cameraMatrix, noArray(), distCoeffs, noArray())) { 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(); const Mat &model = ransac_output->getModel();
model.col(0).copyTo(rvec); model.col(0).copyTo(rvec);
model.col(1).copyTo(tvec); model.col(1).copyTo(tvec);
return true; 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; return false;
} }

@ -345,11 +345,16 @@ TEST(usac_P3P, accuracy) {
log(1 - pow(inl_ratio, 3 /* sample size */)); log(1 - pow(inl_ratio, 3 /* sample size */));
for (auto flag : flags) { for (auto flag : flags) {
std::vector<int> inliers;
cv::Mat rvec, tvec, mask, R, P; cv::Mat rvec, tvec, mask, R, P;
CV_Assert(cv::solvePnPRansac(obj_pts, img_pts, K1, cv::noArray(), rvec, tvec, 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::Rodrigues(rvec, R);
cv::hconcat(K1 * R, K1 * tvec, P); 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<uchar>(inl) = true;
checkInliersMask(TestSolver ::PnP, inl_size, thr, img_pts, obj_pts, P, mask); 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!"); // CV_Error(cv::Error::StsError, "Essential matrix estimation failed!");
} }
std::vector<int> inliers(pts_size);
// P3P // P3P
inl_size = generatePoints(rng, pts1, pts2, K1, K2, false, pts_size, TestSolver::PnP, 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); 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); 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<uchar>(inl) = true;
checkInliersMask(TestSolver::PnP, inl_size, usac_params.threshold, pts1, pts2, model, mask); checkInliersMask(TestSolver::PnP, inl_size, usac_params.threshold, pts1, pts2, model, mask);
// P6P // P6P
inl_size = generatePoints(rng, pts1, pts2, K1, K2, false, pts_size, TestSolver::PnP, 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); getInlierRatio(usac_params.maxIterations, 6, usac_params.confidence), 0.1, gt_inliers);
cv::Mat K_est; 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); cv::Rodrigues(rvec, R); cv::hconcat(K_est * R, K_est * tvec, model);
mask.setTo(Scalar::all(0));
for (auto inl : inliers)
mask.at<uchar>(inl) = true;
checkInliersMask(TestSolver::PnP, inl_size, usac_params.threshold, pts1, pts2, model, mask); checkInliersMask(TestSolver::PnP, inl_size, usac_params.threshold, pts1, pts2, model, mask);
// Affine2D // Affine2D

Loading…
Cancel
Save