In this video tutorial we’re going to see how to detect shapes of geometric figures (like rectangles, triangles and circles) in a live video.
We can detect shapes in real time in this three simple steps:
- Detect the objects, removing the background.
- Find the contours of the objects detected.
- Detect the shape of each of the objects detected, in real time.
1) Detect the objects
Detecting correctly the objects is a crucial part of this project, as If we would like to find their shapes we need to know exactly their boundaries.
It’s possible to use different approaches to detect an object, but as it’s not the goal of this project, we will use a really simple method so mostly we can focuso on the detection of its shape.
If you would like to know more about Color Detection, you can read here the tutorial.
We start by importing the libraries Opencv and Numpy, we create a function nothing that we need later and we load the camera.
import cv2
import numpy as np
def nothing(x):
# any operation
pass
cap = cv2.VideoCapture(1)
We create the trackbars in order to change the ranges to detect a specific color in real time.
I will skip the creation part of the trackbars in this code, if you want to know more about trackbars and color detection, check this article
lower_red = np.array([l_h, l_s, l_v]) upper_red = np.array([u_h, u_s, u_v]) mask = cv2.inRange(hsv, lower_red, upper_red) kernel = np.ones((5, 5), np.uint8) mask = cv2.erode(mask, kernel)
2) Find contours
Second step once we detected the objects by their colors, we need to find the contours.
If you want to know more about contours, check this article.
Bear in mind that the function to detect contour is different depending on the opencv version you’re using.
Find contours on Opencv 3.x.x
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
Find contours on Opencv 4.x.x
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
3) Detect Shapes
If we consider a contour as a polygon which exactly sorrounds the object, getting its shape, the shape detection is a simple counting of how many points the contour has.
We need to remove as much noise as possible in order to have a clean contour.
So we use the approximation function on line 50.
area = cv2.contourArea(cnt) approx = cv2.approxPolyDP(cnt, 0.02*cv2.arcLength(cnt, True), True) x = approx.ravel()[0] y = approx.ravel()[1]
Later we improve even more the detection, removing all the small dots detected, which are just noise.
We do that by taking contour which have a big area, in this case greater than 400 pixels.
And finally we count the lenght of the contours.
If a contour has 3 points is a triangle, 4 points a rectangle and between 10 and 20 points a circle.
if area > 400:
cv2.drawContours(frame, [approx], 0, (0, 0, 0), 5)
if len(approx) == 3:
cv2.putText(frame, "Triangle", (x, y), font, 1, (0, 0, 0))
elif len(approx) == 4:
cv2.putText(frame, "Rectangle", (x, y), font, 1, (0, 0, 0))
elif 10 < len(approx) < 20:
cv2.putText(frame, "Circle", (x, y), font, 1, (0, 0, 0))

Hi there, I’m the founder of Pysource.
I’m a Computer Vision Consultant, developer and Course instructor.
I help Companies and Developers to build efficient computer vision software.
Thanks for all your videos, really it’s so hard to do this, thank you.
Sir, I am PhD student in the first year, and my subject is detection and tracking in real time perhaps I will do this with infrared imagery, could you give me your email please.
Hi, you can find my contacts here https://pysource.com/contact/
Thanks for this video, really useful.
How would you modify the code so that you can detect 3 colors and the shapes, so that the output would display for instance “Red recangle” or “Yellow Circle” ?
thanks man
I’ve been getthing this error.. I hope you can help, thank you!
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
error: OpenCV(4.1.0) ..\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function ‘cv::cvtColor’
It means that the frame is empty.
Make sure you’re correctly loading the frame.
try printing the frame and see what you get.
print(frame)
cap = cv2.VideoCapture(0) make it zero it will work.
Here: cap = cv2.VideoCapture(1)
Change the 1 for a 0 or -1.
That is the assigned number of your camera. Usually starts counting on 0, for 2nd camera a 1, a 3rd camera a 2, etc. Or it may start on -1.
cap = cv2.VideoCapture(0)
Nice video.
Get this error
area = cv2.contourArea(cnt)
TypeError: Expected cv::UMat for argument ‘contour’
I got the same problem
does anyone has a solution?
i got an error
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
ValueError: need more than 2 values to unpack
i hope you can help thanks
i found that, works for me:
contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
ya same error did u find the solution
Sir I am looking to detect helix shaped structures(corkscrew shaped) through image processing/computer vision. Will you please guide me with the path which I should follow for doing the same.
Hi Sergio,
My name is Ger from Holland. The script and explaining is just what i search for.
But, is it possible to use more colors at the same time.
If yes, can you explain how to integrate this into the script.
many thanks in advance,
Ger
Hello , thanks for the work
But I get an error
In _,contrours,_= cv2 …
In this like
And the error is
Value error : not enough values to unpack. ( expected 3 , got 2)
Can anyone help please
I have the same error, please help
contours, hierachy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
syntax has changed
Hi, I wanted to ask if I’m supposed to add more colors in this, where do I need to make the changes ?
i need to detect humans .does anyone have code?
amazing thank you so much.
Hi there. Thank you for the code. If may ask how can I change the draw shape that instead of using the actual shape of the object im just going to use rectangle when it detects an object? thank you so much
Excellent tutorial, many thanks. I am really enjoying using this.
Hey, thanks for your great work. How can I add more objects like turn right/left signs ?
Thanks for your great work. I am trying to detect an arrow with a dotted/broken line but I am unable. I started with detecting a dotted line using Hough transformation then latter I tried to detect the arrowhead but still, I was unable.
sir i am getting error here
File “C:/Users/91918/PycharmProjects/shape1.py/shapedet.py”, line 21
break
^
SyntaxError: ‘break’ outside loop
could u get me the code used in this project to my mail id mentioned
[email protected]
You can directly download the source code by clicking on “click here to download the source code”