From feb5b6aa93a12859ba0fa9d99eff5d0b1cccb08f Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 10:42:55 +0300 Subject: [PATCH] increased singularity epsilon in LU decomposition. This solved singular case from http://code.opencv.org/issues/3305. Added the respective test. --- modules/hal/src/matrix.cpp | 8 ++++---- modules/imgproc/test/test_imgwarp.cpp | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/modules/hal/src/matrix.cpp b/modules/hal/src/matrix.cpp index 9506aaf47..921b7783f 100644 --- a/modules/hal/src/matrix.cpp +++ b/modules/hal/src/matrix.cpp @@ -49,7 +49,7 @@ namespace cv { namespace hal { \****************************************************************************************/ template static inline int -LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) +LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n, _Tp eps) { int i, j, k, p = 1; astep /= sizeof(A[0]); @@ -63,7 +63,7 @@ LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) if( std::abs(A[j*astep + i]) > std::abs(A[k*astep + i]) ) k = j; - if( std::abs(A[k*astep + i]) < std::numeric_limits<_Tp>::epsilon() ) + if( std::abs(A[k*astep + i]) < eps ) return 0; if( k != i ) @@ -111,13 +111,13 @@ LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n) { - return LUImpl(A, astep, m, b, bstep, n); + return LUImpl(A, astep, m, b, bstep, n, FLT_EPSILON*10); } int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n) { - return LUImpl(A, astep, m, b, bstep, n); + return LUImpl(A, astep, m, b, bstep, n, DBL_EPSILON*100); } diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index 9fa48de00..d15f72e40 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1654,4 +1654,18 @@ TEST(Imgproc_Warp, multichannel) } } +TEST(Imgproc_GetAffineTransform, singularity) +{ + Point2f A_sample[3]; + A_sample[0] = cv::Point2f(8, 9); + A_sample[1] = cv::Point2f(40, 41); + A_sample[2] = cv::Point2f(47, 48); + Point2f B_sample[3]; + B_sample[0] = cv::Point2f(7.37465, 11.8295); + B_sample[1] = cv::Point2f(15.0113, 12.8994); + B_sample[2] = cv::Point2f(38.9943, 9.56297); + Mat trans = cv::getAffineTransform(A_sample, B_sample); + ASSERT_EQ(0.0, norm(trans, NORM_INF)); +} + /* End of file. */