We’ll se in this video how to perform a simple shape detection.
Starting from an image with a few shapes, we’ll be able to detect exactly each shape (rectangle, circle, pentagon, etc.) and the position.
As first thing we need to import the libraries, then on line 4 we also define the font that we will use later on to display the text on the image.
import cv2 import numpy as np font = cv2.FONT_HERSHEY_COMPLEX
We then load the image, we get the threshold of the image to have a black and white image, where the background is white and all the shapes are black.
From the black and white image we find the contours, so the boundaries of all the shapes.
img = cv2.imread("shapes.jpg", cv2.IMREAD_GRAYSCALE)
_, threshold = cv2.threshold(img, 240, 255, cv2.THRESH_BINARY)
_, contours, _ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
We loop trough the contours, so we get the coordinates of the contours of each single shape.
On line 10 we approximate the contours to remove the noise.
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.01*cv2.arcLength(cnt, True), True)
cv2.drawContours(img, [approx], 0, (0), 5)
x = approx.ravel()[0]
y = approx.ravel()[1]
if len(approx) == 3:
cv2.putText(img, "Triangle", (x, y), font, 1, (0))
elif len(approx) == 4:
cv2.putText(img, "Rectangle", (x, y), font, 1, (0))
elif len(approx) == 5:
cv2.putText(img, "Pentagon", (x, y), font, 1, (0))
elif 6 < len(approx) < 15:
cv2.putText(img, "Ellipse", (x, y), font, 1, (0))
else:
cv2.putText(img, "Circle", (x, y), font, 1, (0))
Finally we display everything on the screen:
cv2.imshow("shapes", img)
cv2.imshow("Threshold", threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()

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.
_, contours, _ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
ValueError: need more than 2 values to unpack
Getting this type of error. What to do now?
I think you are running OpenCV4. There was a change in the function cv2.findContours
Just try: contours, _=cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
This question also helped me, many thanks!!
actually the problem is the bgr image.first convert your image into binary image by converting bgr to grayscale.
i get this error! NameError: name ‘font’ is not defined. can you please tell me why ?
Check to make sure you defined font as shown on line 4 of the first box.
C:\Users\Kiran\AppData\Local\Programs\Python\Python37-32\python.exe D:/PythonEx/Libraries/OpenCV/obj_det1.py
Traceback (most recent call last):
File “D:/PythonEx/Libraries/OpenCV/obj_det1.py”, line 14, in
cv2.drawContours(img, cnt, 0, (0), 5)
cv2.error: OpenCV(4.0.0) C:\projects\opencv-python\opencv\modules\imgproc\src\drawing.cpp:2509: error: (-215:Assertion failed) npoints > 0 in function ‘cv::drawContours’
I always get this assertion failed error, please help
error: OpenCV(4.0.1) C:\projects\opencv-python\opencv\modules\imgproc\src\contours.cpp:197: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function ‘cvStartFindContours_Impl’
i am getting this error on binary image.
img = cv2.imread(“image.jpg”)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.imread(“/home/anonymous/Downloads/images/mine.jpg”, cv2.IMREAD_GRAYSCALE)
_, threshold = cv2.threshold(img, 240, 255, cv2.THRESH_BINARY)
_, contours, _ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
Error :
ValueError: not enough values to unpack (expected 3, got 2)
how did you fix it? i have the same problem
Just fixed it : wrong path for the image in the imread command.
write _, contours = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
instead of _, contours, _ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
Hello,
Just run your script with your image and got an error : 215 Assertion failed .. Many THanks for your inputs !
———————-
error Traceback (most recent call last)
in
25 cv2.putText(img, “Circle”, (x, y), font, 1, (0))
26
—> 27 cv2.imshow(“shapes”, img)
28 cv2.imshow(“Threshold”, threshold)
29 cv2.waitKey(0)
error: OpenCV(3.4.2) /opt/concourse/worker/volumes/live/9523d527-1b9e-48e0-7ed0-a36adde286f0/volume/opencv-suite_1535558719691/work/modules/highgui/src/window.cpp:356: error: (-215:Assertion failed) size.width>0 && size.height>0 in function ‘imshow’
print(len(approx))
When I run the code with this command ,its shows numerous values like 4,6,23,2,4,….I also tried by changing its threshold value …Is there anyway to fix it??
change the approx not the threshold
Hello i have this erro when i run the code who i can fix it ?
C:\Users\ASUS\PycharmProjects\vision_project\venv\Scripts\python.exe “C:/Users/ASUS/PycharmProjects/vision_project/simple shape detection.py”
Traceback (most recent call last):
File “C:/Users/ASUS/PycharmProjects/vision_project/simple shape detection.py”, line 6, in
_, contours ,_ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
ValueError: not enough values to unpack (expected 3, got 2)
Process finished with exit code 1
For Opencv 3.x;
_, contours ,_ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
For OpenCV 2.x, 4.x
contours, _ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
For Opencv 3.x;
_, contours ,_ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
For OpenCV 2.x, 4.x
contours, _ = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
Hey , can i store these coordinates i.e. x and y in a list such as for a square list will be ((0,0),(0,1),(1,0),(1,1)) ?
what does approx.ravel() do, and how does it work?