Practical Shape Detection Project
Build a complete shape detection system that finds all shapes in an image, classifies them, and reports their properties.
12 min•By Priygop Team•Updated 2026
Complete Shape Analysis
Complete Shape Analysis
import cv2
import numpy as np
def full_shape_analysis(image_path):
"""Complete pipeline: load → process → detect → classify → report."""
image = cv2.imread(image_path)
if image is None:
print(f"Could not load: {image_path}")
return
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
_, binary = cv2.threshold(blurred, 0, 255,
cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
contours, _ = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
print(f"=== Shape Analysis: {image_path} ===")
print(f"Total contours found: {len(contours)}")
result = image.copy()
shapes_found = {}
for contour in contours:
area = cv2.contourArea(contour)
if area < 500:
continue # Skip tiny noise
# Classify shape
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.04 * peri, True)
n = len(approx)
if n == 3: shape = "Triangle"
elif n == 4:
x,y,w,h = cv2.boundingRect(approx)
ratio = w / float(h)
shape = "Square" if 0.9 <= ratio <= 1.1 else "Rectangle"
elif n == 5: shape = "Pentagon"
elif n == 6: shape = "Hexagon"
else:
(cx,cy),r = cv2.minEnclosingCircle(contour)
shape = "Circle" if area / (np.pi*r*r) > 0.8 else "Polygon"
shapes_found[shape] = shapes_found.get(shape, 0) + 1
# Draw and label
M = cv2.moments(contour)
if M["m00"] > 0:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
cv2.drawContours(result, [contour], -1, (0,255,0), 2)
cv2.putText(result, shape, (cx-30, cy),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)
print("Shapes detected:", shapes_found)
cv2.imwrite("shape_analysis.jpg", result)
return shapes_found
full_shape_analysis("shapes_image.jpg")Diagram
Loading diagram…
Machine Learning follows a structured pipeline from data to deployment
Key Takeaways from Module 5
- An edge is a sharp change in pixel intensity — the boundary between light and dark regions
- Canny is the most reliable edge detector: use GaussianBlur first, then Canny with a 1:2 threshold ratio
- Contours are closed curves that follow object boundaries — found with cv2.findContours()
- Classify shapes by approximating contours with cv2.approxPolyDP() and counting vertices
- Hough transforms detect lines (cv2.HoughLinesP) and circles (cv2.HoughCircles) mathematically
- Feature points (keypoints) mark distinctive locations used for image matching and tracking
- ORB is the best free-to-use feature detector — fast and works for most CV applications
Key Takeaways
- Build a complete shape detection system that finds all shapes in an image, classifies them, and reports their properties.
- An edge is a sharp change in pixel intensity — the boundary between light and dark regions
- Canny is the most reliable edge detector: use GaussianBlur first, then Canny with a 1:2 threshold ratio
- Contours are closed curves that follow object boundaries — found with cv2.findContours()