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. 41
      modules/calib3d/test/test_usac.cpp

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

@ -801,7 +801,8 @@ bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
Mat findEssentialMat( InputArray points1, InputArray points2, Mat findEssentialMat( InputArray points1, InputArray points2,
InputArray cameraMatrix1, InputArray cameraMatrix1,
int method, double prob, int method, double prob,
double threshold, OutputArray mask); double threshold, OutputArray mask,
int maxIters);
Mat estimateAffine2D(InputArray from, InputArray to, OutputArray inliers, Mat estimateAffine2D(InputArray from, InputArray to, OutputArray inliers,
int method, double ransacReprojThreshold, int maxIters, 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, 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; 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; Ptr<RansacOutput> ransac_output;
if (run(params, points1, points2, params->getRandomGeneratorState(), if (run(params, points1, points2, params->getRandomGeneratorState(),
ransac_output, cameraMatrix1, cameraMatrix1, noArray(), noArray())) { ransac_output, cameraMatrix1, cameraMatrix1, noArray(), noArray())) {

@ -299,8 +299,11 @@ TEST(usac_Fundamental, regression_19639)
EXPECT_TRUE(m.empty()); 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; std::vector<int> gt_inliers;
const int pts_size = 1500; const int pts_size = 1500;
cv::RNG &rng = cv::theRNG(); cv::RNG &rng = cv::theRNG();
@ -312,10 +315,9 @@ TEST(usac_Essential, accuracy) {
int inl_size = generatePoints(rng, pts1, pts2, K1, K2, false /*two calib*/, 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); pts_size, TestSolver ::Fundam, inl_ratio, 0.01 /*noise std, works bad with high noise*/, gt_inliers);
const double conf = 0.99, thr = 1.; const double conf = 0.99, thr = 1.;
for (auto flag : flags) {
cv::Mat mask, E; cv::Mat mask, E;
try { try {
E = cv::findEssentialMat(pts1, pts2, K1, flag, conf, thr, mask); E = cv::findEssentialMat(pts1, pts2, K1, method, conf, thr, mask);
} catch (cv::Exception &e) { } catch (cv::Exception &e) {
if (e.code != cv::Error::StsNotImplemented) if (e.code != cv::Error::StsNotImplemented)
FAIL() << "Essential matrix estimation failed!\n"; FAIL() << "Essential matrix estimation failed!\n";
@ -330,7 +332,40 @@ TEST(usac_Essential, accuracy) {
cpts1_3d.rowRange(0,2), cpts2_3d.rowRange(0,2), E, mask); 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) { TEST(usac_P3P, accuracy) {
std::vector<int> gt_inliers; std::vector<int> gt_inliers;

Loading…
Cancel
Save