Finding Shapes
Once you have found contours, you can classify them as specific shapes (triangle, rectangle, circle) by analysing their geometry.
10 min•By Priygop Team•Updated 2026
Shape Classification
Shape Classification
import cv2
import numpy as np
def classify_shape(contour):
"""Classify a contour as a specific geometric shape."""
shape = "unknown"
# Approximate the contour to a polygon
perimeter = cv2.arcLength(contour, True)
epsilon = 0.04 * perimeter # Approximation accuracy
approx = cv2.approxPolyDP(contour, epsilon, True)
vertices = len(approx)
# Classify by number of vertices
if vertices == 3:
shape = "triangle"
elif vertices == 4:
# Distinguish rectangle from square by aspect ratio
x, y, w, h = cv2.boundingRect(approx)
ratio = w / float(h)
shape = "square" if 0.9 <= ratio <= 1.1 else "rectangle"
elif vertices == 5:
shape = "pentagon"
elif vertices == 6:
shape = "hexagon"
else:
# Many vertices = probably a circle
area = cv2.contourArea(contour)
(cx, cy), radius = cv2.minEnclosingCircle(contour)
circle_area = np.pi * radius ** 2
if area / circle_area > 0.85:
shape = "circle"
else:
shape = f"polygon ({vertices} sides)"
return shape
image = cv2.imread("shapes.jpg") # Use an image with clear shapes
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
result = image.copy()
for contour in contours:
if cv2.contourArea(contour) > 500:
shape = classify_shape(contour)
M = cv2.moments(contour)
if M["m00"] != 0:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
cv2.putText(result, shape, (cx-30, cy),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
cv2.drawContours(result, [contour], -1, (0,255,0), 2)
cv2.imwrite("shapes_detected.jpg", result)
print("Shape detection complete")Diagram
Loading diagram…
Machine Learning follows a structured pipeline from data to deployment