Wednesday, June 19, 2013

OpenCV Find Biggest Contour Using C++


                    Using OpencCV C++ interface it is very easy to processing with contour compared to old c interface. In old interface there are object like CvContourScanner  used to scan through each contour and the contours are stored in OpenCV Sequences. Also using all these things the code look like lengthy and complex. So here we are going to do all these thing using c++ interface.  A contour can be considered as a sequence of points that define a specific object in an image. Here in the below image we are going to extract the largest contour.
 




        In the above image each object can be considered as a contour, and the largest object can be find out by comparing area of each object.  So as a first step we have to go through each contour for comparing it's area with the previous one. OpenCV providing various function for doing these and described below.

findContours   :- Find contours in the binary image.
drawContours :- Draw filled contour or outline of contour. 
boundingRect  :- Calculate a bounding rectangle for a contour.
contourArea    :-  Calculate area for a specific contour.


The below code do the following;
  • Load 3 channel image.
  • Convert to single channel gray image.
  • Threshold with a lower value to extract contours.
  • Store all contours as vectors.
  • Find out the biggest contour by comparing area of each contour. 
  • Draw the biggest contour.
  • Show the result.
#include <iostream>
#include "opencv2\highgui\highgui.hpp"
#include "opencv\cv.h"

using namespace cv;
using namespace std;
int main()
{
 int largest_area=0;
 int largest_contour_index=0;
 Rect bounding_rect;

 Mat src = imread("src.jpg"); //Load source image
 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<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);  
 imshow( "src", src );
 imshow( "largest Contour", dst );
 waitKey(0);
}


Result:- 

Source Image










Largest Contour