Added the tests for the minEnclosingTriangle function in the existing test_convhull.cpp file.
This commit is contained in:
parent
caaa9e0f2d
commit
0117d77cd1
@ -161,6 +161,22 @@ cvTsPointPolygonTest( CvPoint2D32f pt, const CvPoint2D32f* vv, int n, int* _idx=
|
||||
return result;
|
||||
}
|
||||
|
||||
static cv::Point2f
|
||||
cvTsMiddlePoint(const cv::Point2f &a, const cv::Point2f &b)
|
||||
{
|
||||
return cv::Point2f((a.x + b.x) / 2, (a.y + b.y) / 2);
|
||||
}
|
||||
|
||||
static bool
|
||||
cvTsIsPointOnLineSegment(const cv::Point2f &x, const cv::Point2f &a, const cv::Point2f &b)
|
||||
{
|
||||
double d1 = cvTsDist(CvPoint2D32f(x.x, x.y), CvPoint2D32f(a.x, a.y));
|
||||
double d2 = cvTsDist(CvPoint2D32f(x.x, x.y), CvPoint2D32f(b.x, b.y));
|
||||
double d3 = cvTsDist(CvPoint2D32f(a.x, a.y), CvPoint2D32f(b.x, b.y));
|
||||
|
||||
return (abs(d1 + d2 - d3) <= (1E-5));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
* Base class for shape descriptor tests *
|
||||
@ -769,6 +785,146 @@ _exit_:
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
* MinEnclosingTriangle Test *
|
||||
\****************************************************************************************/
|
||||
|
||||
class CV_MinTriangleTest : public CV_BaseShapeDescrTest
|
||||
{
|
||||
public:
|
||||
CV_MinTriangleTest();
|
||||
|
||||
protected:
|
||||
void run_func(void);
|
||||
int validate_test_results( int test_case_idx );
|
||||
std::vector<cv::Point2f> getTriangleMiddlePoints();
|
||||
|
||||
std::vector<cv::Point2f> convexPolygon;
|
||||
std::vector<cv::Point2f> triangle;
|
||||
double area;
|
||||
};
|
||||
|
||||
|
||||
CV_MinTriangleTest::CV_MinTriangleTest()
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<cv::Point2f> CV_MinTriangleTest::getTriangleMiddlePoints()
|
||||
{
|
||||
std::vector<cv::Point2f> triangleMiddlePoints;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
triangleMiddlePoints.push_back(cvTsMiddlePoint(triangle[i], triangle[(i + 1) % 3]));
|
||||
}
|
||||
|
||||
return triangleMiddlePoints;
|
||||
}
|
||||
|
||||
|
||||
void CV_MinTriangleTest::run_func()
|
||||
{
|
||||
std::vector<cv::Point2f> pointsAsVector;
|
||||
|
||||
cv::cvarrToMat(points).convertTo(pointsAsVector, CV_32F);
|
||||
|
||||
cv::minEnclosingTriangle(pointsAsVector, triangle, area);
|
||||
cv::convexHull(pointsAsVector, convexPolygon, true, true);
|
||||
}
|
||||
|
||||
|
||||
int CV_MinTriangleTest::validate_test_results( int test_case_idx )
|
||||
{
|
||||
bool errorEnclosed = false, errorMiddlePoints = false, errorFlush = true;
|
||||
double eps = 1e-4;
|
||||
int code = CV_BaseShapeDescrTest::validate_test_results( test_case_idx );
|
||||
|
||||
#if 0
|
||||
{
|
||||
int n = 3;
|
||||
double a = 8, c = 8, b = 100, d = 150;
|
||||
CvPoint bp[4], *bpp = bp;
|
||||
cvNamedWindow( "test", 1 );
|
||||
IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 );
|
||||
cvZero(img);
|
||||
for( i = 0; i < point_count; i++ )
|
||||
cvCircle(img,cvPoint(cvRound(p[i].x*a+b),cvRound(p[i].y*c+d)), 3, CV_RGB(0,255,0), -1 );
|
||||
for( i = 0; i < n; i++ )
|
||||
bp[i] = cvPoint(cvRound(triangle[i].x*a+b),cvRound(triangle[i].y*c+d));
|
||||
cvPolyLine( img, &bpp, &n, 1, 1, CV_RGB(255,255,0), 1, CV_AA, 0 );
|
||||
cvShowImage( "test", img );
|
||||
cvWaitKey();
|
||||
cvReleaseImage(&img);
|
||||
}
|
||||
#endif
|
||||
|
||||
int polygonVertices = (int) convexPolygon.size();
|
||||
|
||||
if (polygonVertices > 2) {
|
||||
// Check if all points are enclosed by the triangle
|
||||
for (int i = 0; (i < polygonVertices) && (!errorEnclosed); i++)
|
||||
{
|
||||
if (cv::pointPolygonTest(triangle, cv::Point2f(convexPolygon[i].x, convexPolygon[i].y), true) < (-eps))
|
||||
errorEnclosed = true;
|
||||
}
|
||||
|
||||
// Check if triangle edges middle points touch the polygon
|
||||
std::vector<cv::Point2f> middlePoints = getTriangleMiddlePoints();
|
||||
|
||||
for (int i = 0; (i < 3) && (!errorMiddlePoints); i++)
|
||||
{
|
||||
bool isTouching = false;
|
||||
|
||||
for (int j = 0; (j < polygonVertices) && (!isTouching); j++)
|
||||
{
|
||||
if (cvTsIsPointOnLineSegment(middlePoints[i], convexPolygon[j],
|
||||
convexPolygon[(j + 1) % polygonVertices]))
|
||||
isTouching = true;
|
||||
}
|
||||
|
||||
errorMiddlePoints = (isTouching) ? false : true;
|
||||
}
|
||||
|
||||
// Check if at least one of the edges is flush
|
||||
for (int i = 0; (i < 3) && (errorFlush); i++)
|
||||
{
|
||||
for (int j = 0; (j < polygonVertices) && (errorFlush); j++)
|
||||
{
|
||||
if ((cvTsIsPointOnLineSegment(convexPolygon[j], triangle[i],
|
||||
triangle[(i + 1) % 3])) &&
|
||||
(cvTsIsPointOnLineSegment(convexPolygon[(j + 1) % polygonVertices], triangle[i],
|
||||
triangle[(i + 1) % 3])))
|
||||
errorFlush = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Report any found errors
|
||||
if (errorEnclosed)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"All points should be enclosed by the triangle.\n" );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
}
|
||||
else if (errorMiddlePoints)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"All triangle edges middle points should touch the convex hull of the points.\n" );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
}
|
||||
else if (errorFlush)
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG,
|
||||
"At least one edge of the enclosing triangle should be flush with one edge of the polygon.\n" );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
}
|
||||
}
|
||||
|
||||
if ( code < 0 )
|
||||
ts->set_failed_test_info( code );
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
* MinEnclosingCircle Test *
|
||||
\****************************************************************************************/
|
||||
@ -1691,6 +1847,7 @@ void CV_PerimeterAreaSliceTest::run( int )
|
||||
|
||||
TEST(Imgproc_ConvexHull, accuracy) { CV_ConvHullTest test; test.safe_run(); }
|
||||
TEST(Imgproc_MinAreaRect, accuracy) { CV_MinAreaRectTest test; test.safe_run(); }
|
||||
TEST(Imgproc_MinTriangle, accuracy) { CV_MinTriangleTest test; test.safe_run(); }
|
||||
TEST(Imgproc_MinCircle, accuracy) { CV_MinCircleTest test; test.safe_run(); }
|
||||
TEST(Imgproc_ContourPerimeter, accuracy) { CV_PerimeterTest test; test.safe_run(); }
|
||||
TEST(Imgproc_FitEllipse, accuracy) { CV_FitEllipseTest test; test.safe_run(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user