Requirements:
- Python3
- pip3
- OpenCV
- input image⇒ [for testing]
# importing the library OpenCV
import cv2
# reading image
img = cv2.imread('shapes.png')
# converting image into grayscale image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# setting threshold of gray image
_, threshold = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# using a findContours() function
contours, _ = cv2.findContours(
threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
i = 0
# list for storing names of shapes
for contour in contours:
# here we are ignoring first counter because
# findcontour function detects whole image as shape
if i == 0:
i = 1
continue
# cv2.approxPloyDP() function to approximate the shape
approx = cv2.approxPolyDP(
contour, 0.01 * cv2.arcLength(contour, True), True)
# using drawContours() function
cv2.drawContours(img, [contour], 0, (60, 20, 220), 5)
# finding center point of shape
M = cv2.moments(contour)
if M['m00'] != 0.0:
x = int(M['m10']/M['m00'])
y = int(M['m01']/M['m00'])
# putting shape name at center of each shape
if len(approx) == 3:
cv2.putText(img, 'Triangle', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2)
elif len(approx) == 4:
cv2.putText(img, 'Quadrilateral', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2)
elif len(approx) == 5:
cv2.putText(img, 'Pentagon', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2)
elif len(approx) == 6:
cv2.putText(img, 'Hexagon', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2)
elif len(approx) == 10:
cv2.putText(img, 'Star', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2)
else:
cv2.putText(img, 'circle', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2)
# displaying the image after drawing contours
cv2.imshow('shapes', img)
cv2.imwrite('detected_shapes.png', img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
Input image I used:
Output image it creates:
This code need some improvement to detect other shapes like the Oval or ellipse.
More specific quadrilaterals shapes like square, rectangle, kite, and rhombus.
shape detection OpenCV.zip258.9KB