【问题标题】:How to calculate convex hull area using openCV functions?如何使用openCV函数计算凸包面积?
【发布时间】:2011-06-24 16:45:37
【问题描述】:

我找不到如何使用 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 );

【问题讨论】:

    标签: opencv


    【解决方案1】:
        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)));
    

    【讨论】:

    • 我完全看不到将 std::vector(s) 转换为 cv::Mat 的必要性:它们完全可以被凸包、approxPolyDP 和 contourArea 消化
    • @Pradeep Pati 感谢您的帮助,convexHull 和轮廓向量有什么区别?在我的情况下,它总是相同的点向量?据我了解,convexHull 本身就是多边形曲线吗?
    【解决方案2】:

    实际上计算 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.
    }
    

    面积=绝对(面积); // 如果积分是从右到左开始的,则面积可以是负数。

    【讨论】:

    • 你是对的,虽然(感谢你)我找到了另一种计算二维凸包面积的方法。
    【解决方案3】:

    使用: CvSeq* convex_hull=cvConvexHull2( &amp;point_mat, &amp;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);
    }
    

    【讨论】:

    • 这正是我所需要的。谢谢
    【解决方案4】:

    在 OpenCV 2.4.9 中:

    double computeConvexHullArea(vector<Point> originalPoints)
    {
        vector<Point> hull;
        convexHull(originalPoints, hull);
    
        return contourArea(hull);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-16
      • 2013-08-11
      • 2012-01-04
      • 1970-01-01
      • 2019-02-28
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      • 2016-02-23
      相关资源
      最近更新 更多