From 9408a5ef5dcfa9a216fb1e4eabf357510f72e580 Mon Sep 17 00:00:00 2001 From: Jiri Horner Date: Fri, 27 Jan 2017 16:55:29 +0100 Subject: [PATCH 1/2] fix conversion bug in estimateAffine2D* functions functions support points to have other datatypes than floats. * fix bug in coversion that overwrites src points with dst points --- modules/calib3d/src/ptsetreg.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/calib3d/src/ptsetreg.cpp b/modules/calib3d/src/ptsetreg.cpp index cbf8175d48..ba9b7865ab 100644 --- a/modules/calib3d/src/ptsetreg.cpp +++ b/modules/calib3d/src/ptsetreg.cpp @@ -802,11 +802,11 @@ Mat estimateAffine2D(InputArray _from, InputArray _to, OutputArray _inliers, if (from.type() != CV_32FC2 || to.type() != CV_32FC2) { - Mat tmp; - from.convertTo(tmp, CV_32FC2); - from = tmp; - to.convertTo(tmp, CV_32FC2); - to = tmp; + Mat tmp1, tmp2; + from.convertTo(tmp1, CV_32FC2); + from = tmp1; + to.convertTo(tmp2, CV_32FC2); + to = tmp2; } // convert to N x 1 vectors from = from.reshape(2, count); @@ -869,11 +869,11 @@ Mat estimateAffinePartial2D(InputArray _from, InputArray _to, OutputArray _inlie if (from.type() != CV_32FC2 || to.type() != CV_32FC2) { - Mat tmp; - from.convertTo(tmp, CV_32FC2); - from = tmp; - to.convertTo(tmp, CV_32FC2); - to = tmp; + Mat tmp1, tmp2; + from.convertTo(tmp1, CV_32FC2); + from = tmp1; + to.convertTo(tmp2, CV_32FC2); + to = tmp2; } // convert to N x 1 vectors from = from.reshape(2, count); From 4ee25c7e9587155f8c498f54bbbd0509a404ca1b Mon Sep 17 00:00:00 2001 From: Jiri Horner Date: Fri, 27 Jan 2017 17:52:35 +0100 Subject: [PATCH 2/2] add test for convertions in estimateAffine2D* functions test with integer points to cover conversion bugs. --- .../calib3d/test/test_affine2d_estimator.cpp | 28 +++++++++++++++++++ .../test/test_affine_partial2d_estimator.cpp | 27 ++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/modules/calib3d/test/test_affine2d_estimator.cpp b/modules/calib3d/test/test_affine2d_estimator.cpp index de9f7003e1..2007c497c4 100644 --- a/modules/calib3d/test/test_affine2d_estimator.cpp +++ b/modules/calib3d/test/test_affine2d_estimator.cpp @@ -127,4 +127,32 @@ TEST_P(EstimateAffine2D, testNPoints) } } +// test conversion from other datatypes than float +TEST_P(EstimateAffine2D, testConversion) +{ + Mat aff(2, 3, CV_32S); + cv::randu(aff, 1., 3.); + + std::vector fpts(3); + std::vector tpts(3); + + // setting points that are not in the same line + fpts[0] = Point2f( rngIn(1,2), rngIn(5,6) ); + fpts[1] = Point2f( rngIn(3,4), rngIn(3,4) ); + fpts[2] = Point2f( rngIn(1,2), rngIn(3,4) ); + + transform(fpts, tpts, aff); + + vector inliers; + Mat aff_est = estimateAffine2D(fpts, tpts, inliers, GetParam() /* method */); + + ASSERT_FALSE(aff_est.empty()); + + aff.convertTo(aff, CV_64F); // need to convert before compare + EXPECT_NEAR(0., cvtest::norm(aff_est, aff, NORM_INF), 1e-3); + + // all must be inliers + EXPECT_EQ(countNonZero(inliers), 3); +} + INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffine2D, Method::all()); diff --git a/modules/calib3d/test/test_affine_partial2d_estimator.cpp b/modules/calib3d/test/test_affine_partial2d_estimator.cpp index dde7d7da1c..a61739a52a 100644 --- a/modules/calib3d/test/test_affine_partial2d_estimator.cpp +++ b/modules/calib3d/test/test_affine_partial2d_estimator.cpp @@ -137,4 +137,31 @@ TEST_P(EstimateAffinePartial2D, testNPoints) } } +// test conversion from other datatypes than float +TEST_P(EstimateAffinePartial2D, testConversion) +{ + Mat aff = rngPartialAffMat(); + aff.convertTo(aff, CV_32S); // convert to int to transform ints properly + + std::vector fpts(3); + std::vector tpts(3); + + fpts[0] = Point2f( rngIn(1,2), rngIn(5,6) ); + fpts[1] = Point2f( rngIn(3,4), rngIn(3,4) ); + fpts[2] = Point2f( rngIn(1,2), rngIn(3,4) ); + + transform(fpts, tpts, aff); + + vector inliers; + Mat aff_est = estimateAffinePartial2D(fpts, tpts, inliers, GetParam() /* method */); + + ASSERT_FALSE(aff_est.empty()); + + aff.convertTo(aff, CV_64F); // need to convert back before compare + EXPECT_NEAR(0., cvtest::norm(aff_est, aff, NORM_INF), 1e-3); + + // all must be inliers + EXPECT_EQ(countNonZero(inliers), 3); +} + INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffinePartial2D, Method::all());