How to detect shapes using cv2 — with source code— Easy Project

In today’s blog, we will see how we can detect shapes using cv2 in an image using contours and moments. This is going to be a very fun project, so without any further due.

Read the full article with source code here — https://machinelearningprojects.net/detect-shapes-using-cv2/

Let’s do it…

Code for how to detect shapes using cv2…

import cv2
import numpy as np

img = cv2.imread('someshapes.jpg')
cv2.imshow('1. original image', img)
cv2.waitKey(0)

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('2. gray image', gray_img)
cv2.waitKey(0)

edges = cv2.Canny(gray_img, 50, 200)
cv2.imshow('3. edges', edges)
cv2.waitKey(0)

contours, hierarchy = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for cnt in contours:

approx = cv2.approxPolyDP(cnt, 0.03*cv2.arcLength(cnt, True), True)
print(len(approx))
# detect shapes using cv2
if len(approx) == 3:
shape = 'Triangle'
M = cv2.moments(approx)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])

elif len(approx) == 4:
x, y, w, h = cv2.boundingRect(cnt)
if abs(w-h) < 5:
shape = 'Square'
M = cv2.moments(approx)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
else:
shape = 'Rectangle'
M = cv2.moments(approx)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])

elif len(approx) == 10:
shape = 'Star'
M = cv2.moments(approx)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])

elif len(approx) == 8:
shape = 'Circle'
M = cv2.moments(approx)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])

cv2.putText(img, shape, (cx-30, cy),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 1)

cv2.drawContours(img, cnt, -1, (0, 255, 0), 2)

cv2.imshow('cnt', img)
cv2.destroyAllWindows()
  • Line 1–2 — Importing required libraries.
  • Line 4–6 — Show the input image, till someone hits any key.
  • Line 8–10 — Convert the image to grayscale and show the image.

NOTE — Our input image and the grayscale image will look similar because our input image already didn’t have colors but it still had 3 channels (RGB), that’s why we still need to convert it to grayscale to bring it down to 1 channel.

  • Line 12 -14 — Detect edges from the gray image, and show them.
  • Line 16 — Detect contours from the image with edges.
  • Line 18 — Let’s traverse in contours.
  • Line 20 — Calculate the number of lines in contours using cv2.approxPolyDP() and let’s detect shapes using cv2.
  • Line 23–27 — If no. of lines equals 3, then it’s a triangle.
  • Line 29–40 — If the no. of lines equals 4 then it’s either a rectangle or a square.
  • Line 31–35 — If the difference between height and width is less than 5 pixels, then there’s a very negligible difference in width and height, it’s a square.
  • Line 36–40 — Else it’s a rectangle.
  • Line 42–46 — If no. of lines equal 10, it’s a star.
  • Line 48–52 — If no. of lines equal 8, it’s a circle.
  • Line 54 — Put the text in the center of every detected contour. We calculated the center coordinates of every contour using moments.
  • Line 56 — Draw the contours and show the image.
  • Line 58 — Show the output image.
  • Line 59 — Destroy all the open windows.

Final results…

Do let me know if there’s any query regarding detecting shapes using cv2 by contacting me on email or LinkedIn.

For further code explanation and source code visit here https://machinelearningprojects.net/detect-shapes-using-cv2/

So this is all for this blog folks, thanks for reading it and I hope you are taking something with you after reading this and till the next time 👋…

Read my previous post: MAKE YOUR SKETCH USING OPENCV IN PYTHON

Check out my other machine learning projects, deep learning projects, computer vision projects, NLP projects, Flask projects at machinelearningprojects.net.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store