From c69245da1f4f37097fe22501023552ac3eb686f5 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 3 Oct 2019 20:45:43 +0000 Subject: [PATCH] imgproc: fix fitLine() implementation - update optimal solutions on each iteration --- .../imgproc/misc/java/test/ImgprocTest.java | 2 +- modules/imgproc/src/linefit.cpp | 19 +++++++--- modules/imgproc/test/test_convhull.cpp | 35 +++++++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/modules/imgproc/misc/java/test/ImgprocTest.java b/modules/imgproc/misc/java/test/ImgprocTest.java index ca23ee35b3..52da455993 100644 --- a/modules/imgproc/misc/java/test/ImgprocTest.java +++ b/modules/imgproc/misc/java/test/ImgprocTest.java @@ -807,7 +807,7 @@ public class ImgprocTest extends OpenCVTestCase { points.put(0, 0, 0, 0, 2, 3, 3, 4, 5, 8); Mat linePoints = new Mat(4, 1, CvType.CV_32FC1); - linePoints.put(0, 0, 0.53196341, 0.84676737, 2.496531, 3.7467217); + linePoints.put(0, 0, 0.53198653, 0.84675282, 2.5, 3.75); Imgproc.fitLine(points, dst, Imgproc.CV_DIST_L12, 0, 0.01, 0.01); diff --git a/modules/imgproc/src/linefit.cpp b/modules/imgproc/src/linefit.cpp index 1abde1e0d1..97e0d2961a 100644 --- a/modules/imgproc/src/linefit.cpp +++ b/modules/imgproc/src/linefit.cpp @@ -408,8 +408,14 @@ static void fitLine2D( const Point2f * points, int count, int dist, } /* calculate distances */ err = calcDist2D( points, count, _line, r ); - if( err < EPS ) - break; + + if (err < min_err) + { + min_err = err; + memcpy(line, _line, 4 * sizeof(line[0])); + if (err < EPS) + break; + } /* calculate weights */ if( calc_weights ) @@ -550,8 +556,13 @@ static void fitLine3D( Point3f * points, int count, int dist, } /* calculate distances */ err = calcDist3D( points, count, _line, r ); - //if( err < FLT_EPSILON*count ) - // break; + if (err < min_err) + { + min_err = err; + memcpy(line, _line, 6 * sizeof(line[0])); + if (err < EPS) + break; + } /* calculate weights */ if( calc_weights ) diff --git a/modules/imgproc/test/test_convhull.cpp b/modules/imgproc/test/test_convhull.cpp index 3f82e04524..3f12140328 100644 --- a/modules/imgproc/test/test_convhull.cpp +++ b/modules/imgproc/test/test_convhull.cpp @@ -1609,6 +1609,8 @@ int CV_FitLineTest::validate_test_results( int test_case_idx ) int k, max_k = 0; double vec_diff = 0, t; + //std::cout << dims << " " << Mat(1, dims*2, CV_32FC1, line.data()) << " " << Mat(1, dims, CV_32FC1, line0.data()) << std::endl; + for( k = 0; k < dims*2; k++ ) { if( cvIsNaN(line[k]) || cvIsInf(line[k]) ) @@ -2038,5 +2040,38 @@ INSTANTIATE_TEST_CASE_P(Imgproc, ConvexityDefects_regression_5908, testing::Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) )); +TEST(Imgproc_FitLine, regression_15083) +{ + int points2i_[] = { + 432, 654, + 370, 656, + 390, 656, + 410, 656, + 348, 658 + }; + Mat points(5, 1, CV_32SC2, points2i_); + + Vec4f lineParam; + fitLine(points, lineParam, DIST_L1, 0, 0.01, 0.01); + EXPECT_GE(fabs(lineParam[0]), fabs(lineParam[1]) * 4) << lineParam; +} + +TEST(Imgproc_FitLine, regression_4903) +{ + float points2f_[] = { + 1224.0, 576.0, + 1234.0, 683.0, + 1215.0, 471.0, + 1184.0, 137.0, + 1079.0, 377.0, + 1239.0, 788.0, + }; + Mat points(6, 1, CV_32FC2, points2f_); + + Vec4f lineParam; + fitLine(points, lineParam, DIST_WELSCH, 0, 0.01, 0.01); + EXPECT_GE(fabs(lineParam[1]), fabs(lineParam[0]) * 4) << lineParam; +} + }} // namespace /* End of file. */