Calculating convexityDefects using OpenCV 2.4 in c++

后端 未结 4 1714
时光取名叫无心
时光取名叫无心 2020-11-30 12:21

I\'m using OpenCV 2.4 to calculate the convex hull of a image.

I\'m also doing some processing to remove some noise from the image, which is not really relevant to

相关标签:
4条回答
  • 2020-11-30 12:27

    I've been having the same error for a while until the solution was presented to me. Just check the size of contours[i] before calling convexityDefects

    /// Find the convex hull object for each contour
    vector<vector<int> > hullsI(contours.size());
    vector<vector<Point> > hullsP(contours.size());
    vector<vector<Vec4i> > defects(contours.size());
    
    for(int i = 0; i <contours.size(); ++i){
        //find the hulls
        convexHull(contours[i], hullsI[i], false, false);
        convexHull(contours[i], hullsP[i], false, true);
        //find the defects
        if (contours[i].size() >3 )
        {
            convexityDefects(contours[i], hullsI[i], defects[i]);            
        }
    
    }
    

    Hope it helps :)

    0 讨论(0)
  • 2020-11-30 12:34

    For those who don't read the comments or didn't see it the solution is to use:

    vector<cv::vector<int> >hull;

    to create the hull instead of:

    vector<cv::vector<Point> >hull;

    as convexityDefects only works on hulls stored as a series of indices rather than a series of Points.

    Sadly this gives another problem as drawContours only draws contours stored as a series of Points and not as a series of indices! So if you want to draw your hulls at a later stage you may want to create 2 stores when you are finding the hulls, one for drawing and one for finding defects from. Something along the lines of the following works:

      // create storage space
      vector<vector<int> > hullsI(contours.size());
      vector<vector<Point> > hullsP(contours.size());
      vector<vector<Vec4i> > defects(contours.size());
    
      for(int i = 0; i <contours.size(); ++i){
         //find the hulls
         convexHull(contours[i], hullsI[i], true);
         convexHull(contours[i], hullsP[i], true);
         //find the defects  
         convexityDefects(contours[i], hullsI[i], defects[i]);
         }
    

    It may be more efficient to just use a different method to draw the hulls rather than calculating them twice but this was the most elegant way I saw of doing it.

    Also I'm still getting the hang of C/C++ myself (Java guy) but I believe if you add using namespace cv to the top of the code you can save having to have cv:: throughout your code.

    Hope I haven't stepped on toes Innuendo, not my intention at all if I have.

    0 讨论(0)
  • 2020-11-30 12:42

    From openCV wiki :

    Finds the convexity defects of a contour.

    So you should include it in your loop.

    std::vector<Vec4i> defects; 
    vector<cv::vector<int> >hull( contours.size() );
    
    for (int i = 0; i < contours.size(); i++)
    {  
        convexHull( contours[i], hull[i], false );
        convexityDefects(contours[i], hull[i], defects[i]);
    }
    

    Also, as you mentioned, in wiki is said:

    hull – Output convex hull. It is either an integer vector of indices or vector of points. In the first case, the hull elements are 0-based indices of the convex hull points in the original array (since the set of convex hull points is a subset of the original point set). In the second case, hull elements are the convex hull points themselves.

    0 讨论(0)
  • 2020-11-30 12:48

    i had problems like mentioned above but at last i write the correct one :)

    vector<vector<Point>> hull( contours.size() );
    vector<vector<int> > hullsI(contours.size());
    vector<vector<Vec4i>> convdefect(contours.size());
    
    for( int i = 0; i < contours.size(); i++ )
    { 
        convexHull( Mat(contours[i]), hull[i], false);
        convexHull( Mat(contours[i]), hullsI[i], false);        
        if(hullsI[i].size() > 3 )
            convexityDefects(contours[i],hullsI[i],convdefect[i]);
    }
    /// Draw contours + hull results
    Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
    for( int i = 0; i< contours.size(); i++ )
    {
        size_t count = contours[i].size();
        if( count <300 )
            continue;
    
        //Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255));
        drawContours( drawing, contours, i, Scalar(255,0,0), 1, 8, vector<Vec4i>(), 0, Point());
        drawContours( drawing, hull, i, Scalar(0,0,255), 1, 8, vector<Vec4i>(), 0, Point());
    }
    
    /// Draw convexityDefects
    for( int i = 0; i< contours.size(); i++ )
    {
        size_t count = contours[i].size();
        if( count <300 )
            continue;
    
        vector<Vec4i>::iterator d=convdefect[i].begin();
        while( d!=convdefect[i].end() ) {
            Vec4i& v=(*d);
            int startidx=v[0]; Point ptStart( contours[i][startidx] );
            int endidx=v[1]; Point ptEnd( contours[i][endidx] );
            int faridx=v[2]; Point ptFar( contours[i][faridx] );
            float depth = v[3] / 256;
    
            line( drawing, ptStart, ptEnd, Scalar(0,255,0), 1 );
            line( drawing, ptStart, ptFar, Scalar(0,255,0), 1 );
            line( drawing, ptEnd, ptFar, Scalar(0,255,0), 1 );
            circle( drawing, ptFar,   4, Scalar(0,255,0), 2 );
            d++;
        }
    }
    
    0 讨论(0)
提交回复
热议问题