0% found this document useful (0 votes)
13 views6 pages

OpenCV Contour Features in Python

Uploaded by

zinnigianluca2
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views6 pages

OpenCV Contour Features in Python

Uploaded by

zinnigianluca2
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Docs » OpenCV-Python Tutorials » Image Processing in OpenCV » Contours in OpenCV »

Contour Features

Contour Features
Goal
In this article, we will learn

To find the different features of contours, like area, perimeter, centroid, bounding box
etc
You will see plenty of functions related to contours.

1. Moments 

Image moments help you to calculate some features like center of mass of the object, area of
the object etc. Check out the wikipedia page on Image Moments

The function [Link]() gives a dictionary of all moment values calculated. See below:

import cv2
import numpy as np

img = [Link]('[Link]',0)
ret,thresh = [Link](img,127,255,0)
contours,hierarchy = [Link](thresh, 1, 2)

cnt = contours[0]
M = [Link](cnt)
print M

From this moments, you can extract useful data like area, centroid etc. Centroid is given by the
relations, and . This can be done as follows:

cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])

2. Contour Area
Contour area is given by the function [Link]() or from moments, M[‘m00’].
area = [Link](cnt)

3. Contour Perimeter
It is also called arc length. It can be found out using [Link]() function. Second argument
specify whether shape is a closed contour (if passed True ), or just a curve.

perimeter = [Link](cnt,True)

4. Contour Approximation
It approximates a contour shape to another shape with less number of vertices depending
upon the precision we specify. It is an implementation of Douglas-Peucker algorithm. Check
the wikipedia page for algorithm and demonstration.

To understand this, suppose you are trying to find a square in an image, but due to some
problems in the image, you didn’t get a perfect square, but a “bad shape” (As shown in first
image below). Now you can use this function to approximate the shape. In this, second
argument is called epsilon , which is maximum distance from contour to approximated
contour. It is an accuracy parameter. A wise selection of epsilon is needed to get the correct
output.

epsilon = 0.1*[Link](cnt,True)
approx = [Link](cnt,epsilon,True)

Below, in second image, green line shows the approximated curve for
epsilon = 10% of arc length . Third image shows the same for
epsilon = 1% of the arc length . Third argument specifies whether curve is closed or not.

5. Convex Hull
Convex Hull will look similar to contour approximation, but it is not (Both may provide same
results in some cases). Here, [Link]() function checks a curve for convexity defects
and corrects it. Generally speaking, convex curves are the curves which are always bulged out,
or at-least flat. And if it is bulged inside, it is called convexity defects. For example, check the
below image of hand. Red line shows the convex hull of hand. The double-sided arrow marks
shows the convexity defects, which are the local maximum deviations of hull from contours.

There is a little bit things to discuss about it its syntax:

