Shape detection OpenCV

Shape detection is a technique used in image processing and computer vision, that enables us to identify and classify various shapes present within an image. By analyzing the geometric attributes of objects, shape detection forms the basis for numerous applications, including object recognition, industrial automation, and quality assessment.

Here are the steps to detect shapes in your image:

Installing OpenCV

First of all, we need to install OpenCV. We can install it using the following command:

pip install opencv-python

Importing libraries

After installing OpenCV, we will start by importing the necessary libraries:

import cv2
import numpy as np

We import the cv2 for image processing and manipulation and the numpy for array operations.

Preprocessing the image

Next, we need to load the image and preprocess it for better detection. We will convert the image to grayscale and apply Gaussian Blur to reduce noise in the image. Here is a sample code:

image = cv2.imread('image.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)

We load an image using the cv2.imread() and convert it to grayscale using the cv2.cvtColor(). Then we apply Gaussian blur using the cv2.GaussianBlur(). Following is the image that we will be using:

Image having distinct shapes
Image having distinct shapes

Detecting edges

In this step, we will use the Canny edge detection algorithm to detect the edges within the grayscale image. Edge detection highlights the significant transitions in pixel intensity, which often correspond to object boundaries. Here is the usage of the Canny edge detection function:

edges = cv2.Canny(blur, threshold1, threshold2)

We can adjust the threshold1 and threshold2 parameters to control the sensitivity of edge detection.

Finding and analyzing contours

Apply the cv2.findContours() function to identify contours in the edge-detected image. The function returns a list of contours and hierarchy information. Here is the syntax:

contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

We use the _ variable to discard hierarchy data. You can also adjust the second argument (cv2.RETR_EXTERNAL) to specify the contour retrieval mode.

Approximating shapes

To simplify the representation of contours while preserving their core structure, we employ the cv2.approxPolyDP() function. By iteratively approximating the contours, we reduce the number of vertices while retaining the underlying shape’s integrity. These approximated contours will serve as a foundation for subsequent shape classification.

for contour in contours:
epsilon = 0.04 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
cv2.drawContours(image, [approx], 0, (0, 255, 0), 2)

Classifying shapes

This step involves classifying the shapes based on the number of vertices present in the approximated contours. By analyzing the vertex count, we categorize the shapes into various geometric forms, such as triangles, squares, rectangles, pentagons, and circles. The identified shape names are then superimposed onto the original image using the cv2.putText() function.

for contour in contours:
epsilon = 0.04 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
vertices = len(approx)
if vertices == 3:
shape = "Triangle"
elif vertices == 4:
(x, y, w, h) = cv2.boundingRect(approx)
ar = w / float(h)
# A square will have an aspect ratio(ar) that is approximately
# equal to one, otherwise, the shape is a rectangle
shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
elif vertices == 5:
shape = "Pentagon"
else:
shape = "Circle"
cv2.putText(image, shape, (approx[0][0][0], approx[0][0][1]+5), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)

Displaying results

Use the cv2.imshow() to display the original image and the contour image.

cv2.imshow('Shape Detection', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

The cv2.waitKey(0) function waits for a key press before closing windows, and the cv2.destroyAllWindows() closes all windows.

Putting together

By following these steps, the complete code will turn out like this:

import cv2
import numpy as np
# Load and preprocess an Image
image = cv2.imread('image.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# Perform edge detection
edges = cv2.Canny(blur, 30, 150)
# Find contours
contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Classifying shapes
for contour in contours:
epsilon = 0.04 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
vertices = len(approx)
if vertices == 3:
shape = "Triangle"
elif vertices == 4:
(x, y, w, h) = cv2.boundingRect(approx)
ar = w / float(h)
shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
elif vertices == 5:
shape = "Pentagon"
else:
shape = "Circle"
cv2.drawContours(image, [approx], 0, (0, 255, 0), 2)
cv2.putText(image, shape, (approx[0][0][0], approx[0][0][1]+5), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
# Save Results
cv2.imwrite('output/DetectedShapes.png',image)

Conclusion

Shape detection is a technique in computer vision that plays a crucial role in various image analysis tasks. OpenCV simplifies the process by offering tools for shape detection. Furthermore, you can explore more advanced techniques and combine shape detection with machine learning to achieve even more sophisticated results in your projects.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved