Find Contour

void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())

Parameters:
  • image – Source, an 8-bit single-channel image. Non-zero pixels are treated as 1’s. Zero pixels remain 0’s, so the image is treated as binary . You can use compare() , inRange() , threshold() , adaptiveThreshold() , Canny() , and others to create a binary image out of a grayscale or color one. The function modifies the image while extracting the contours.
  • contours – Detected contours. Each contour is stored as a vector of points.
  • hierarchy – Optional output vector, containing information about the image topology. It has as many elements as the number of contours. For each i-th contour contours[i] , the elements hierarchy[i][0] , hiearchy[i][1] , hiearchy[i][2] , and hiearchy[i][3] are set to 0-based indices in contours of the next and previous contours at the same hierarchical level, the first child contour and the parent contour, respectively. If for the contour i there are no next, previous, parent, or nested contours, the corresponding elements of hierarchy[i] will be negative.
  • mode – Contour retrieval mode (if you use Python see also a note below).
    • CV_RETR_EXTERNAL retrieves only the extreme outer contours. It sets hierarchy[i][2]=hierarchy[i][3]=-1 for all the contours.
    • CV_RETR_LIST retrieves all of the contours without establishing any hierarchical relationships.
    • CV_RETR_CCOMP retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level.
    • CV_RETR_TREE retrieves all of the contours and reconstructs a full hierarchy of nested contours. This full hierarchy is built and shown in the OpenCV contours.c demo.
  • method – Contour approximation method (if you use Python see also a note below).
    • CV_CHAIN_APPROX_NONE stores absolutely all the contour points. That is, any 2 subsequent points (x1,y1) and (x2,y2) of the contour will be either horizontal, vertical or diagonal neighbors, that is, max(abs(x1-x2),abs(y2-y1))==1.
    • CV_CHAIN_APPROX_SIMPLE compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points.
    • CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS applies one of the flavors of the Teh-Chin chain approximation algorithm. 
  • offset – Optional offset by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context.

void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )

Parameters:
  • image – Destination image.
  • contours – All the input contours. Each contour is stored as a point vector.
  • contourIdx – Parameter indicating a contour to draw. If it is negative, all the contours are drawn.
  • color – Color of the contours.
  • thickness – Thickness of lines the contours are drawn with. If it is negative (for example, thickness=CV_FILLED ), the contour interiors are drawn.
  • lineType – Line connectivity. See line() for details.
  • hierarchy – Optional information about hierarchy. It is only needed if you want to draw only some of the contours (see maxLevel ).
  • maxLevel – Maximal level for drawn contours. If it is 0, only the specified contour is drawn. If it is 1, the function draws the contour(s) and all the nested contours. If it is 2, the function draws the contours, all the nested contours, all the nested-to-nested contours, and so on. This parameter is only taken into account when there is hierarchy available.
  • offset – Optional contour shift parameter. Shift all the drawn contours by the specified \texttt{offset}=(dx,dy) .
  • contour – Pointer to the first contour.
  • externalColor – Color of external contours.
  • holeColor – Color of internal contours (holes)

Steps:

  1. Load an image 
  2. Create a structuring element
  3. Apply erosion or dilation on the image
  4. Show result

Functions:

Example 1:Find Contour OpenCV documentation implementation

