Detect Polygons in an Image using OpenCV in Python
In this tutorial, we will be learning to identify different shapes present in an image on the basis of the number of edges detected in Python. We will be detecting shapes in an image by evaluating contours(edges) in an image and calculating the number of sides of the shape eg-if there are four sides then it is a square or rectangle. We will be using OpenCV and NumPy for image processing.
Algorithm:
- Read an image.
- Convert the image into grayscale for better processing.
- Detect shapes in the image by selecting a region on the basis of the same colors or intensity levels.
- Search every region in the image for the desired polygon i.e – 3 for Triangle,4-for square or Rectangle,5 for Pentagon, and so on.
- Select region based on area and check no of sides for the desired polygon.
- Show the outlined image.
Library used:
OpenCV
pip install opencv-python
Numpy
pip install numpy
Implementation:
The given code will detect types of polygons found in an image and will print the name along with the polygon found.
import cv2 import numpy as np img = cv2.imread('image.jpg') #read image from system cv2.imshow('original', img) #Displaying original image cv2.waitKey(0) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #Convert to grayscale image edged = cv2.Canny(gray, 170, 255) #Determine edges of objects in an image ret,thresh = cv2.threshold(gray,240,255,cv2.THRESH_BINARY) (contours,_) = cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) #Find contours in an image def detectShape(c): #Function to determine type of polygon on basis of number of sides shape = 'unknown' peri=cv2.arcLength(cnt,True) vertices = cv2.approxPolyDP(cnt, 0.02 * peri, True) sides = len(vertices) if (sides == 3): shape='triangle' elif(sides==4): x,y,w,h=cv2.boundingRect(cnt) aspectratio=float(w)/h if (aspectratio==1): shape='square' else: shape="rectangle" elif(sides==5): shape='pentagon' elif(sides==6): shape='hexagon' elif(sides==8): shape='octagon' elif(sides==10): shape='star' else: shape='circle' return shape for cnt in contours: moment=cv2.moments(cnt) cx = int(moment['m10'] / moment['m00']) cy = int(moment['m01'] / moment['m00']) shape=detectShape(cnt) cv2.drawContours(img,[cnt],-1,(0,255,0),2) cv2.putText(img,shape,(cx,cy),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,0),2) #Putting name of polygon along with the shape cv2.imshow('polygons_detected',img) cv2.waitKey(0) cv2.destroyAllWindows()
Input Image:
Output:
This Code will give an image with outlined shapes detected along with name of the shape.![]()
This code works well in Python 3 with all the libraries installed. The code will perfectly detect the shapes and identify them. This tutorial aims at the basic understanding of edge detection and how to identify regions in an image. Learners are advised to implement code in their machines and modify the code according to their requirements. This code is a basic example of polygon detection.
the opencv and python should be installed inside python and
where should the above programme be dumpped in python promt/pyton idle/ command promt ..?
Open CV is a library installed in Python.
You can run program anywhere like in pycharm or jupyter notebook
Hi Harshil,
Nice code. But Im getting this error
cx = int(moment[‘m10’] / moment[‘m00’])
ZeroDivisionError: float division by zero
You can comment out the relevant labeling ares such as cx, cy and cv.puttext. Since in my opinio these parts are extra for labelling. Then the zero division exception will fade.