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.
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
1 2 3 |
cv2.findContours(src, contour_retrieval, contours_approximation) |
Parameters
You need to pass three parameters to findContours() method.
src:
Input Image of n – dimensional array(n = 2,3) but preferred 2-dim binary images for better result.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.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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# 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) |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# 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) |
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.