Fix hardcoded maxIters

This commit is contained in:
Sergei Shutov 2022-12-15 14:00:48 +02:00 committed by Alexander Smorkalov
parent a2b3acfc6e
commit 3cfe737581
4 changed files with 58 additions and 22 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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())) {

View File

@ -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";
@ -329,9 +331,42 @@ TEST(usac_Essential, accuracy) {
checkInliersMask(TestSolver::Essen, inl_size, thr / ((K1.at<double>(0,0) + K1.at<double>(1,1)) / 2), 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); 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;
const int pts_size = 3000; const int pts_size = 3000;