Skip to content

Commit f70e80a

Browse files
authored
Merge pull request opencv#19640 from alalek:issue_19639
calib3d(usac): do not crash on empty models * calib3d(test): regression test for issue 19639 * calib3d(usac): do not crash in setModelParameters() * calib3d(usac): handle empty models in isModelGood()
1 parent e0265c6 commit f70e80a

File tree

3 files changed

+75
-11
lines changed

3 files changed

+75
-11
lines changed

modules/calib3d/src/usac/estimator.cpp

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,18 @@ class ReprojectionErrorSymmetricImpl : public ReprojectionErrorSymmetric {
236236
CV_DbgAssert(points);
237237
}
238238

239-
inline void setModelParameters (const Mat &model) override {
239+
inline void setModelParameters(const Mat& model) override
240+
{
241+
CV_Assert(!model.empty());
242+
CV_CheckTypeEQ(model.depth(), CV_64F, "");
243+
240244
const auto * const m = (double *) model.data;
241245
m11=static_cast<float>(m[0]); m12=static_cast<float>(m[1]); m13=static_cast<float>(m[2]);
242246
m21=static_cast<float>(m[3]); m22=static_cast<float>(m[4]); m23=static_cast<float>(m[5]);
243247
m31=static_cast<float>(m[6]); m32=static_cast<float>(m[7]); m33=static_cast<float>(m[8]);
244248

245249
const Mat model_inv = model.inv();
250+
CV_CheckTypeEQ(model_inv.depth(), CV_64F, "");
246251
const auto * const minv = (double *) model_inv.data;
247252
minv11=(float)minv[0]; minv12=(float)minv[1]; minv13=(float)minv[2];
248253
minv21=(float)minv[3]; minv22=(float)minv[4]; minv23=(float)minv[5];
@@ -299,7 +304,11 @@ class ReprojectionErrorForwardImpl : public ReprojectionErrorForward {
299304
CV_DbgAssert(points);
300305
}
301306

302-
inline void setModelParameters (const Mat &model) override {
307+
inline void setModelParameters(const Mat& model) override
308+
{
309+
CV_Assert(!model.empty());
310+
CV_CheckTypeEQ(model.depth(), CV_64F, "");
311+
303312
const auto * const m = (double *) model.data;
304313
m11=static_cast<float>(m[0]); m12=static_cast<float>(m[1]); m13=static_cast<float>(m[2]);
305314
m21=static_cast<float>(m[3]); m22=static_cast<float>(m[4]); m23=static_cast<float>(m[5]);
@@ -349,7 +358,11 @@ class SampsonErrorImpl : public SampsonError {
349358
CV_DbgAssert(points);
350359
}
351360

352-
inline void setModelParameters (const Mat &model) override {
361+
inline void setModelParameters(const Mat& model) override
362+
{
363+
CV_Assert(!model.empty());
364+
CV_CheckTypeEQ(model.depth(), CV_64F, "");
365+
353366
const auto * const m = (double *) model.data;
354367
m11=static_cast<float>(m[0]); m12=static_cast<float>(m[1]); m13=static_cast<float>(m[2]);
355368
m21=static_cast<float>(m[3]); m22=static_cast<float>(m[4]); m23=static_cast<float>(m[5]);
@@ -416,7 +429,11 @@ class SymmetricGeometricDistanceImpl : public SymmetricGeometricDistance {
416429
CV_DbgAssert(points);
417430
}
418431

419-
inline void setModelParameters (const Mat &model) override {
432+
inline void setModelParameters(const Mat& model) override
433+
{
434+
CV_Assert(!model.empty());
435+
CV_CheckTypeEQ(model.depth(), CV_64F, "");
436+
420437
const auto * const m = (double *) model.data;
421438
m11=static_cast<float>(m[0]); m12=static_cast<float>(m[1]); m13=static_cast<float>(m[2]);
422439
m21=static_cast<float>(m[3]); m22=static_cast<float>(m[4]); m23=static_cast<float>(m[5]);
@@ -476,7 +493,11 @@ class ReprojectionErrorPmatrixImpl : public ReprojectionErrorPmatrix {
476493
}
477494

478495

479-
inline void setModelParameters (const Mat &model) override {
496+
inline void setModelParameters (const Mat& model) override
497+
{
498+
CV_Assert(!model.empty());
499+
CV_CheckTypeEQ(model.depth(), CV_64F, "");
500+
480501
const auto * const p = (double *) model.data;
481502
p11 = (float)p[0]; p12 = (float)p[1]; p13 = (float)p[2]; p14 = (float)p[3];
482503
p21 = (float)p[4]; p22 = (float)p[5]; p23 = (float)p[6]; p24 = (float)p[7];
@@ -535,7 +556,11 @@ class ReprojectionDistanceAffineImpl : public ReprojectionErrorAffine {
535556
CV_DbgAssert(points);
536557
}
537558

538-
inline void setModelParameters (const Mat &model) override {
559+
inline void setModelParameters(const Mat& model) override
560+
{
561+
CV_Assert(!model.empty());
562+
CV_CheckTypeEQ(model.depth(), CV_64F, "");
563+
539564
const auto * const m = (double *) model.data;
540565
m11 = (float)m[0]; m12 = (float)m[1]; m13 = (float)m[2];
541566
m21 = (float)m[3]; m22 = (float)m[4]; m23 = (float)m[5];

modules/calib3d/src/usac/quality.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,11 @@ class SPRTImpl : public SPRT {
421421
* @current_hypothesis: current RANSAC iteration
422422
* Return: true if model is good, false - otherwise.
423423
*/
424-
inline bool isModelGood (const Mat &model) override {
424+
inline bool isModelGood(const Mat& model) override
425+
{
426+
if (model.empty())
427+
return false;
428+
425429
// update error object with current model
426430
err->setModelParameters(model);
427431

@@ -584,4 +588,4 @@ Ptr<SPRT> SPRT::create (int state, const Ptr<Error> &err_, int points_size_,
584588
return makePtr<SPRTImpl>(state, err_, points_size_, inlier_threshold_,
585589
prob_pt_of_good_model, prob_pt_of_bad_model, time_sample, avg_num_models, score_type_);
586590
}
587-
}}
591+
}}

modules/calib3d/test/test_usac.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
#include "test_precomp.hpp"
66

7-
namespace opencv_test {
7+
namespace opencv_test { namespace {
8+
89
enum TestSolver { Homogr, Fundam, Essen, PnP, Affine};
910
/*
1011
* rng -- reference to random generator
@@ -264,7 +265,40 @@ TEST(usac_Fundamental, accuracy) {
264265
int(max_iters), mask);
265266
checkInliersMask(TestSolver::Fundam, inl_size, thr, pts1, pts2, F, mask);
266267
}
267-
}}
268+
}
269+
}
270+
271+
TEST(usac_Fundamental, regression_19639)
272+
{
273+
double x_[] = {
274+
941, 890,
275+
596, 940,
276+
898, 941,
277+
894, 933,
278+
586, 938,
279+
902, 933,
280+
887, 935
281+
};
282+
Mat x(7, 1, CV_64FC2, x_);
283+
284+
double y_[] = {
285+
1416, 806,
286+
1157, 852,
287+
1380, 855,
288+
1378, 843,
289+
1145, 849,
290+
1378, 843,
291+
1378, 843
292+
};
293+
Mat y(7, 1, CV_64FC2, y_);
294+
295+
//std::cout << x << std::endl;
296+
//std::cout << y << std::endl;
297+
298+
Mat m = cv::findFundamentalMat(x, y, USAC_MAGSAC, 3, 0.99);
299+
EXPECT_TRUE(m.empty());
300+
}
301+
268302

269303
TEST(usac_Essential, accuracy) {
270304
std::vector<int> gt_inliers;
@@ -405,4 +439,5 @@ TEST(usac_testUsacParams, accuracy) {
405439
checkInliersMask(TestSolver::Homogr, inl_size, usac_params.threshold, pts1, pts2, model, mask);
406440
}
407441

408-
}
442+
443+
}} // namespace

0 commit comments

Comments
 (0)