Table of contents
1.
Introduction
2.
Applications of Contours
3.
Steps to Detect and Draw Contours in OpenCV
3.1.
1. Converting Image to Grayscale Format
3.2.
2. Apply Binary Thresholding
3.3.
3. Find the Contours
3.4.
4. Drawing the Contours on the Original Image
4.
Implementation
4.1.
Reading Image and Converting it to Grayscale
4.2.
Apply Binary Thresholding
4.3.
findContours() Method
4.4.
drawContours() Method
5.
Detecting Extreme Points
6.
Implementation
7.
FAQs
8.
Key Takeaways
Last Updated: Mar 27, 2024
Easy

Detecting Image Contour

Author soham Medewar
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Let us understand what contour is. A contour is created by joining all of the points on an object's boundaries. Usually, a contour is defined as a set of boundary pixels with the same color and intensity.

OpenCV provides two simple functions that will help us to find and draw the contours easily. The two functions are:

  • findContours()
  • drawContours()

 

OpenCV provides two different algorithms that help us to find the contours. The two algorithms are:

  • CHAIN_APPROX_SIMPLE
  • CHAIN_APPROX_NONE

Before going onto the algorithms, let us see some applications of contours.

Applications of Contours

Motion Detection: Motion detection technology has a wide range of applications in surveillance video traffic control, including indoor and outdoor security, detection of unattended objects, behavior identification during sporting activities, and even video compression.

Unattended object detection: Anything left alone in a public place is often regarded as suspicious. The following could be a good and safe solution: Unattended Object Detection through Contour Formation using Background Subtraction.

Background / Foreground Segmentation: To replace the background of an image with another background, you need to perform image-foreground extraction (similar to image segmentation); by using contours, we can achieve image segmentation.

Steps to Detect and Draw Contours in OpenCV

Contours can be detected by the following four steps:

1. Converting Image to Grayscale Format

The image should be read and converted to the grayscale format. The conversion to grayscale is crucial because it prepares the image for the next step. The image must be converted to a single-channel grayscale image for thresholding, which is required for the contour detection technique to perform effectively.

2. Apply Binary Thresholding

Always perform binary thresholding to the grayscale image before looking for contours. We'll use binary thresholding in this case.

This turns the image to black and white, highlighting the points of interest to make the contour-detection algorithm's job easier. Thresholding makes the image's object's border totally white, with the same intensity across all pixels. From these white pixels, the program can now discern the object's edges.

3. Find the Contours

We will use the findContours() function to detect the contours of the image.

4. Drawing the Contours on the Original Image

Use the drawContours() function to overlay the contours on the original RGB image once contours have been identified.

Also See, Image Sampling 

Implementation

Reading Image and Converting it to Grayscale

Import the OpenCV library and read the input image.

import cv2
# reading image
img = cv2.imread('image2.png')
You can also try this code with Online Python Compiler
Run Code

 

Display function.

def display(photo, s):
    while(True):
        cv2.imshow('frame', photo)
        k = cv2.waitKey(1) 
        if k == ord('q'):
            break
    cv2.imwrite(s, photo)
    cv2.destroyAllWindows()
    cv2.waitKey(1)
You can also try this code with Online Python Compiler
Run Code

 

Displaying original image.

display(image, "original.jpeg")
You can also try this code with Online Python Compiler
Run Code

 

Convert the image to grayscale format.

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
You can also try this code with Online Python Compiler
Run Code

Apply Binary Thresholding

Apply a binary threshold to the image using the threshold() function. A value of 255 will be assigned to any pixel with a value greater than 150. (white). In the resultant image, all remaining pixels will be set to 0. (black). You can play around with the threshold value of 150 because it is a configurable option.

After thresholding, use the imshow() function to display the binary image, as shown below.

ret, thresh = cv2.threshold(img_gray, 150, 255, cv2.THRESH_BINARY)
You can also try this code with Online Python Compiler
Run Code

 

Displaying, the binary image.

display(thresh, "img_thresh.jpeg")
You can also try this code with Online Python Compiler
Run Code

Till now, we have created a binary image. Furthermore, we will apply both the algorithms, i.e., CHAIN_APPROX_NONE and CHAIN_APPROX_SIMPLE.

findContours() Method

To find contours, we will use the findContours() method provided by OpenCV. It takes three arguments mandatorily. The three arguments are as follows:

Image: Binary image as input.

Mode: It is the contour-retrieval mode. The modes are as follows:

  • RETR_EXTERNAL retrieves only the extreme outer contours.
  • RETR_LIST retrieves all the contours without establishing any hierarchical relationship.
  • RETR_CCOMP retrieves all the contours and establishes a two-level hierarchy.
  • RETR_TREE retrieves all the contours and constructs a full hierarchy of nested contours.

