OpenCV Draw draw contours of 2 largest objects

11,037

Solution 1

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);

Solution 2

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.

Share:
11,037
Tomazi
Author by

Tomazi

Updated on June 04, 2022

Comments

  • Tomazi
    Tomazi almost 2 years

    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:

    enter image description here

    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