-------------
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
using namespace cv;
using namespace std;
int main( )
{
    Mat image;
    image = imread("shape.jpg", 1);  
    namedWindow( "Display window", CV_WINDOW_AUTOSIZE );  
    imshow( "Display window", image );
    Mat gray;
    cvtColor(image, gray, CV_BGR2GRAY);
    Canny(gray, gray, 100, 200, 3);
    /// Find contours   
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    RNG rng(12345);
    findContours( gray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    /// Draw contours
    Mat drawing = Mat::zeros( gray.size(), CV_8UC3 );
    for( int i = 0; i< contours.size(); i++ )
    {
        Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
        drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
    }     

    imshow( "Result window", drawing );
    waitKey(0);                                         
    return 0;
}
-------------

 Result:

 

 

Example 2: Find Largest contour

-------------
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp""
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
using namespace cv;
using namespace std;
int main( )
{
    Mat src;
    src = imread("shape.jpg", CV_LOAD_IMAGE_COLOR);
    Mat gray;
    cvtColor(src, gray, CV_BGR2GRAY);
    threshold(gray, gray,200, 255,THRESH_BINARY_INV); //Threshold the gray
    imshow("gray",gray);int largest_area=0;
    int largest_contour_index=0;
    Rect bounding_rect;
    vector<vector<Point>> contours; // Vector for storing contour
    vector<Vec4i> hierarchy;
    findContours( gray, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
    // iterate through each contour.
    for( int i = 0; i< contours.size(); i++ )
    {
        //  Find the area of contour
        double a=contourArea( contours[i],false); 
        if(a>largest_area){
            largest_area=a;cout<<i<<" area  "<<a<<endl;
            // Store the index of largest contour
            largest_contour_index=i;               
            // Find the bounding rectangle for biggest contour
            bounding_rect=boundingRect(contours[i]);
        }
    }
    Scalar color( 255,255,255);  // color of the contour in the
    //Draw the contour and rectangle
    drawContours( src, contours,largest_contour_index, color, CV_FILLED,8,hierarchy);
    rectangle(src, bounding_rect,  Scalar(0,255,0),2, 8,0);
    namedWindow( "Display window", CV_WINDOW_AUTOSIZE );
    imshow( "Display window", src );    
    waitKey(0);                                         
    return 0;
} 

-------------

Result:




Sources:
http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html
http://harismoonamkunnu.blogspot.in/2013/06/opencv-find-biggest-contour-using-c.html


32 comments:

  1. Hi, i have threshold image. How can i draw bounding box for the threshold object.

    ReplyDelete
    Replies
    1. That means you are at line 13 of Example 2.

      Make sure that after threshold, the object of interest is white and background is black.

      Then you can apply "findContours" as in line 19.
      If you will have only one contour, then you can directly put the index value as "0" in line 30 to find the "bounding_rect".

      Then use line 36 to draw a bounding box around the object.

      Delete
  2. can you explain contour.size() ? and I want to know how many points in each contours,

    ReplyDelete
    Replies
    1. I want to use the contour.size() to find the number of vertices of the contours,have you found the solution ?

      Delete
    2. contours.size() provides the number of contours in the image. Here number of contours means number of segmented regions.

      Therefore, you can not use contours.size() to find the number of vertices.

      You may find a solution of this question by using convex-hull method.

      Delete
  3. And how I can draw bounding box if I use bgs MOG from opencv? Is it the same?

    ReplyDelete
  4. can i please get the same coed in python?

    ReplyDelete
  5. import numpy as np
    import cv2
    im = cv2.imread("shape.jpg")
    imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    ret,thresh = cv2.threshold(imgray,127,255,0)
    contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

    cv2.drawContours(im,contours,-1,(0,255,0),2) #-1 fills it


    cv2.imshow("Contours",im)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    # Lijo Joseph

    ReplyDelete
    Replies
    1. but for 16 uint images??
      i've an image from a depth camera, i've binarized it with otsu method and now i want find and plot contour area
      thanks

      Delete
    2. I'm getting this error. Could you please help? Thanks

      Traceback (most recent call last):
      File "C:\Python27\contous.py", line 4, in
      imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
      error: ..\..\..\src\opencv\modules\imgproc\src\color.cpp:3414: error: (-215) scn == 3 || scn == 4

      Delete
    3. Get error:
      contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
      ValueError: too many values to unpack (expected 2)

      Delete
  6. Code is working fine. Thank you. I have another question. Is there any way to draw only the largest contour on new image?

    I can draw the largest contour, but new Mat size is in size of old one image.

    Mat mask_image( image.size(), CV_8U, Scalar(0));
    drawContours(mask_image, contours, largest_contour_index, Scalar(255), FILLED);
    plate.copyTo(original_image, mask_image);

    Is there any way to get biggest contour size, then make new Mat in size of this contour and draw an image? Without other area which is black?

    ReplyDelete
  7. Your problem statement is not clear, sorry...

    ReplyDelete
  8. Hi, I wish to draw the contours of certain clicked region only, For example, mouse click on the triangle, and only the contour of triangle is drawn. Is it possible? and How should i implement that?

    ReplyDelete
    Replies
    1. You can use mouse click to do so. Please refer to the following link.
      opencvexamples.blogspot.com/2014/01/select-region-on-mouse-click.html

      Once you get all contours, click on one image region and it will high light based on the mouse position.

      Delete
  9. Thank you very much for this very clear example. You saved my day.. :)

    ReplyDelete
  10. Hi,I want to display the chain codes of the contour in opencv with c++ language, but I can not find function in c++.
    can someone help me?
    Thanks.

    ReplyDelete
  11. Hi how can I extract the properties of a ( or some ) pixel(s) at the center of a contour? and if it is a camera frame and camera is moving how can I track each contour and extract the properties of a ( or some ) pixel(s) at the center of contour?

    ReplyDelete
  12. how can i draw contours only around blue colored objects? Also I need their centroids.

    ReplyDelete
  13. Very nice programs you had these hidden here.

    ReplyDelete
  14. really working program very nice

    ReplyDelete
  15. how can i find out number of child contours inside a parent contour?
    and is there any method wherein i can add box numbers to boxes of chessboard type image?

    ReplyDelete
  16. How come you use the zeros function? What is it's purpose in the first program? Is it to make the whole picture totally black by setting the pixel values in the array to 0? Then the drawing of contours would pop out more?

    ReplyDelete
  17. Are there any C# codes to do this? Specially EmguCv. Can someone help me?
    Thank you!

    ReplyDelete
  18. Hi

    How do i detect a face using contours ?Currently i have the edge image of the face but have no idea on the next step.

    ReplyDelete
  19. I have a image with has lot of different colors. Suppose I draw a polygon with a specific color which is not there in the original image, how do I draw a contour around it and fill it with a specific color?

    Preferably in python.

    ReplyDelete
  20. Hi do you have a detection text using tesseract with OpenCV Thanks in advanced ^_^

    ReplyDelete
  21. how to find the area of the contour with opencv python

    ReplyDelete
  22. Can an6one translate the codes ti android/java... Thanks

    ReplyDelete