hull = [Link](points[, hull[, clockwise[, returnPoints]]

Arguments details:

points are the contours we pass into.


hull is the output, normally we avoid it.
clockwise : Orientation flag. If it is True , the output convex hull is oriented clockwise.
Otherwise, it is oriented counter-clockwise.
returnPoints : By default, True . Then it returns the coordinates of the hull points. If
False , it returns the indices of contour points corresponding to the hull points.

So to get a convex hull as in above image, following is sufficient:

hull = [Link](cnt)

But if you want to find convexity defects, you need to pass returnPoints = False . To
understand it, we will take the rectangle image above. First I found its contour as cnt . Now I
found its convex hull with returnPoints = True , I got following values:
[[[234 202]], [[ 51 202]], [[ 51 79]], [[234 79]]] which are the four corner points of
rectangle. Now if do the same with returnPoints = False , I get following result:
[[129],[ 67],[ 0],[142]] . These are the indices of corresponding points in contours. For eg,
check the first value: cnt[129] = [[234, 202]] which is same as first result (and so on for
others).

You will see it again when we discuss about convexity defects.

6. Checking Convexity
There is a function to check if a curve is convex or not, [Link](). It just return
whether True or False. Not a big deal.

k = [Link](cnt)

7. Bounding Rectangle
There are two types of bounding rectangles.

7.a. Straight Bounding Rectangle

It is a straight rectangle, it doesn’t consider the rotation of the object. So area of the bounding
rectangle won’t be minimum. It is found by the function [Link]().

Let (x,y) be the top-left coordinate of the rectangle and (w,h) be its width and height.

x,y,w,h = [Link](cnt)
img = [Link](img,(x,y),(x+w,y+h),(0,255,0),2)

7.b. Rotated Rectangle

Here, bounding rectangle is drawn with minimum area, so it considers the rotation also. The
function used is [Link](). It returns a Box2D structure which contains following
detals - ( top-left corner(x,y), (width, height), angle of rotation ). But to draw this rectangle, we
need 4 corners of the rectangle. It is obtained by the function [Link]()

rect = [Link](cnt)
box = [Link](rect)
box = np.int0(box)
im = [Link](im,[box],0,(0,0,255),2)
Both the rectangles are shown in a single image. Green rectangle shows the normal bounding
rect. Red rectangle is the rotated rect.

8. Minimum Enclosing Circle


Next we find the circumcircle of an object using the function [Link](). It is a
circle which completely covers the object with minimum area.

(x,y),radius = [Link](cnt)
center = (int(x),int(y))
radius = int(radius)
img = [Link](img,center,radius,(0,255,0),2)

9. Fitting an Ellipse
Next one is to fit an ellipse to an object. It returns the rotated rectangle in which the ellipse is
inscribed.
ellipse = [Link](cnt)
im = [Link](im,ellipse,(0,255,0),2)

10. Fitting a Line


Similarly we can fit a line to a set of points. Below image contains a set of white points. We can
approximate a straight line to it.

rows,cols = [Link][:2]
[vx,vy,x,y] = [Link](cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
img = [Link](img,(cols-1,righty),(0,lefty),(0,255,0),2)

Additional Resources

Exercises

Common questions

Powered by AI

Using a convex hull, generated with cv2.convexHull(), is advantageous when one needs to identify the boundary of the shape that is always convex, which is useful in identifying defects (deviations) in concave shapes. Contour approximation, however, is preferred when the aim is to simplify a contour with fewer vertices while still retaining its shape. Thus, convex hulls are more suited to ensure completeness of shape and to remove concavities, while contour approximation is aimed at reducing complexity .

To fit an ellipse to a contour in OpenCV, first detect the contour using functions like cv2.findContours(). Then, use cv2.fitEllipse() by passing the detected contour to obtain the parameters of the ellipse, which represents a rotated rectangle inscribing the ellipse. Finally, use cv2.ellipse() to draw the fitted ellipse on the image .

Image moments are used to calculate features like the center of mass (centroid) and the area of an object. In OpenCV, the function cv2.moments() computes the moments, providing a dictionary of values. These values can be used to derive the centroid of the contour as cx = int(M['m10']/M['m00']) and cy = int(M['m01']/M['m00']).

The 'epsilon' parameter in contour approximation using the cv2.approxPolyDP() function defines the maximum distance between the original contour and the approximated contour. It is an accuracy parameter that determines the level of simplification; a wise choice of epsilon is necessary to achieve the desired approximation. For example, epsilon = 0.1 times the contour's arc length approximates the contour more loosely, while epsilon = 0.01 leads to a result that is closer to the original shape .

Fitting a straight line to a set of points, using cv2.fitLine(), can be useful in applications such as edge detection, trajectory prediction, or road lane detection in autonomous driving. It simplifies the detected points into a single linear feature, which can then be further analyzed or compared. This technique allows for the reduction of noise and the identification of predominant directional trends in data .

A straight bounding rectangle, calculated using cv2.boundingRect(), aligns with the image axes and therefore does not account for the rotation of the object, resulting in potentially larger area coverage. In contrast, a rotated bounding rectangle, obtained using cv2.minAreaRect(), considers the object's orientation and thus minimizes the enclosing area, providing a tighter fit .

Convexity defects indicate the deviations of a contour from its convex hull, suggesting areas of the contour that bulge inward. They are detected in OpenCV by first creating a convex hull of the contour using cv2.convexHull() with the parameter 'returnPoints' set to False. This returns indices of the contour points corresponding to the convex hull. These indices are then used in conjunction with cv2.convexityDefects() to compute the actual defects, which can highlight features such as inter-finger spaces in hand detection .

Using moments for contour feature extraction offers significant advantages, such as providing precise information about the shape of the object. By calculating spatial moments (e.g., m00, m01), one can easily derive attributes like the area and centroid very accurately. This information is critical for tasks like object recognition and alignment, as it allows for a robust analysis of contour characteristics independent of position and scale in the image .

The Douglas-Peucker algorithm, implemented in OpenCV through the cv2.approxPolyDP() function, is a line simplification algorithm used to approximate a polygonal curve with a smaller number of vertices while maintaining its original shape. It recursively divides the curve into smaller sections and uses the 'epsilon' parameter to control the maximum allowable distance between the original and the simplified curve. This algorithm is crucial for reducing the computational complexity of contours while preserving their structural integrity .

The concept of a minimum enclosing circle, computed using cv2.minEnclosingCircle(), is useful in image processing for tasks that require a compact representation of a region, such as object detection and tracking. It provides a simple yet effective way to encapsulate an object, thus simplifying the analysis and comparison of circular object features. Additionally, it can be used to quickly ascertain if an object lies within a specific radial distance .

You might also like