如何使用openCV函数计算凸包区域?

Gor*_*yni 4 opencv

我无法找到如何使用OpenCV计算凸包区域的实例.我看到一个使用cvApproxPoly和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 );
Run Code Online (Sandbox Code Playgroud)

Gor*_*yni 13

    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)));
Run Code Online (Sandbox Code Playgroud)

  • 我完全没有看到需要转换为cv :: Mat的std :: vector(s):它们被convexHull,approxPolyDP和contourArea完美地消化了 (2认同)

Dan*_*HsH 6

实际上计算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.
}
Run Code Online (Sandbox Code Playgroud)

area = abs(area); //如果从右到左开始集成,则Area可以为负数.