Contours - Getting Started - OpenCV-Python Tutorials 1 Documentation
Contours - Getting Started - OpenCV-Python Tutorials 1 Documentation
For better accuracy, use binary images. So before finding contours, apply threshold or
canny edge detection.
findContours function modifies the source image. So if you want source image even
after finding contours, already store it to some other variables.
In OpenCV, finding contours is like finding white object from black background. So
remember, object to be found should be white and background should be black.
import numpy as np
import cv2
im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
image, contours, hierarchy =
cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
See, there are three arguments in cv2.findContours() function, first one is source image,
second is contour retrieval mode, third is contour approximation method. And it outputs the
image, contours and hierarchy. 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.
Note
We will discuss second and third arguments and about hierarchy in details later. Until then,
the values given to them in code sample will work fine for all images.
cnt = contours[4]
img = cv2.drawContours(img, [cnt], 0, (0,255,0), 3)
Note
Last two methods are same, but when you go forward, you will see last one is more useful.
Above, we told that contours are the boundaries of a shape with 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 you pass cv2.CHAIN_APPROX_NONE , all the boundary points are stored. But actually do we need
all the points? For eg, you found the contour of a straight line. Do you need all the points on the
line to represent that line? No, we need just two end points of that line. This is what
cv2.CHAIN_APPROX_SIMPLE does. It removes all redundant points and compresses the contour,
thereby saving memory.
Below image of a rectangle demonstrate this technique. Just draw a circle on all the
coordinates in the contour array (drawn in blue color). First image shows points I got with
cv2.CHAIN_APPROX_NONE (734 points) and second image shows the one with
cv2.CHAIN_APPROX_SIMPLE (only 4 points). See, how much memory it saves!!!
Additional Resources
Exercises