1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Merge pull request #16136 from mcellis33:mec-nan

* Handle det == 0 in findCircle3pts.

Issue 16051 shows a case where findCircle3pts returns NaN for the
center coordinates and radius due to dividing by a determinant of 0. In
this case, the points are colinear, so the longest distance between any
2 points is the diameter of the minimum enclosing circle.

* imgproc(test): update test checks for minEnclosingCircle()

* imgproc: fix handling of special cases in minEnclosingCircle()
This commit is contained in:
mcellis33
2019-12-18 14:25:59 +00:00
committed by Alexander Alekhin
parent f8b16fa293
commit 5d15c65e48
2 changed files with 125 additions and 3 deletions
+81
View File
@@ -1084,6 +1084,87 @@ int CV_MinCircleTest2::validate_test_results( int test_case_idx )
return code;
}
/****************************************************************************************\
* minEnclosingCircle Test 3 *
\****************************************************************************************/
TEST(Imgproc_minEnclosingCircle, basic_test)
{
vector<Point2f> pts;
pts.push_back(Point2f(0, 0));
pts.push_back(Point2f(10, 0));
pts.push_back(Point2f(5, 1));
const float EPS = 1.0e-3f;
Point2f center;
float radius;
// pts[2] is within the circle with diameter pts[0] - pts[1].
// 2
// 0 1
// NB: The triangle is obtuse, so the only pts[0] and pts[1] are on the circle.
minEnclosingCircle(pts, center, radius);
EXPECT_NEAR(center.x, 5, EPS);
EXPECT_NEAR(center.y, 0, EPS);
EXPECT_NEAR(5, radius, EPS);
// pts[2] is on the circle with diameter pts[0] - pts[1].
// 2
// 0 1
pts[2] = Point2f(5, 5);
minEnclosingCircle(pts, center, radius);
EXPECT_NEAR(center.x, 5, EPS);
EXPECT_NEAR(center.y, 0, EPS);
EXPECT_NEAR(5, radius, EPS);
// pts[2] is outside the circle with diameter pts[0] - pts[1].
// 2
//
//
// 0 1
// NB: The triangle is acute, so all 3 points are on the circle.
pts[2] = Point2f(5, 10);
minEnclosingCircle(pts, center, radius);
EXPECT_NEAR(center.x, 5, EPS);
EXPECT_NEAR(center.y, 3.75, EPS);
EXPECT_NEAR(6.25f, radius, EPS);
// The 3 points are colinear.
pts[2] = Point2f(3, 0);
minEnclosingCircle(pts, center, radius);
EXPECT_NEAR(center.x, 5, EPS);
EXPECT_NEAR(center.y, 0, EPS);
EXPECT_NEAR(5, radius, EPS);
// 2 points are the same.
pts[2] = pts[1];
minEnclosingCircle(pts, center, radius);
EXPECT_NEAR(center.x, 5, EPS);
EXPECT_NEAR(center.y, 0, EPS);
EXPECT_NEAR(5, radius, EPS);
// 3 points are the same.
pts[0] = pts[1];
minEnclosingCircle(pts, center, radius);
EXPECT_NEAR(center.x, 10, EPS);
EXPECT_NEAR(center.y, 0, EPS);
EXPECT_NEAR(0, radius, EPS);
}
TEST(Imgproc_minEnclosingCircle, regression_16051) {
vector<Point2f> pts;
pts.push_back(Point2f(85, 1415));
pts.push_back(Point2f(87, 1415));
pts.push_back(Point2f(89, 1414));
pts.push_back(Point2f(89, 1414));
pts.push_back(Point2f(87, 1412));
Point2f center;
float radius;
minEnclosingCircle(pts, center, radius);
EXPECT_NEAR(center.x, 86.9f, 1e-3);
EXPECT_NEAR(center.y, 1414.1f, 1e-3);
EXPECT_NEAR(2.1024551f, radius, 1e-3);
}
/****************************************************************************************\
* Perimeter Test *
\****************************************************************************************/