Python | cv2 findContours() Method

In this tutorial, we will see how to find all boundary points(x,y) of an object in the image using python open-cv, which exists as cv2 (computer vision) library.
[toc]
You can use findContours() method of cv2 library to find all boundary points(x,y) of an object in the image. To use cv2 library, you need to import cv2 library using import statement.

Contours can be explained simply as a curve joining all the continuous points (along the boundary), having the same color or intensity. The contours are very useful for shape analysis and object recognition and object detection.

Note:
For better accuracy, we must use binary images. So before finding contours, apply threshold or canny edge detection on the input image.

Now let’s see the syntax and return value of cv2 findContours() method first, then we will move on to the examples.

Syntax

cv2.findContours(src, contour_retrieval, contours_approximation) 

Parameters

You need to pass three parameters to findContours() method.

  1. src: Input Image of n – dimensional array(n = 2,3) but preferred 2-dim binary images for better result.
  2. contour_retrieval: This is contour retrieval mode. Possible values are :
    a) cv2.RETR_TREE
    b) cv2.RETR_EXTERNAL
    c) cv2.RETR_LIST
    d) cv2.RETR_CCOMP etc.
  3. contours_approximation: This is Contour approximation method. Possible values are :
    a) cv2.CHAIN_APPROX_NONE
    b) cv2.CHAIN_APPROX_SIMPLE

Return Value

It returns three values :
a) Input image array
b) Contours
c) Hierarchy

Note:
1) Contours is a Python list of all the contours in the image. Each individual contour is a Numpy array of (x,y) coordinates of boundary points of the object.

2) Hierarchy is the parent-child relationship in contours. It is represented as an array of four values : [Next contour, previous contour, First child contour, Parent contour]

If you are interested in reading more about Hierarchy,Contour Retrieval Mode then click on this given link hierarchy and contours retrieval mode

Contours Approximation Method

Above, we see that contours are the boundaries of a shape with the same intensity. It stores the (x, y) coordinates of the boundary of a shape. But does it store all the coordinates? That is specified by this contour approximation method.
If we pass cv2.CHAIN_APPROX_NONE, all the boundary points are captured. But actually, do we need all the points? For eg, if we need find the contour of a straight line. We require just two endpoints of that line. In that case, you can pass cv2.CHAIN_APPROX_SIMPLE. It excludes all excessive points and compresses the contour, thereby saving memory.

cv2 findContours() Method examples

Now Let’s see the Python code:

Example 1: Using cv2.RETR_TREE as a retrieval mode and cv2.CHAIN_APPROX_NONE as a Contour approximation method.

# import computer vision library(cv2) in this code
import cv2

# main code
if __name__ == "__main__" :

    # mentioning absolute path of the image
    img_path = "C:\\Users\\user\\Desktop\\rectangle.jpg"

    # read/load an image in grayscale mode
    image = cv2.imread(img_path,0)

    # show the Input image on the newly created image window
    cv2.imshow('Input',image)

    # applying cv2.THRESH_BINARY thresholding techniques
    ret, bin_img = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)

    # show the binary image on the newly created image window
    cv2.imshow('Intermediate',bin_img)

    # extracting the contours from the given binary image
    img,contours, hierarchy = cv2.findContours(bin_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

    print("Total Number of Contours found =", len(contours))
    print("contours are: \n",contours)
    print("hierarchy is: \n",hierarchy)

Output :
output1

Total Number of Contours found = 5
contours are:
[array([[[0, 0]],[[0, 1]],

[[0, 2]],

…,

[[3, 0]],

[[2, 0]],

[[1, 0]]], dtype=int32), array([[[202, 35]],

[[203, 34]],

[[204, 35]],

[[203, 36]]], dtype=int32), array([[[183, 35]],

[[184, 34]],

[[185, 34]],

[[186, 34]],

[[187, 34]],

[[188, 34]],

[[189, 34]],

[[190, 34]],

[[191, 34]],

[[192, 35]],

[[191, 36]],

[[190, 36]],

[[189, 36]],

[[188, 36]],

[[187, 36]],

[[186, 36]],

[[185, 36]],

[[184, 36]]], dtype=int32), array([[[49, 35]],

[[50, 34]],

[[51, 34]],

[[52, 34]],

[[53, 35]],

[[52, 36]],

[[51, 36]],

[[51, 37]],

[[50, 38]],

[[49, 37]],

[[49, 36]]], dtype=int32), array([[[46, 32]],

[[47, 31]],

[[48, 31]],

…,

[[46, 35]],

[[46, 34]],

[[46, 33]]], dtype=int32)]
hierarchy is:
[[[-1 -1 1 -1]
[ 2 -1 -1 0]
[ 3 1 -1 0]
[ 4 2 -1 0]
[-1 3 -1 0]]]

Example 2: Using cv2.RETR_EXTERNAL as a Contour retrieval mode and cv2.CHAIN_APPROX_SIMPLE as a Contour approximation method.

# import computer vision library(cv2) in this code
import cv2

# main code
if __name__ == "__main__" :

    # mentioning absolute path of the image
    img_path = "C:\\Users\\user\\Desktop\\rectangle.jpg"

    # read/load an image in grayscale mode
    image = cv2.imread(img_path,0)

    # show the Input image on the newly created image window
    cv2.imshow('Input',image)

    # applying cv2.THRESH_BINARY thresholding techniques
    ret, bin_img = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)

    # show the binary image on the newly created image window
    cv2.imshow('Intermediate',bin_img)

    # extracting the contours from the given binary image
    img,contours, hierarchy = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    print("Total Number of Contours found =", len(contours))

    print("contours are: \n",contours)
    print("hierarchy is: \n",hierarchy)

Output :
output1

Total Number of Contours found = 1
contours are:
[array([[[ 0, 0]],[[ 0, 191]],

[[261, 191]],

[[261, 0]]], dtype=int32)]
hierarchy is:

[[[-1 -1 -1 -1]]]

Reference

OpenCV python Contours tutorial

That’s all about cv2 findContours() Method.

[social_share share_on="facebook,twitter,linkedin,whatsapp"][post_navigator in_same_term="true"]

Leave a Reply

Your email address will not be published. Required fields are marked *

Subscribe to our newletter

Get quality tutorials to your inbox. Subscribe now.