Skip to main content

Contour Detection

Introduction

This section teaches how to use OpenCV for image contour detection. Contours refer to the edge lines of shapes or objects in an image.

Experiment Objective

Detect image contours and draw them for display.

Experiment Explanation

The OpenCV Python library provides the findContours() function for finding contours and the drawContours() function for drawing contours.

findContours() Usage

contours, hierarchy = cv2.findContours(image, mode, method)

Finds edge coordinates in an image. Returns contours as a list of contour point coordinates and hierarchy representing the hierarchical relationships.

  • image: 8-bit single-channel binary image.
  • mode: Detection mode.
    • cv2.RETR_EXTERNAL: Only detect outer contours.
    • cv2.RETR_LIST: Detect all contours without establishing hierarchical relationships.
    • cv2.RETR_CCOMP: Detect all contours and establish 2-level hierarchical relationships.
    • cv2.RETR_TREE: Detect all contours and establish tree-like hierarchical relationships.
  • method: Detection method.
    • cv2.CHAIN_APPROX_NONE: Save all contour points.
    • cv2.CHAIN_APPROX_SIMPLE: Only save the endpoints of horizontal, vertical, or diagonal contours.

drawContours() Usage

img = cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset)

Draws contours.

  • image: Original image.
  • contours: The list obtained from findContours().
  • contourIdx: Indexing method; -1 means draw all contours.
  • color: Color.
  • thickness: Thickness; -1 means filled.
  • lineType: Contour line type (optional).
  • hierarchy: Hierarchical relationship obtained from findContours() (optional).
  • maxLevel: Depth of hierarchy (optional).
  • offset: Offset to change the position of the drawn result (optional).

Here we can draw a filled circle and a filled rectangle, then binarize the image, find the contours, and draw them. The code flow is as follows:


The reference code is as follows:

'''
Experiment Name: Contour Detection
Experiment Platform: WalnutPi 1B
'''

import cv2
import numpy as np

# Create a new 300×300 pixel RGB888 pure white image
img = np.ones((300,300,3),np.uint8)*255

# Draw a blue filled circle on img0
img0 = cv2.circle(img, (100, 100), 50, (255,0,0), -1)

# Draw a red filled rectangle
img = cv2.rectangle(img0, (150, 150), (250, 250), (0,0,255), -1)

cv2.imshow('color', img) # Display the image

# Convert the color image to a grayscale image (single channel)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', img) # Display the image

# Convert the grayscale image to a binary image
t,img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('binary', img) # Display the image

# Detect contours
contours, hierarchy = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

# Draw contours on the original image img0 in green
img = cv2.drawContours(img0, contours, -1, (0,255,0), 5)
cv2.imshow('contours', img) # Display the image

cv2.waitKey() # Wait for any keyboard key to be pressed
cv2.destroyAllWindows() # Close the window

Experiment Results

Run the above code on the WalnutPi, and you can see the transformation process of the experimental images. The final contour drawing result is shown below:

contour_detection1

Extension

Let's use lenna.jpg to draw contours and observe the result. The code is as follows:

'''
Experiment Name: Contour Detection 2
Experiment Platform: WalnutPi 1B
'''
import cv2
import numpy as np

img0 = cv2.imread('lenna.jpg') # Read the image for original observation
cv2.imshow('lenna', img0) # Display the image

img = cv2.imread('lenna.jpg',0) # Get the grayscale image
cv2.imshow('gray', img) # Display the grayscale image

# Convert the grayscale image to a binary image
t,img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('binary', img) # Display the binary image

# Detect contours
contours, hierarchy = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

# Draw contours on the original image img0
img = cv2.drawContours(img0, contours, -1, (0,255,0), 5)
cv2.imshow('contours', img) # Display the contour image

cv2.waitKey() # Wait for any keyboard key to be pressed
cv2.destroyAllWindows() # Close the window

The experiment results are as follows:

contour_detection1