简体   繁体   中英

OpenCV Draw draw contours of 2 largest objects

I am doing a OpenCV software that detects boxing gloves therefore i want to detect and draw only 2 largest contours (one for each boxing glove).

My software draws contours for everything and some things are noise only which ofcourse i dont want

My code for drawing contours:

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(mBlur, contours, hierarchy, CV_RETR_EXTERNAL,  CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    //----------------------------------------------------------------------------->

    vector<vector<Point> > contours_poly(contours.size());
    vector<Rect> boundRect (contours.size());
    vector<Point2f> boundingBoxArea(boundRect.size());

    //----------------------------------------------------------------------------->

    for( int i = 0; i < contours.size(); i++ )
     { 
       approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
       boundRect[i] = boundingRect( Mat(contours_poly[i]) );

     }

    /// Draw polygonal contour + bonding rects
   Mat drawing = Mat::zeros( range_out.size(), CV_8UC3 );

    for( int i = 0; i< contours.size(); i++ )
        {

           Scalar color = Scalar(0,0,255);
           drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
           fillPoly(drawing, contours, Scalar(255,0,0));

       }

Here is an Image Example:

在此处输入图片说明

My program already segments the gloves by color, The problelem is that at times small contours are drawn in random locations due to noise. Now of course the gloves contours are by far dominant and this is why i want to keep only the contours of these. Hope this makes my question clearer

Could someone suggest a solution please I am coding in C++ environment regards

The easiest way to look at the two largest contours is to simply look at the contours size. Something like this should do the trick:

int largestIndex = 0;
int largestContour = 0;
int secondLargestIndex = 0;
int secondLargestContour = 0;
for( int i = 0; i< contours.size(); i++ )
{
    if(contours[i].size() > largestContour){
        secondLargestContour = largestContour;
        secondLargestIndex = largestIndex;
        largestContour = contours[i].size();
        largestIndex = i;
    }else if(contours[i].size() > secondLargestContour){
        secondLargestContour = contours[i].size();
        secondLargestIndex = i;
    }
}
Scalar color = Scalar(0,0,255);
drawContours( drawing, contours, largestIndex, color, CV_FILLED, 8);
drawContours( drawing, contours, secondLargestIndex, color, CV_FILLED, 8);

It seems that vector<vector<Point> > contours stores all your contours. What you need to do is iterate on this vector and do a little arithmetics with it elements, to be able to detect the 2 largest contours in the vector.

On this answer I shared code that detects the largest contour in a vector<vector<Point> > , so you are half way there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM