Shape detection using OpenCV and Python

In this tutorial I will show you how to detect shape in image using OpenCV. In my last post I have shown, how you can detect object using contour detection technique. In this tutorial I will use same contour detection technique for shape detection using OpenCV and python.

By reading this article you will know:

  • Object detection using contour
  • Shape recognition of any object in the image
    • Detect rectangle in image OpenCV python
    • Detect circle in image OpenCV python
    • Detect Triangle in image OpenCV python
    • etc.

Must Read:

Approach

To Find any shape in image we will follow below steps:

  • Import module & image
  • Detect object using contour
  • Recognize shape of any object by end points of contour
  • Write shape name of contour

Import module & image

In this post I will use same image which I have used in my last post (Object detection using contour).

import cv2

# Read image for contour detection and shape recognition
input_image = cv2.imread("shapes.png")

# Make a copy to draw contour outline
input_image_cpy = input_image.copy()

Detect object using contour

To detect object using contour to need to do some modification to your image. In my last tutorial I have explained this in details. If you already read my last tutorial you will know how to detect contours. I am using same code (from my last article) to detect and draw contour.

Must Read:

# Convert input image to grayscale
gray_img = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)

threshold_value = gray_img[216, 402]
print(threshold_value)

# Convert the grayscale image to binary (image binarization opencv python)
ret, binary_img = cv2.threshold(gray_img, threshold_value, 255, cv2.THRESH_BINARY)

# Invert image
inverted_binary_img = ~ binary_img

# Detect contours
# hierarchy variable contains information about the relationship between each contours
contours_list, hierarchy = cv2.findContours(inverted_binary_img,
                                       cv2.RETR_TREE,
                                       cv2.CHAIN_APPROX_SIMPLE) # Find contours

# Draw 4th contour
contour_num = 3

# Draw detected contour with shape name
contour1 = cv2.drawContours(input_image_cpy, contours_list, contour_num, (255, 0, 255), 3)

cv2.imshow('First detected contour', contour1)
cv2.waitKey(0)
cv2.destroyAllWindows()
shape detection opencv python
Output

For now I am only drawing 4th contour which is a Rectangle.

Also Read:  Motorcycle Helmet Detection using Deep Learning

Recognize shape of any object by end points of contour

We can recognize any shape of an object by knowing number of endpoints of that object. For example:

  • Rectangular / square object have 4 end points
  • Triangle have 3 end points
  • etc.

In OpenCV we can easily find out number of end points of a detected contour.

# Find number of end points of detected contour
end_points = cv2.approxPolyDP(contours_list[contour_num], 0.01 * cv2.arcLength(contours_list[contour_num], True), True)
print(end_points)
print(len(end_points))

Output

[[[350 116]]

[[350 305]]

[[461 305]]

[[461 116]]]


4

The variable end_points contains all the end points coordinate for 4th contour of our input image , which is a rectangle.
So length of that end_points variable must be 4.

Write shape name of contour with OpenCV

At this point you know how to detect shape or recognize shape using contour end points. Now let’s write text on top of each shape. To do that we need to know the point, where we will write the shape name.

If you print end_point variable you will have four points (for rectangle). Those are coordinates (x, y) of each points of the rectangle. We will write text at first point.

# Find number of end points of detected contour
end_points = cv2.approxPolyDP(contours_list[contour_num], 0.01 * cv2.arcLength(contours_list[contour_num], True), True)
print(end_points)
print(len(end_points))

# Find first point of rectangle
point_x = end_points[0][0][0]
point_y = end_points[0][0][1]

# Writing shape name at first point of rectangular shape in black color (0, 0, 0)
text_color_black = (0, 0, 0)

# If a contour have four end points, then shape should be a Rectangle or Square
if len(end_points) == 4:
    cv2.putText(input_image_cpy, 'Rectangle', (point_x, point_y), cv2.FONT_HERSHEY_SIMPLEX, 0.8, text_color_black, 2)

