mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08:00
Merge pull request #20012 from ivashmak:bugfix_solvepnp
* fix inliers in solvePnPRansac * fix inliers in test_usac * fix inliers in test_usac
This commit is contained in:
parent
7d66f1e391
commit
527d86a93d
@ -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…
Reference in New Issue
Block a user