Overview
Contours can be explained simply as a curve joining all the continuous points (along the boundary), having same color or intensity. The contours are a useful tool for shape analysis and object detection and recognition.
It is recommended to use binary images for better accuracy.
If you want to go deeper into OpenCV and Image Detection techniques with Blob, Edge and Contour then you can learn it with Live Demo.
Edge Detection
This is the first step towards identification of edges in an image to identify the objects
cv2.Canny(image, edges, threshold1, threshold2)
- image – input image
- threshold1 – first thresholding for identification of real edges
- threshold2 – second thresholding for identification of real edges
- apertureSize (optional) – aperture size for the Sobel operator.
- L2gradient (optional) – specifies the equation for finding gradient magnitude
import cv2
img = cv2.imread('robot.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(image=img_gray, threshold1=100, threshold2=200)
cv2.imshow('Canny', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
Original Image
Canny Edge Detection
Find the Contours
Before finding contours, we apply threshold or canny edge detection. 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.
contours, hierarchy = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
wherein:
- image – input image
- second argument is contour retrieval mode
- third argument is contour approximation method
- Another approximation method cv2.CHAIN_APPROX_NONE stores all boundary points which are unnecessary as in cv2.CHAIN_APPROX_SIMPLE corner points will suffice to form boundary.
contours is a Numpy array of (x,y) coordinates of boundary points of the object detected in an image
hierarchy is the relationship of contours with each others. Its an array of four values [Next, Previous, First_Child, Parent]
Draw the Contour
The drawcontour() method can be used to draw any shape provided you have its boundary points.
cv2.drawContours(image, contours, -1, (0,255,0), 3, lineType=cv2.LINE_AA)
wherein:
- image – input image
- (0,255,0) – second argument is the contours which should be passed as a Python list
- -1 – index of contours (useful when drawing individual contour. To draw all contours, pass -1)
- (0,255,0) – color type
- 3 – thinkness of line
- lineType (optional) -type of line
import cv2
img = cv2.imread('robot.jpg')
img_copy = img.copy()
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(image=img_gray,threshold1=100, threshold2=200)
contours, hierarchy = cv2.findContours(image=edges, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)
cv2.drawContours(image=img, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=2, lineType=cv2.LINE_AA)
cv2.imshow('Contours', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Draw Contours
Contour Features
In addition to this, there are other important features such as area (area of the identified contour) and rectangle (straight rectangle) can be drawn.
area = cv2.contourArea(cnt)
cv2.boundingRect()
Let (x,y) be the top-left coordinate of the rectangle and (w,h) be its width and height.
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)