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 cv2import 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:
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 rectangleshape = "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 cv2import numpy as np# Load and preprocess an Imageimage = cv2.imread('image.png')gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)blur = cv2.GaussianBlur(gray, (5, 5), 0)# Perform edge detectionedges = cv2.Canny(blur, 30, 150)# Find contourscontours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# Classifying shapesfor 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 Resultscv2.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