Merge pull request #22967 from stopmosk:usac-maxiters-bugfix

Fix maxIter parameter in usac findEssentialMat
pull/23012/head
Alexander Smorkalov 2 years ago committed by GitHub
commit 63b6b24cd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      modules/calib3d/src/five-point.cpp
  2. 3
      modules/calib3d/src/usac.hpp
  3. 4
      modules/calib3d/src/usac/ransac_solvers.cpp
  4. 69
      modules/calib3d/test/test_usac.cpp

@ -433,9 +433,9 @@ cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, InputArr
{
CV_INSTRUMENT_REGION();
if (method >= 32 && method <= 38)
if (method >= USAC_DEFAULT && method <= USAC_MAGSAC)
return usac::findEssentialMat(_points1, _points2, _cameraMatrix,
method, prob, threshold, _mask);
method, prob, threshold, _mask, maxIters);
Mat points1, points2, cameraMatrix;
_points1.getMat().convertTo(points1, CV_64F);

@ -801,7 +801,8 @@ bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
Mat findEssentialMat( InputArray points1, InputArray points2,
InputArray cameraMatrix1,
int method, double prob,
double threshold, OutputArray mask);
double threshold, OutputArray mask,
int maxIters);
Mat estimateAffine2D(InputArray from, InputArray to, OutputArray inliers,
int method, double ransacReprojThreshold, int maxIters,

@ -520,9 +520,9 @@ Mat findFundamentalMat( InputArray points1, InputArray points2, int method, doub
}
Mat findEssentialMat (InputArray points1, InputArray points2, InputArray cameraMatrix1,
int method, double prob, double thr, OutputArray mask) {
int method, double prob, double thr, OutputArray mask, int maxIters) {
Ptr<Model> params;
setParameters(method, params, EstimationMethod::Essential, thr, 1000, prob, mask.needed());
setParameters(method, params, EstimationMethod::Essential, thr, maxIters, prob, mask.needed());
Ptr<RansacOutput> ransac_output;
if (run(params, points1, points2, params->getRandomGeneratorState(),
ransac_output, cameraMatrix1, cameraMatrix1, noArray(), noArray())) {

@ -299,8 +299,11 @@ TEST(usac_Fundamental, regression_19639)
EXPECT_TRUE(m.empty());
}
CV_ENUM(UsacMethod, USAC_DEFAULT, USAC_ACCURATE, USAC_PROSAC, USAC_FAST, USAC_MAGSAC)
typedef TestWithParam<UsacMethod> usac_Essential;
TEST(usac_Essential, accuracy) {
TEST_P(usac_Essential, accuracy) {
int method = GetParam();
std::vector<int> gt_inliers;
const int pts_size = 1500;
cv::RNG &rng = cv::theRNG();
@ -312,26 +315,58 @@ TEST(usac_Essential, accuracy) {
int inl_size = generatePoints(rng, pts1, pts2, K1, K2, false /*two calib*/,
pts_size, TestSolver ::Fundam, inl_ratio, 0.01 /*noise std, works bad with high noise*/, gt_inliers);
const double conf = 0.99, thr = 1.;
for (auto flag : flags) {
cv::Mat mask, E;
try {
E = cv::findEssentialMat(pts1, pts2, K1, flag, conf, thr, mask);
} catch (cv::Exception &e) {
if (e.code != cv::Error::StsNotImplemented)
FAIL() << "Essential matrix estimation failed!\n";
else continue;
}
// calibrate points
cv::Mat cpts1_3d, cpts2_3d;
cv::vconcat(pts1, cv::Mat::ones(1, pts1.cols, pts1.type()), cpts1_3d);
cv::vconcat(pts2, cv::Mat::ones(1, pts2.cols, pts2.type()), cpts2_3d);
cpts1_3d = K1.inv() * cpts1_3d; cpts2_3d = K1.inv() * cpts2_3d;
checkInliersMask(TestSolver::Essen, inl_size, thr / ((K1.at<double>(0,0) + K1.at<double>(1,1)) / 2),
cpts1_3d.rowRange(0,2), cpts2_3d.rowRange(0,2), E, mask);
cv::Mat mask, E;
try {
E = cv::findEssentialMat(pts1, pts2, K1, method, conf, thr, mask);
} catch (cv::Exception &e) {
if (e.code != cv::Error::StsNotImplemented)
FAIL() << "Essential matrix estimation failed!\n";
else continue;
}
// calibrate points
cv::Mat cpts1_3d, cpts2_3d;
cv::vconcat(pts1, cv::Mat::ones(1, pts1.cols, pts1.type()), cpts1_3d);
cv::vconcat(pts2, cv::Mat::ones(1, pts2.cols, pts2.type()), cpts2_3d);
cpts1_3d = K1.inv() * cpts1_3d; cpts2_3d = K1.inv() * cpts2_3d;
checkInliersMask(TestSolver::Essen, inl_size, thr / ((K1.at<double>(0,0) + K1.at<double>(1,1)) / 2),
cpts1_3d.rowRange(0,2), cpts2_3d.rowRange(0,2), E, mask);
}
}
TEST_P(usac_Essential, maxiters) {
int method = GetParam();
cv::RNG &rng = cv::theRNG();
cv::Mat mask;
cv::Mat K1 = cv::Mat(cv::Matx33d(1, 0, 0,
0, 1, 0,
0, 0, 1.));
const double conf = 0.99, thr = 0.5;
int roll_results_sum = 0;
for (int iters = 0; iters < 10; iters++) {
cv::Mat E1, E2;
try {
cv::Mat pts1 = cv::Mat(2, 50, CV_64F);
cv::Mat pts2 = cv::Mat(2, 50, CV_64F);
rng.fill(pts1, cv::RNG::UNIFORM, 0.0, 1.0);
rng.fill(pts2, cv::RNG::UNIFORM, 0.0, 1.0);
E1 = cv::findEssentialMat(pts1, pts2, K1, method, conf, thr, 1, mask);
E2 = cv::findEssentialMat(pts1, pts2, K1, method, conf, thr, 1000, mask);
if (E1.dims != E2.dims) { continue; }
roll_results_sum += cv::norm(E1, E2, NORM_L1) != 0;
} catch (cv::Exception &e) {
if (e.code != cv::Error::StsNotImplemented)
FAIL() << "Essential matrix estimation failed!\n";
else continue;
}
EXPECT_NE(roll_results_sum, 0);
}
}
INSTANTIATE_TEST_CASE_P(Calib3d, usac_Essential, UsacMethod::all());
TEST(usac_P3P, accuracy) {
std::vector<int> gt_inliers;
const int pts_size = 3000;

Loading…
Cancel
Save