Merge pull request #8089 from hrnr:estimate_convert_fix

fix wrong conversion in estimateAffine2D* functions
This commit is contained in:
Alexander Alekhin 2017-01-30 16:53:50 +03:00 committed by GitHub
commit 124c4825a7
3 changed files with 65 additions and 10 deletions

View File

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

View File

@ -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<Point> fpts(3);
std::vector<Point> 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<uchar> 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());

View File

@ -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<Point> fpts(3);
std::vector<Point> 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<uchar> 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());