我找不到如何使用OpenCV计算凸包面积的工作示例。我看到了一个使用cvApprovPoly和cvContourArea的例子,但我无法使其工作。我有以下代码。
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
int i, count = rand()%100 + 1;
CvPoint pt0;
CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0]));
int* hull = (int*)malloc( count * sizeof(hull[0]));
CvMat point_mat = cvMat( 1, count, CV_32SC2, points );
CvMat hull_mat = cvMat( 1, count, CV_32SC1, hull );
for( i = 0; i < count; i++ )
{
pt0.x = rand() % (img->width/2) + img->width/4;
pt0.y = rand() % (img->height/2) + img->height/4;
points[i] = pt0;
}
CvSeq* convex_hull=cvConvexHull2( &point_mat, &hull_mat, CV_CLOCKWISE, 0 );
vector<Point2f> originalPoints; // Your original points
vector<Point2f> convexHull; // Convex hull points
vector<Point2f> contour; // Convex hull contour points
double epsilon = 0.001; // Contour approximation accuracy
// Calculate convex hull of original points (which points positioned on the boundary)
convexHull(Mat(originalPoints),convexHull,false);
// Approximating polygonal curve to convex hull
approxPolyDP(Mat(convexHull), contour, 0.001, true);
cout << fabs(contourArea(Mat(contour)));
实际上计算2D凸包的面积非常容易。按顺时针方向积分每个点下方的面积。这里有一个简单的代码可以做到这一点。(很少有第一行是凸包的定义和计算)。
vector<Point2f> originalPoints; // Your original points
vector<Point2f> ch; // Convex hull points
// Calculate convex hull of original points (which points positioned on the boundary)
cv::convexHull(Mat(originalPoints),ch,false);
// false parameter is used to organize the points in clockwise direction
// Now calculate the area of sonvex hull 'ch':
double area = 0;
for (int i = 0; i < ch.size(); i++){
int next_i = (i+1)%(ch.size());
double dX = ch[next_i].x - ch[i].x;
double avgY = (ch[next_i].y + ch[i].y)/2;
area += dX*avgY; // This is the integration step.
}
面积=abs(面积);//如果从右到左开始集成,则面积可能为负值。
使用:CvSeq* convex_hull=cvConvexHull2( &point_mat, &hull_mat, CV_CLOCKWISE, **1** ); // !!
我的代码:
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contours = 0;
cvFindContours(bordImage, storage, &contours, sizeof(CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
for(CvSeq* seq = contours; seq != 0; seq = seq->h_next){
cvDrawContours(dstImage, seq, CV_RGB(255,216,0), CV_RGB(0,0,250), 0, 1, 8);
}
CvMemStorage* hullStorage = cvCreateMemStorage(0);
for(CvSeq* seq = contours; seq != 0; seq = seq->h_next){
CvSeq *hulls = cvConvexHull2(seq, hullStorage, CV_CLOCKWISE, 1);
cvDrawContours(dstImage, hulls, CV_RGB(255, 0, 0), CV_RGB(100, 0, 0), 0, 1, 8);
for (int i = 0; i < hulls->total; i++) {
CvPoint* p = (CvPoint*)cvGetSeqElem ( hulls, i );
// ...
}
cvClearMemStorage(hullStorage);
}
在OpenCV 2.4.9:中
double computeConvexHullArea(vector<Point> originalPoints)
{
vector<Point> hull;
convexHull(originalPoints, hull);
return contourArea(hull);
}
对于OpenCV python:
hull = cv2.convexHull(cntr) #cntr is the contour
convex_hull_area = cv2.contourArea(hull)