8
Contours
Although algorithms like the Canny edge detector can be used to find the edge pixels that separate different
segments in an image, they do not tell you anything about those edges as entities in themselves. The next
step is to be able to assemble those edge pixels into contours. By now you have probably come to expect
that there is a convenient function in OpenCV that will do exactly this for you, and indeed there is:
cv::findContours(). We will start out this chapter with some basics that we will need in order to use
this function.. With those concepts in hand, we will get into contour finding in some detail. Thereafter, we
will move on to the many things we can do with contours after they’ve been computed.
Contour Finding
A contour is a list of points that represent, in one way or another, a curve in an image. This representation
can be different depending on the circumstance at hand. There are many ways to represent a curve.
Contours are represented in OpenCV by STL style vector<> template objects in which every entry in the
vector encodes information about the location of the next point on the curve. It should be noted that though
a sequence of 2d points (vector<cv::Point> or vector<cv::Point2f>) is the most common
representation, there are other ways to represent contours as well. One example of such a construct is the
Freeman Chain, in which each point is represented as a particular “step” in a given direction from the prior
point. We will get into such variations in more detail as we encounter them. For now, the important thing to
know is that contours are almost always STL vectors, but are not necessarily limited to the obvious vectors
of cv::Point objects.
The function cv::findContours() computes contours from binary images. It can take images created
by cv::Canny(), which have edge pixels in them, or images created by functions like
cv::threshold() or cv::adaptiveThreshold(), in which the edges are implicit as boundaries
between positive and negative regions.
1
Contour Hierarchies
Before getting down to exactly how to extract contours, it is worth taking a moment to understand exactly
what a contour is, and how groups of contours can be related to one another. Of particular interest is the
concept of a contour tree, which is important for understanding one of the most useful ways
1
There are some subtle differences between passing edge images and binary images to cvFindContours(); we
will discuss those shortly.
cv::findContours() (retrieval methods derive from Suzuki [Suzuki85]) can communicate its results
to us.
Take a moment to look at
Figure 8-1, which depicts the functionality of cv::findContours(). The upper part of the figure
shows a test image containing a number of “colored” (here, gray) regions (labeled A through E) on a light
background. The lower portion of the figure depicts the same image along with the contours that will be
located by cv::findContours(). Those contours are labeled cX or hX, where “c” stands for
“contour,” “h” stands for “hole,” and “X” is some number. OpenCV and cv::findContours()
distinguishes between the exterior boundaries of non-zero regions which are labeled contours and the
interior
boundaries which are labeled holes.

Get Learning OpenCV, 2nd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.