diff --git a/modules/imgproc/src/shapedescr.cpp b/modules/imgproc/src/shapedescr.cpp index 007bf9ac62..ccb006b90c 100644 --- a/modules/imgproc/src/shapedescr.cpp +++ b/modules/imgproc/src/shapedescr.cpp @@ -340,9 +340,10 @@ double cv::contourArea( InputArray _contour, bool oriented ) namespace cv { -static inline Point2f getOfs(int i, float eps) +static inline Point2f getOfs(float eps) { - return Point2f(((i & 1)*2 - 1)*eps, ((i & 2) - 1)*eps); + RNG& rng = theRNG(); + return Point2f(rng.uniform(-eps, eps), rng.uniform(-eps, eps)); } static RotatedRect fitEllipseNoDirect( InputArray _points ) @@ -419,7 +420,7 @@ static RotatedRect fitEllipseNoDirect( InputArray _points ) float eps = (float)(s/(n*2)*1e-3); for( i = 0; i < n; i++ ) { - Point2f p = ptsf_copy[i] + getOfs(i, eps); + const Point2f p = ptsf_copy[i] + getOfs(eps); ptsf_copy[i] = p; } @@ -744,7 +745,7 @@ cv::RotatedRect cv::fitEllipseDirect( InputArray _points ) for( i = 0; i < n; i++ ) { Point2f p = is_float ? ptsf[i] : Point2f((float)ptsi[i].x, (float)ptsi[i].y); - Point2f delta = getOfs(i, eps); + const Point2f delta = getOfs(eps); double px = (p.x + delta.x - c.x)*scale, py = (p.y + delta.y - c.y)*scale; A.at(i,0) = px*px; diff --git a/modules/imgproc/test/test_fitellipse.cpp b/modules/imgproc/test/test_fitellipse.cpp index 3e6d0478ca..169751acab 100644 --- a/modules/imgproc/test/test_fitellipse.cpp +++ b/modules/imgproc/test/test_fitellipse.cpp @@ -102,4 +102,15 @@ TEST(Imgproc_FitEllipse_JavaCase, accuracy) { EXPECT_NEAR(e.size.height, sqrt(2.)*2, 0.4); } +TEST(Imgproc_FitEllipse_HorizontalLine, accuracy) { + vector pts({{-300, 100}, {-200, 100}, {-100, 100}, {0, 100}, {100, 100}, {200, 100}, {300, 100}}); + const RotatedRect el = fitEllipse(pts); + + EXPECT_NEAR(el.center.x, -100, 100); + EXPECT_NEAR(el.center.y, 100, 1); + EXPECT_NEAR(el.size.width, 1, 1); + EXPECT_GE(el.size.height, 150); + EXPECT_NEAR(el.angle, 90, 0.1); +} + }} // namespace diff --git a/modules/imgproc/test/test_fitellipse_ams.cpp b/modules/imgproc/test/test_fitellipse_ams.cpp index 92e7f2e7a2..5c672bec89 100644 --- a/modules/imgproc/test/test_fitellipse_ams.cpp +++ b/modules/imgproc/test/test_fitellipse_ams.cpp @@ -337,4 +337,15 @@ TEST(Imgproc_FitEllipseAMS_Issue_7, accuracy) { EXPECT_TRUE(checkEllipse(ellipseAMSTest, ellipseAMSTrue, tol)); } +TEST(Imgproc_FitEllipseAMS_HorizontalLine, accuracy) { + vector pts({{-300, 100}, {-200, 100}, {-100, 100}, {0, 100}, {100, 100}, {200, 100}, {300, 100}}); + const RotatedRect el = fitEllipseAMS(pts); + + EXPECT_NEAR(el.center.x, -100, 100); + EXPECT_NEAR(el.center.y, 100, 1); + EXPECT_NEAR(el.size.width, 1, 1); + EXPECT_GE(el.size.height, 150); + EXPECT_NEAR(el.angle, 90, 0.1); +} + }} // namespace diff --git a/modules/imgproc/test/test_fitellipse_direct.cpp b/modules/imgproc/test/test_fitellipse_direct.cpp index 4ae8c4dc76..e41c52764d 100644 --- a/modules/imgproc/test/test_fitellipse_direct.cpp +++ b/modules/imgproc/test/test_fitellipse_direct.cpp @@ -337,4 +337,15 @@ TEST(Imgproc_FitEllipseDirect_Issue_7, accuracy) { EXPECT_TRUE(checkEllipse(ellipseDirectTest, ellipseDirectTrue, tol)); } +TEST(Imgproc_FitEllipseDirect_HorizontalLine, accuracy) { + vector pts({{-300, 100}, {-200, 100}, {-100, 100}, {0, 100}, {100, 100}, {200, 100}, {300, 100}}); + const RotatedRect el = fitEllipseDirect(pts); + + EXPECT_NEAR(el.center.x, 0, 100); + EXPECT_NEAR(el.center.y, 100, 1); + EXPECT_NEAR(el.size.width, 2, 2); + EXPECT_NEAR(el.size.height, 600, 100); + EXPECT_NEAR(el.angle, 90, 0.1); +} + }} // namespace