How to Find Contours in OpenCV for Computer Vision
To find contours in OpenCV, use the
cv2.findContours() function on a binary image. This function returns contours and their hierarchy, which you can use to analyze shapes or objects in the image.Syntax
The basic syntax of cv2.findContours() is:
image: A binary image (usually after thresholding or edge detection).mode: Contour retrieval mode (e.g.,cv2.RETR_EXTERNALto get only outer contours).method: Contour approximation method (e.g.,cv2.CHAIN_APPROX_SIMPLEto compress horizontal, vertical, and diagonal segments).
The function returns contours and hierarchy information.
python
contours, hierarchy = cv2.findContours(image, mode, method)
Example
This example shows how to load an image, convert it to grayscale, apply thresholding to get a binary image, find contours, and draw them on the original image.
python
import cv2 # Load image img = cv2.imread('shapes.png') # Convert to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Apply binary threshold _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # Find contours contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Draw contours on the original image cv2.drawContours(img, contours, -1, (0, 255, 0), 3) # Save the result image cv2.imwrite('contours_output.png', img) # Print number of contours found print(f'Number of contours found: {len(contours)}')
Output
Number of contours found: 3
Common Pitfalls
- Passing a non-binary image to
cv2.findContours()will not work correctly; always threshold or edge-detect first. - OpenCV versions before 4.0 return three values from
findContours(), but newer versions return two; use unpacking accordingly. - Using the wrong contour retrieval mode can miss inner contours or hierarchy details.
python
import cv2 # Wrong: Using a color image directly img = cv2.imread('shapes.png') contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # This will fail or give wrong results # Right: Convert to grayscale and threshold first gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Quick Reference
| Parameter | Description | Common Values |
|---|---|---|
| image | Binary image to find contours on | Thresholded or edge-detected image |
| mode | Contour retrieval mode | cv2.RETR_EXTERNAL, cv2.RETR_LIST, cv2.RETR_TREE |
| method | Contour approximation method | cv2.CHAIN_APPROX_NONE, cv2.CHAIN_APPROX_SIMPLE |
| returns | Contours and hierarchy | List of contours, hierarchy array |
Key Takeaways
Always use a binary image (thresholded or edge-detected) as input to cv2.findContours().
Use cv2.RETR_EXTERNAL to get only outer contours or cv2.RETR_TREE for full hierarchy.
cv2.CHAIN_APPROX_SIMPLE reduces contour points to save memory without losing shape.
Check OpenCV version for correct unpacking of findContours() return values.
Draw contours with cv2.drawContours() to visualize detected shapes.