Method: It is the contour-approximation method. This blog will see both CHAIN_APPROX_NONE and CHAIN_APPROX_SIMPLE to store all the contours.

contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)
You can also try this code with Online Python Compiler
Run Code

 

The contours variable will store all the contours of the binary image. Now, we need to draw these contours on the original image; to do so, we will use the drawContours() function provided by the OpenCV library.

drawContours() Method

The drawContours() method provides functionality to draw the contours that are generated from the findContours() function on the original image. This function takes four mandatory arguments. Following are the four arguments:

image: This is the RGB input picture on which the contour should be drawn.

contours: The contours returned by the findContours() method are displayed here.

contourIdx: In the produced contours, the pixel coordinates of the contour points are listed. You can provide the index position from this list with this input, specifying exactly the contour point you wish to draw. If you provide a negative value, all of the contour points will be drawn.

color: This indicates the color of the contour you are drawing. Here we are drawing with red color.

image_copy = img.copy()
cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(0, 0, 255), thickness=2, lineType=cv2.LINE_AA)
You can also try this code with Online Python Compiler
Run Code

 

Displaying the final image on which contours are drawn.

display(image_copy,"img_copy.jpg")
You can also try this code with Online Python Compiler
Run Code

Note: To implement CHAIN_APPROX_SIMPLE just change the method to cv2.CHAIN_APPROX_SIMPLE.

Detecting Extreme Points

This was all about detecting contours in an image. In this section, we will see how to find extreme points in contours. Detecting extreme points helps enhance computer vision applications as it is preprocessing technique.

Let us see how we detect extreme points on the contours with an example.

Implementation

Till detecting contours, the process is the same. The first is to import libraries and read the input image. Convert the image to grayscale format. Now apply a binary threshold on the grayscale formatted image. Then detect contours using any of two algorithms provided by OpenCV.

After detecting contours we will import a library named imutils. We will pass all the detected contours in the grab_contours() function provided by the imutils library and will determine the largest contour. Now we will determine left, right, top, bottom extreme points. Following code will guide you through the implementation process.

# importing libraries
import imutils
import cv2

# display function
def display(photo, s):
    while(True):
        cv2.imshow('frame', photo)
        k = cv2.waitKey(1) 
        if k == ord('q'):
            break
    cv2.imwrite(s, photo)
    cv2.destroyAllWindows()
    cv2.waitKey(1)

# reading the image
image = cv2.imread("image3.png")

# displaying real image
display(image)

# converting the image to grayscale format
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# applying binary threshold
thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1]

# find contours in thresholded image, then grab the largest contour
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)

# determining left, right, top, bottom extreme points
extLeft = tuple(c[c[:, :, 0].argmin()][0])
extRight = tuple(c[c[:, :, 0].argmax()][0])
extTop = tuple(c[c[:, :, 1].argmin()][0])
extBot = tuple(c[c[:, :, 1].argmax()][0])

# drawing largest contour and plotting extreme points on the image
cv2.drawContours(image, [c], -1, (0, 255, 255), 2)
cv2.circle(image, extLeft, 8, (0, 0, 255), -1)
cv2.circle(image, extRight, 8, (0, 255, 0), -1)
cv2.circle(image, extTop, 8, (255, 0, 0), -1)
cv2.circle(image, extBot, 8, (255, 255, 0), -1)

# displaying image
display(image,"ExtremePoints.jpeg")
You can also try this code with Online Python Compiler
Run Code

Original Image

Image after finding extreme points

Also read, Sampling and Quantization

FAQs

1. What are image contours?

A: Contours are defined as a line that connects all of the spots along the image's boundaries that have the same intensity.

2. Difference between contour detection and edge detection?

A: Edge detection simply identifies points where the picture intensity varies dramatically. It might create a closed shape or not. The fundamental goal of contour detection is to discover a closed-form and draw the object's border.

3. Why do we use the CHAIN_APPROX_SIMPLE method?

A: To eliminate all unnecessary points and compress the shape, saving memory in the process.

4. Why is contour used in image processing?

A: The contours are a valuable tool for item detection and recognition as well as form analysis.

Key Takeaways

In this article, we have discussed the following topics:

  • Introduction to contours
  • Steps to detect contours
  • Practical implementation of detecting contours
  • Detecting extreme points of a contour.

Want to learn more about Machine Learning? Here is an excellent course that can guide you in learning. 

Happy Coding!

Live masterclass