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:
committed by
Alexander Alekhin
parent
f8b16fa293
commit
5d15c65e48
@@ -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 *
|
||||
\****************************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user