diff --git a/modules/calib3d/src/ptsetreg.cpp b/modules/calib3d/src/ptsetreg.cpp index 4d2e9135d2..ae9ac459bc 100644 --- a/modules/calib3d/src/ptsetreg.cpp +++ b/modules/calib3d/src/ptsetreg.cpp @@ -833,6 +833,13 @@ Mat estimateAffine2D(InputArray _from, InputArray _to, OutputArray _inliers, to.convertTo(tmp2, CV_32FC2); to = tmp2; } + else + { + // avoid changing of inputs in compressElems() call + from = from.clone(); + to = to.clone(); + } + // convert to N x 1 vectors from = from.reshape(2, count); to = to.reshape(2, count); @@ -900,6 +907,13 @@ Mat estimateAffinePartial2D(InputArray _from, InputArray _to, OutputArray _inlie to.convertTo(tmp2, CV_32FC2); to = tmp2; } + else + { + // avoid changing of inputs in compressElems() call + from = from.clone(); + to = to.clone(); + } + // convert to N x 1 vectors from = from.reshape(2, count); to = to.reshape(2, count); diff --git a/modules/calib3d/test/test_affine2d_estimator.cpp b/modules/calib3d/test/test_affine2d_estimator.cpp index b636f2685b..95f1235105 100644 --- a/modules/calib3d/test/test_affine2d_estimator.cpp +++ b/modules/calib3d/test/test_affine2d_estimator.cpp @@ -152,4 +152,46 @@ TEST_P(EstimateAffine2D, testConversion) INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffine2D, Method::all()); + +// https://github.com/opencv/opencv/issues/14259 +TEST(EstimateAffine2D, issue_14259_dont_change_inputs) +{ + /*const static*/ float pts0_[10] = { + 0.0f, 0.0f, + 0.0f, 8.0f, + 4.0f, 0.0f, // outlier + 8.0f, 8.0f, + 8.0f, 0.0f + }; + /*const static*/ float pts1_[10] = { + 0.1f, 0.1f, + 0.1f, 8.1f, + 0.0f, 4.0f, // outlier + 8.1f, 8.1f, + 8.1f, 0.1f + }; + + Mat pts0(Size(1, 5), CV_32FC2, (void*)pts0_); + Mat pts1(Size(1, 5), CV_32FC2, (void*)pts1_); + + Mat pts0_copy = pts0.clone(); + Mat pts1_copy = pts1.clone(); + + Mat inliers; + + cv::Mat A = cv::estimateAffine2D(pts0, pts1, inliers); + + for(int i = 0; i < pts0.rows; ++i) + { + EXPECT_EQ(pts0_copy.at(i), pts0.at(i)) << "pts0: i=" << i; + } + + for(int i = 0; i < pts1.rows; ++i) + { + EXPECT_EQ(pts1_copy.at(i), pts1.at(i)) << "pts1: i=" << i; + } + + EXPECT_EQ(0, (int)inliers.at(2)); +} + }} // namespace diff --git a/modules/calib3d/test/test_affine_partial2d_estimator.cpp b/modules/calib3d/test/test_affine_partial2d_estimator.cpp index 1bb85a4136..0be25ee7eb 100644 --- a/modules/calib3d/test/test_affine_partial2d_estimator.cpp +++ b/modules/calib3d/test/test_affine_partial2d_estimator.cpp @@ -161,4 +161,46 @@ TEST_P(EstimateAffinePartial2D, testConversion) INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffinePartial2D, Method::all()); + +// https://github.com/opencv/opencv/issues/14259 +TEST(EstimateAffinePartial2D, issue_14259_dont_change_inputs) +{ + /*const static*/ float pts0_[10] = { + 0.0f, 0.0f, + 0.0f, 8.0f, + 4.0f, 0.0f, // outlier + 8.0f, 8.0f, + 8.0f, 0.0f + }; + /*const static*/ float pts1_[10] = { + 0.1f, 0.1f, + 0.1f, 8.1f, + 0.0f, 4.0f, // outlier + 8.1f, 8.1f, + 8.1f, 0.1f + }; + + Mat pts0(Size(1, 5), CV_32FC2, (void*)pts0_); + Mat pts1(Size(1, 5), CV_32FC2, (void*)pts1_); + + Mat pts0_copy = pts0.clone(); + Mat pts1_copy = pts1.clone(); + + Mat inliers; + + cv::Mat A = cv::estimateAffinePartial2D(pts0, pts1, inliers); + + for(int i = 0; i < pts0.rows; ++i) + { + EXPECT_EQ(pts0_copy.at(i), pts0.at(i)) << "pts0: i=" << i; + } + + for(int i = 0; i < pts1.rows; ++i) + { + EXPECT_EQ(pts1_copy.at(i), pts1.at(i)) << "pts1: i=" << i; + } + + EXPECT_EQ(0, (int)inliers.at(2)); +} + }} // namespace