diff --git a/modules/calib3d/src/usac/estimator.cpp b/modules/calib3d/src/usac/estimator.cpp index 91abe30512..75bc3cf5dd 100644 --- a/modules/calib3d/src/usac/estimator.cpp +++ b/modules/calib3d/src/usac/estimator.cpp @@ -236,13 +236,18 @@ public: CV_DbgAssert(points); } - inline void setModelParameters (const Mat &model) override { + inline void setModelParameters(const Mat& model) override + { + CV_Assert(!model.empty()); + CV_CheckTypeEQ(model.depth(), CV_64F, ""); + const auto * const m = (double *) model.data; m11=static_cast(m[0]); m12=static_cast(m[1]); m13=static_cast(m[2]); m21=static_cast(m[3]); m22=static_cast(m[4]); m23=static_cast(m[5]); m31=static_cast(m[6]); m32=static_cast(m[7]); m33=static_cast(m[8]); const Mat model_inv = model.inv(); + CV_CheckTypeEQ(model_inv.depth(), CV_64F, ""); const auto * const minv = (double *) model_inv.data; minv11=(float)minv[0]; minv12=(float)minv[1]; minv13=(float)minv[2]; minv21=(float)minv[3]; minv22=(float)minv[4]; minv23=(float)minv[5]; @@ -299,7 +304,11 @@ public: CV_DbgAssert(points); } - inline void setModelParameters (const Mat &model) override { + inline void setModelParameters(const Mat& model) override + { + CV_Assert(!model.empty()); + CV_CheckTypeEQ(model.depth(), CV_64F, ""); + const auto * const m = (double *) model.data; m11=static_cast(m[0]); m12=static_cast(m[1]); m13=static_cast(m[2]); m21=static_cast(m[3]); m22=static_cast(m[4]); m23=static_cast(m[5]); @@ -349,7 +358,11 @@ public: CV_DbgAssert(points); } - inline void setModelParameters (const Mat &model) override { + inline void setModelParameters(const Mat& model) override + { + CV_Assert(!model.empty()); + CV_CheckTypeEQ(model.depth(), CV_64F, ""); + const auto * const m = (double *) model.data; m11=static_cast(m[0]); m12=static_cast(m[1]); m13=static_cast(m[2]); m21=static_cast(m[3]); m22=static_cast(m[4]); m23=static_cast(m[5]); @@ -416,7 +429,11 @@ public: CV_DbgAssert(points); } - inline void setModelParameters (const Mat &model) override { + inline void setModelParameters(const Mat& model) override + { + CV_Assert(!model.empty()); + CV_CheckTypeEQ(model.depth(), CV_64F, ""); + const auto * const m = (double *) model.data; m11=static_cast(m[0]); m12=static_cast(m[1]); m13=static_cast(m[2]); m21=static_cast(m[3]); m22=static_cast(m[4]); m23=static_cast(m[5]); @@ -476,7 +493,11 @@ public: } - inline void setModelParameters (const Mat &model) override { + inline void setModelParameters (const Mat& model) override + { + CV_Assert(!model.empty()); + CV_CheckTypeEQ(model.depth(), CV_64F, ""); + const auto * const p = (double *) model.data; p11 = (float)p[0]; p12 = (float)p[1]; p13 = (float)p[2]; p14 = (float)p[3]; p21 = (float)p[4]; p22 = (float)p[5]; p23 = (float)p[6]; p24 = (float)p[7]; @@ -535,7 +556,11 @@ public: CV_DbgAssert(points); } - inline void setModelParameters (const Mat &model) override { + inline void setModelParameters(const Mat& model) override + { + CV_Assert(!model.empty()); + CV_CheckTypeEQ(model.depth(), CV_64F, ""); + const auto * const m = (double *) model.data; m11 = (float)m[0]; m12 = (float)m[1]; m13 = (float)m[2]; m21 = (float)m[3]; m22 = (float)m[4]; m23 = (float)m[5]; diff --git a/modules/calib3d/src/usac/quality.cpp b/modules/calib3d/src/usac/quality.cpp index 856dbb5c95..835306c4f4 100644 --- a/modules/calib3d/src/usac/quality.cpp +++ b/modules/calib3d/src/usac/quality.cpp @@ -421,7 +421,11 @@ public: * @current_hypothesis: current RANSAC iteration * Return: true if model is good, false - otherwise. */ - inline bool isModelGood (const Mat &model) override { + inline bool isModelGood(const Mat& model) override + { + if (model.empty()) + return false; + // update error object with current model err->setModelParameters(model); @@ -584,4 +588,4 @@ Ptr SPRT::create (int state, const Ptr &err_, int points_size_, return makePtr(state, err_, points_size_, inlier_threshold_, prob_pt_of_good_model, prob_pt_of_bad_model, time_sample, avg_num_models, score_type_); } -}} \ No newline at end of file +}} diff --git a/modules/calib3d/test/test_usac.cpp b/modules/calib3d/test/test_usac.cpp index 0b5cfde182..fb5641bd1e 100644 --- a/modules/calib3d/test/test_usac.cpp +++ b/modules/calib3d/test/test_usac.cpp @@ -4,7 +4,8 @@ #include "test_precomp.hpp" -namespace opencv_test { +namespace opencv_test { namespace { + enum TestSolver { Homogr, Fundam, Essen, PnP, Affine}; /* * rng -- reference to random generator @@ -264,7 +265,40 @@ TEST(usac_Fundamental, accuracy) { int(max_iters), mask); checkInliersMask(TestSolver::Fundam, inl_size, thr, pts1, pts2, F, mask); } - }} + } +} + +TEST(usac_Fundamental, regression_19639) +{ + double x_[] = { + 941, 890, + 596, 940, + 898, 941, + 894, 933, + 586, 938, + 902, 933, + 887, 935 + }; + Mat x(7, 1, CV_64FC2, x_); + + double y_[] = { + 1416, 806, + 1157, 852, + 1380, 855, + 1378, 843, + 1145, 849, + 1378, 843, + 1378, 843 + }; + Mat y(7, 1, CV_64FC2, y_); + + //std::cout << x << std::endl; + //std::cout << y << std::endl; + + Mat m = cv::findFundamentalMat(x, y, USAC_MAGSAC, 3, 0.99); + EXPECT_TRUE(m.empty()); +} + TEST(usac_Essential, accuracy) { std::vector gt_inliers; @@ -405,4 +439,5 @@ TEST(usac_testUsacParams, accuracy) { checkInliersMask(TestSolver::Homogr, inl_size, usac_params.threshold, pts1, pts2, model, mask); } -} + +}} // namespace