Block 1: Import Libraries
import numpy as np
To kickstart our shape detection algorithm, we begin by importing essential libraries. The `cv2` library is the powerful OpenCV tool that provides us with various computer vision functions. In conjunction, we use the versatile `numpy` library (as `np`) for numerical computations and array manipulations, complementing the functionality of OpenCV.
Block 2: Load and Preprocess the Image
image = cv2.imread(image_path)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 0)
return image, blurred_image
We believe in effective preprocessing as a key step in image analysis. In this block, our `preprocess_image` function loads the input image and applies crucial preprocessing steps. We use `cv2.imread` to read the image, followed by converting it to grayscale using `cv2.cvtColor`. This step simplifies the subsequent shape detection process. We then employ `cv2.GaussianBlur` to reduce noise and smoothen the image, leading to better contours during shape detection.
Block 3: Detect Contours
edges = cv2.Canny(blurred_image, 50, 150)
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
To identify candy shapes accurately, we must find their contours. Our `detect_contours` function plays a crucial role in this task. We leverage the Canny edge detection algorithm, available through `cv2.Canny`, to detect edges in the preprocessed image. This edge information is then utilized by `cv2.findContours` to locate and extract contours from the image. The function returns a list of contours, which serves as the foundation for our shape detection.
Block 4: Shape Detection
def detect_shapes(image, contours):
detected_shapes = 
for contour in contours:
perimeter = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.04 * perimeter, True)
if len(approx) == 3:
shape_name = "Triangle"
elif len(approx) == 4:
x, y, w, h = cv2.boundingRect(approx)
aspect_ratio = float(w) / h
if 0.95 <= aspect_ratio <= 1.05:
shape_name = "Square"
shape_name = "Rectangle"
elif len(approx) == 5:
shape_name = "Pentagon"
shape_name = "Circle"
Our `detect_shapes` function takes the preprocessed image and the list of contours as inputs to identify and classify the shapes of candies. We use the `cv2.arcLength` function to calculate the perimeter of each contour. Utilizing the `cv2.approxPolyDP` function, we approximate each contour's shape by reducing the number of vertices while preserving the overall structure. Based on the number of vertices after approximation, we categorize the shape as a Triangle, Square, Rectangle, Pentagon, or Circle.
Block 5: Main Function
if __name__ == "__main__":
image_path = "path/to/your/image.jpg"
image, blurred_image = preprocess_image(image_path)
contours = detect_contours(blurred_image)
detected_shapes = detect_shapes(image, contours)
for shape_name, contour in detected_shapes:
cv2.drawContours(image, [contour], 0, (0, 255, 0), 2)
cv2.putText(image, shape_name, (contour, contour), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("Detected Shapes", image)
In our main function, we bring all the previous blocks together to detect and visualize candy shapes. As a user, you can replace `"path/to/your/image.jpg"` with the actual path to your input image. The program will then preprocess the image, detect the shapes, draw contours around the candies, and label each shape with its name. The image with the detected shapes will be displayed, and the program will wait for a key press before closing the window.
By following this guide, you have successfully configured an image detector in Python to identify different shapes of candies. Computer vision techniques offer powerful solutions for shape detection, opening up possibilities for various applications beyond candies. Understanding these concepts can be instrumental in solving real-world problems and unleashing your creativity.