cv2.imshow('First detected contour', contour1)
cv2.waitKey(0)
cv2.destroyAllWindows()
rectangle detection opencv python
Detected Rectangle

We have detected Rectangle in image with OpenCV and python. In the same way let’s detect shape for all the objects in our input image using a for loop.

Also Read:  Tutorial - Neural Style Transfer using Tensorflow

Shape detection OpenCV Python full Code

import cv2

# Read image for contour detection
input_image = cv2.imread("shapes.png")

# Make a copy to draw bounding box
input_image_cpy = input_image.copy()

# Convert input image to grayscale
gray_img = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)

threshold_value = gray_img[216, 402]
print(threshold_value)

# Convert the grayscale image to binary (image binarization opencv python)
ret, binary_img = cv2.threshold(gray_img, threshold_value, 255, cv2.THRESH_BINARY)

# Invert image
inverted_binary_img = ~ binary_img

# Detect contours
# hierarchy variable contains information about the relationship between each contours
contours_list, hierarchy = cv2.findContours(inverted_binary_img,
                                       cv2.RETR_TREE,
                                       cv2.CHAIN_APPROX_SIMPLE) # Find contours

# for each detected contours
for contour_num in range(len(contours_list)):

    # Draw detected contour with shape name
    contour1 = cv2.drawContours(input_image_cpy, contours_list, contour_num, (255, 0, 255), 3)

    # Find number of points of detected contour
    end_points = cv2.approxPolyDP(contours_list[contour_num], 0.01 * cv2.arcLength(contours_list[contour_num], True), True)

    # Make sure contour area is large enough (Rejecting unwanted contours)
    if (cv2.contourArea(contours_list[contour_num])) > 10000:

        # Find first point of each shape
        point_x = end_points[0][0][0]
        point_y = end_points[0][0][1]

        # Writing shape name at center of each shape in black color (0, 0, 0)
        text_color_black = (0, 0, 0)

        # If a contour have three end points, then shape should be a Triangle
        if len(end_points) == 3:
            cv2.putText(input_image_cpy, 'Triangle', (point_x, point_y),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.9, text_color_black, 2)

        # If a contour have four end points, then shape should be a Rectangle or Square
        elif len(end_points) == 4:
            cv2.putText(input_image_cpy, 'Rectangle', (point_x, point_y),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.9, text_color_black, 2)

        # If a contour have five end points, then shape should be a Pentagon
        elif len(end_points) == 5:
            cv2.putText(input_image_cpy, 'Pentagon', (point_x, point_y),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.9, text_color_black, 2)

        # If a contour have ten end points, then shape should be a Star
        elif len(end_points) == 10:
            cv2.putText(input_image_cpy, 'Star', (point_x, point_y),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.9, text_color_black, 2)

        # If a contour have more than ten end points, then shape should be a Star
        else:
            cv2.putText(input_image_cpy, 'circle', (point_x, point_y),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.9, text_color_black, 2)

    cv2.imshow('First detected contour', contour1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
real time shape detection opencv python
Final Output

Conclusion

In this post, I have explained how to perform shape detection with OpenCV and Python. To accomplish this, we leveraged:

  • Contour detection using OpenCV and Python
  • Draw contour using OpenCV and Python
  • Find End Points of a contour using Contour Approximation
  • Decide type of shape using number of end points of any detected contour
  • Write shape name of a contour on top of shape
Also Read:  Find and Draw Contours with OpenCV in Python

If you have any question or suggestion regarding this post please let me know in the comment section below.

7 thoughts on “Shape detection using OpenCV and Python”

  1. Wow, this post about shape detection using opencv and python is nice. You have covered the entire thing in one article.

    Reply
  2. Элементы лестниц оптом, кухни на заказ, двери из массива дуба https://www.ekolestnica.ru Большой выбор изделий из дерева (дуб, бук, ясень, береза, сосна) оптом балясины, перила, ступени для лестниц, двери из массива дуба, мебельный щит! На рынке 15 лет, доставка в любые регионы

    Reply

Leave a comment