Ask Your Question
3

Draw largest/rect contour on this image

asked 2014-04-22 22:55:32 -0600

Luek gravatar image

updated 2020-10-28 02:33:41 -0600

I need to find the largest contour/rect on this image which should be the card. image description

I try to use the following code but I get no drawing:

int largest_area=0;
int largest_contour_index=0;
cv::Rect bounding_rect;

Mat thr(src.rows,src.cols,CV_8UC1);
Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0));
cvtColor(src,thr,CV_BGR2GRAY); //Convert to gray
threshold(thr, thr,25, 255,THRESH_BINARY); //Threshold the gray

vector<vector<cv::Point>> contours; // Vector for storing contour
vector<Vec4i> hierarchy;

findContours( thr, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image

for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
{
    double a=contourArea( contours[i],false);  //  Find the area of contour
    if(a>largest_area){
        largest_area=a;
        largest_contour_index=i;                //Store the index of largest contour
        bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
    }

}

Scalar color( 255,255,255);
drawContours( dst, contours,largest_contour_index, color, CV_FILLED, 8, hierarchy ); // Draw the largest contour using previously stored index.
rectangle(src, bounding_rect,  Scalar(0,255,0),1, 8,0);

Could someone provide me with an example using this image to find the largest rect?

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2015-05-30 13:42:20 -0600

updated 2015-12-28 17:01:25 -0600

image description

sample code for finding and drawing biggest contour.

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
    Mat src = imread( argv[1] );

    int largest_area=0;
    int largest_contour_index=0;
    Rect bounding_rect;

    Mat thr;
    cvtColor( src, thr, COLOR_BGR2GRAY ); //Convert to gray
    threshold( thr, thr, 125, 255, THRESH_BINARY ); //Threshold the gray

    vector<vector<Point> > contours; // Vector for storing contours

    findContours( thr, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE ); // Find the contours in the image

    for( size_t i = 0; i< contours.size(); i++ ) // iterate through each contour.
    {
        double area = contourArea( contours[i] );  //  Find the area of contour

        if( area > largest_area )
        {
            largest_area = area;
            largest_contour_index = i;               //Store the index of largest contour
            bounding_rect = boundingRect( contours[i] ); // Find the bounding rectangle for biggest contour
        }
    }

    drawContours( src, contours,largest_contour_index, Scalar( 0, 255, 0 ), 2 ); // Draw the largest contour using previously stored index.

    imshow( "result", src );
    waitKey();
    return 0;
}
edit flag offensive delete link more
0

answered 2014-04-23 17:17:07 -0600

Witek gravatar image

Try adding this at the very end of your code:

imshow("dst_image", dst);
imshow("src_image", src);
waitKey();
edit flag offensive delete link more

Comments

is it possible to find the 2nd, 3rd and 4th largest?

vom gravatar imagevom ( 2019-09-21 06:40:19 -0600 )edit

Yes, you can sort the contours by their size (perimeter or area, whichever you prefer) in descending order and so contours[0] will be the largest contour, contours[1] 2nd largest and so on.

sort(contours.begin(), contours.end(), [](const vector<Point>& c1, const vector<Point>& c2){
    return contourArea(c1, false) > contourArea(c2, false);
});
Witek gravatar imageWitek ( 2019-09-21 12:51:40 -0600 )edit

Question Tools

Stats

Asked: 2014-04-22 22:55:32 -0600

Seen: 24,883 times

Last updated: Dec 28 '15