# Shape Detection OpenCV Python

In the previous blog, we took the Circle Detection, now we’re moving one step further and we’re going to learn about shape detection in OpenCV Python.

Learn about Circle Detection OpenCV Python.

Let’s Start Coding Shape Detection in OpenCV Python.

The imports for this program will also be the same as the previous blog i.e import cv2, import NumPy, and also import matplotlib if you want to show the pictures in a grid format.

## Shape Detection OpenCV Algorithm

First of all, read and store the image. For this example, I am taking an image that contains shapes like triangle, square, rectangle, and circle.

The image is then converted to grayscale using the `cvtColor()` function.

Grayscaled image is then thresholded using the THRESH_BINARY Method. The Thresholded image is then taken and contours are found on that image.

The Contours obtained is then looped and the edges are counted using the `approxPolyDP()` function, that takes each contour.

The edges of the Contour is then drawn on the image using `drawContours()` function.

To write the name of the shape blocks of if-else are used that take decisions on the basis of the number of edges.

Example: If three edges are found the shape will be triangle.

In the case of square and rectangle aspect ratio between the width and height is calculated. If the ratio is close to 1 then the shape is square else rectangle.

If no edges edges are found then it is likely to be a circle.

``````def shapes():
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

_, thresh = cv.threshold(img_gray, 240, 255, cv.THRESH_BINARY)
contours, _ = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)

white = np.ones((img.shape[0], img.shape[1], 3))

for c in contours:
approx = cv.approxPolyDP(c, 0.01*cv.arcLength(c, True), True)
cv.drawContours(img, [approx], 0, (0, 255, 0), 5)
x = approx.ravel()[0]
y = approx.ravel()[1] - 5
if len(approx) == 3:
cv.putText(img, "Triangle", (x, y),
cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)
elif len(approx) == 4:
x1, y1, w, h = cv.boundingRect(approx)
aspect_ratio = float(w) / float(h)
print(aspect_ratio)
if aspect_ratio >= 0.95 and aspect_ratio <= 1.05:
cv.putText(img, "Square", (x, y),
cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)
else:
cv.putText(img, "Rectangle", (x, y),
cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)
elif len(approx) == 5:
cv.putText(img, "Pentagon", (x, y),
cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)
elif len(approx) == 10:
cv.putText(img, "Star", (x, y),
cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)
else:
cv.putText(img, "Circle", (x, y),
cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1)

cv.imshow("Shapes", img)
cv.waitKey()
cv.destroyAllWindows()
``````