0
# Contour Detection and Shape Analysis
1
2
OpenCV provides a comprehensive suite of functions for detecting contours in binary images and analyzing their geometric properties. Contours are curves that join continuous points along a boundary, representing the outline of objects in images. These tools are essential for object detection, shape recognition, and image segmentation tasks.
3
4
## Capabilities
5
6
### Contour Detection
7
8
Find and draw contours in binary images. Contours are typically found after edge detection or thresholding operations.
9
10
```python { .api }
11
cv2.findContours(image, mode, method) -> contours, hierarchy
12
```
13
Finds contours in a binary image.
14
15
**Parameters:**
16
- `image` (ndarray): Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's, zero pixels remain 0's.
17
- `mode` (int): Contour retrieval mode (see constants below).
18
- `method` (int): Contour approximation method (see constants below).
19
20
**Returns:**
21
- `contours` (list): List of contours found. Each contour is a NumPy array of (x,y) coordinates of boundary points.
22
- `hierarchy` (ndarray): Optional output vector containing information about the image topology. It has as many elements as the number of contours.
23
24
```python { .api }
25
cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None) -> image
26
```
27
Draws contours outlines or filled contours on an image.
28
29
**Parameters:**
30
- `image` (ndarray): Destination image.
31
- `contours` (list): All the input contours. Each contour is stored as a point vector.
32
- `contourIdx` (int): Parameter indicating a contour to draw. If it is negative, all the contours are drawn.
33
- `color` (tuple): Color of the contours (BGR format).
34
- `thickness` (int, optional): Thickness of lines the contours are drawn with. If negative (e.g., -1), the contour interiors are drawn. Default is 1.
35
- `lineType` (int, optional): Line connectivity. See `cv2.LINE_4`, `cv2.LINE_8`, `cv2.LINE_AA`.
36
- `hierarchy` (ndarray, optional): Optional information about hierarchy. Only needed if you want to draw only some of the contours.
37
- `maxLevel` (int, optional): Maximal level for drawn contours. If 0, only the specified contour is drawn. If 1, the function draws the contour and all nested contours. If 2, the function draws the contours, all nested contours, and so on.
38
- `offset` (tuple, optional): Optional contour shift parameter. Shift all the drawn contours by the specified offset=(dx,dy).
39
40
**Returns:**
41
- `image` (ndarray): The modified image with contours drawn.
42
43
**Contour Retrieval Modes:**
44
45
```python { .api }
46
cv2.RETR_EXTERNAL
47
```
48
Retrieves only the extreme outer contours. It sets `hierarchy[i][2]=hierarchy[i][3]=-1` for all contours.
49
50
```python { .api }
51
cv2.RETR_LIST
52
```
53
Retrieves all contours without establishing any hierarchical relationships.
54
55
```python { .api }
56
cv2.RETR_CCOMP
57
```
58
Retrieves all contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level.
59
60
```python { .api }
61
cv2.RETR_TREE
62
```
63
Retrieves all contours and reconstructs a full hierarchy of nested contours.
64
65
**Contour Approximation Methods:**
66
67
```python { .api }
68
cv2.CHAIN_APPROX_NONE
69
```
70
Stores absolutely all the contour points. This means no approximation - every point on the contour boundary is stored.
71
72
```python { .api }
73
cv2.CHAIN_APPROX_SIMPLE
74
```
75
Compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points.
76
77
```python { .api }
78
cv2.CHAIN_APPROX_TC89_L1
79
```
80
Applies one of the flavors of the Teh-Chin chain approximation algorithm using the L1 distance metric.
81
82
```python { .api }
83
cv2.CHAIN_APPROX_TC89_KCOS
84
```
85
Applies one of the flavors of the Teh-Chin chain approximation algorithm using the cosine metric.
86
87
### Contour Properties
88
89
Calculate basic properties of contours such as area, perimeter, and convexity.
90
91
```python { .api }
92
cv2.contourArea(contour, oriented=None) -> area
93
```
94
Calculates a contour area.
95
96
**Parameters:**
97
- `contour` (ndarray): Input vector of 2D points (contour vertices).
98
- `oriented` (bool, optional): Oriented area flag. If True, the function returns a signed area value, depending on the contour orientation (clockwise or counter-clockwise). Using this feature, you can determine the orientation of a contour by taking the sign of the area. Default is False.
99
100
**Returns:**
101
- `area` (float): Area enclosed by the contour in pixels.
102
103
```python { .api }
104
cv2.arcLength(curve, closed) -> perimeter
105
```
106
Calculates a contour perimeter or a curve length.
107
108
**Parameters:**
109
- `curve` (ndarray): Input vector of 2D points.
110
- `closed` (bool): Flag indicating whether the curve is closed.
111
112
**Returns:**
113
- `perimeter` (float): Length of the curve in pixels.
114
115
```python { .api }
116
cv2.isContourConvex(contour) -> bool
117
```
118
Tests a contour convexity.
119
120
**Parameters:**
121
- `contour` (ndarray): Input vector of 2D points.
122
123
**Returns:**
124
- `bool`: True if the contour is convex, False otherwise.
125
126
### Contour Approximation
127
128
Approximate contours to simpler shapes with fewer vertices.
129
130
```python { .api }
131
cv2.approxPolyDP(curve, epsilon, closed) -> approxCurve
132
```
133
Approximates a polygonal curve with the specified precision using the Douglas-Peucker algorithm.
134
135
**Parameters:**
136
- `curve` (ndarray): Input vector of 2D points stored in NumPy array.
137
- `epsilon` (float): Parameter specifying the approximation accuracy. This is the maximum distance between the original curve and its approximation. Typically, epsilon = 0.01 to 0.1 * perimeter.
138
- `closed` (bool): If True, the approximated curve is closed (its first and last vertices are connected). Otherwise, it is not closed.
139
140
**Returns:**
141
- `approxCurve` (ndarray): Result of the approximation. The type should match the type of the input curve.
142
143
```python { .api }
144
cv2.convexHull(points, hull=None, clockwise=None, returnPoints=None) -> hull
145
```
146
Finds the convex hull of a point set.
147
148
**Parameters:**
149
- `points` (ndarray): Input 2D point set, stored in NumPy array.
150
- `hull` (ndarray, optional): Output convex hull. It is either an array of indices of the hull points or an array of the hull points themselves.
151
- `clockwise` (bool, optional): Orientation flag. If True, the output convex hull is oriented clockwise. Otherwise, it is oriented counter-clockwise. Default is False.
152
- `returnPoints` (bool, optional): Operation flag. If True, the function returns convex hull points. Otherwise, it returns indices of the convex hull points. Default is True.
153
154
**Returns:**
155
- `hull` (ndarray): Output convex hull as an array of points or indices.
156
157
### Bounding Shapes
158
159
Calculate various bounding shapes around contours for object localization and orientation detection.
160
161
```python { .api }
162
cv2.boundingRect(array) -> (x, y, width, height)
163
```
164
Calculates the up-right bounding rectangle of a point set or non-zero pixels of gray-scale image.
165
166
**Parameters:**
167
- `array` (ndarray): Input gray-scale image or 2D point set.
168
169
**Returns:**
170
- `x` (int): X-coordinate of the top-left corner of the bounding rectangle.
171
- `y` (int): Y-coordinate of the top-left corner of the bounding rectangle.
172
- `width` (int): Width of the bounding rectangle.
173
- `height` (int): Height of the bounding rectangle.
174
175
```python { .api }
176
cv2.minAreaRect(points) -> ((center_x, center_y), (width, height), angle)
177
```
178
Finds a rotated rectangle of the minimum area enclosing the input 2D point set.
179
180
**Parameters:**
181
- `points` (ndarray): Input vector of 2D points.
182
183
**Returns:**
184
- `center` (tuple): Center of the rectangle as (center_x, center_y).
185
- `size` (tuple): Size of the rectangle as (width, height).
186
- `angle` (float): Rotation angle in degrees. The angle is measured in a clockwise direction with respect to the horizontal axis. Values range from -90 to 0 degrees.
187
188
```python { .api }
189
cv2.minEnclosingCircle(points) -> ((center_x, center_y), radius)
190
```
191
Finds a circle of the minimum area enclosing a 2D point set.
192
193
**Parameters:**
194
- `points` (ndarray): Input vector of 2D points.
195
196
**Returns:**
197
- `center` (tuple): Center of the circle as (center_x, center_y).
198
- `radius` (float): Radius of the circle.
199
200
```python { .api }
201
cv2.minEnclosingTriangle(points) -> retval, triangle
202
```
203
Finds a triangle of minimum area enclosing a 2D point set and returns its area.
204
205
**Parameters:**
206
- `points` (ndarray): Input vector of 2D points.
207
208
**Returns:**
209
- `retval` (float): Area of the minimum enclosing triangle.
210
- `triangle` (ndarray): Output vector of three 2D points defining the vertices of the triangle.
211
212
```python { .api }
213
cv2.boxPoints(box) -> points
214
```
215
Finds the four vertices of a rotated rectangle. Useful for drawing rotated rectangles from minAreaRect output.
216
217
**Parameters:**
218
- `box` (tuple): Rotated rectangle as returned by minAreaRect: ((center_x, center_y), (width, height), angle).
219
220
**Returns:**
221
- `points` (ndarray): Array of four points (4x2 float32 array), one for each vertex of the rotated rectangle.
222
223
```python { .api }
224
cv2.fitEllipse(points) -> ((center_x, center_y), (width, height), angle)
225
```
226
Fits an ellipse around a set of 2D points.
227
228
**Parameters:**
229
- `points` (ndarray): Input vector of 2D points. Must have at least 5 points.
230
231
**Returns:**
232
- `center` (tuple): Center of the ellipse as (center_x, center_y).
233
- `axes` (tuple): Length of the ellipse axes as (major_axis, minor_axis).
234
- `angle` (float): Rotation angle of the ellipse in degrees.
235
236
```python { .api }
237
cv2.fitLine(points, distType, param, reps, aeps) -> line
238
```
239
Fits a line to a 2D or 3D point set.
240
241
**Parameters:**
242
- `points` (ndarray): Input vector of 2D or 3D points.
243
- `distType` (int): Distance used by the M-estimator (e.g., `cv2.DIST_L2`, `cv2.DIST_L1`, `cv2.DIST_L12`, `cv2.DIST_FAIR`, `cv2.DIST_WELSCH`, `cv2.DIST_HUBER`).
244
- `param` (float): Numerical parameter (C) for some types of distances. If it is 0, an optimal value is chosen.
245
- `reps` (float): Sufficient accuracy for the radius (distance between the coordinate origin and the line).
246
- `aeps` (float): Sufficient accuracy for the angle. 0.01 would be a good default value.
247
248
**Returns:**
249
- `line` (ndarray): Output line parameters. For 2D fitting, it contains (vx, vy, x0, y0) where (vx, vy) is a normalized vector collinear to the line and (x0, y0) is a point on the line. For 3D fitting, it contains (vx, vy, vz, x0, y0, z0).
250
251
### Shape Moments
252
253
Calculate image moments for shape analysis and feature extraction. Moments are weighted averages of image pixel intensities.
254
255
```python { .api }
256
cv2.moments(array, binaryImage=None) -> moments_dict
257
```
258
Calculates all of the moments up to the third order of a polygon or rasterized shape.
259
260
**Parameters:**
261
- `array` (ndarray): Raster image (single-channel, 8-bit or floating-point 2D array) or an array of 2D points (contour vertices).
262
- `binaryImage` (bool, optional): If True, all non-zero image pixels are treated as 1's. Default is False.
263
264
**Returns:**
265
- `moments_dict` (dict): Dictionary containing spatial moments (m00, m10, m01, m20, m11, m02, m30, m21, m12, m03), central moments (mu20, mu11, mu02, mu30, mu21, mu12, mu03), and normalized central moments (nu20, nu11, nu02, nu30, nu21, nu12, nu03).
266
267
**Notable moment values:**
268
- `m00`: Area (for binary images) or sum of pixel intensities
269
- `m10/m00` and `m01/m00`: Centroid coordinates (center of mass)
270
271
```python { .api }
272
cv2.HuMoments(moments) -> hu
273
```
274
Calculates seven Hu invariants from spatial moments.
275
276
**Parameters:**
277
- `moments` (dict): Input moments computed with `cv2.moments()`.
278
279
**Returns:**
280
- `hu` (ndarray): Output Hu invariants as a 7x1 array. These values are invariant to translation, scale, and rotation, making them useful for shape matching.
281
282
### Shape Comparison
283
284
Compare shapes using contour matching to determine similarity between different contours.
285
286
```python { .api }
287
cv2.matchShapes(contour1, contour2, method, parameter) -> similarity
288
```
289
Compares two shapes using Hu moments.
290
291
**Parameters:**
292
- `contour1` (ndarray): First contour or grayscale image.
293
- `contour2` (ndarray): Second contour or grayscale image.
294
- `method` (int): Comparison method. One of:
295
- `cv2.CONTOURS_MATCH_I1`: I1 = sum_i |1/m_i^A - 1/m_i^B|
296
- `cv2.CONTOURS_MATCH_I2`: I2 = sum_i |m_i^A - m_i^B|
297
- `cv2.CONTOURS_MATCH_I3`: I3 = max_i |m_i^A - m_i^B| / |m_i^A|
298
- `parameter` (float): Method-specific parameter (not supported now, use 0).
299
300
**Returns:**
301
- `similarity` (float): Similarity measure. A value of 0 indicates a perfect match, while higher values indicate greater dissimilarity.
302
303
### Point Tests
304
305
Test spatial relationships between points and contours.
306
307
```python { .api }
308
cv2.pointPolygonTest(contour, pt, measureDist) -> result
309
```
310
Performs a point-in-contour test.
311
312
**Parameters:**
313
- `contour` (ndarray): Input contour.
314
- `pt` (tuple): Point tested against the contour as (x, y).
315
- `measureDist` (bool): If True, the function estimates the signed distance from the point to the nearest contour edge. If False, the function only checks if the point is inside, outside, or on the edge.
316
317
**Returns:**
318
- `result` (float):
319
- If `measureDist=False`: Returns +1 (inside), -1 (outside), or 0 (on edge).
320
- If `measureDist=True`: Returns the signed distance. Positive for inside, negative for outside, zero for on edge.
321