Open In App

What Are Contours in Computer Vision?

In computer vision, a contour is like a digital representation of that outline. It can be described as the series of connected points that define the boundary of an object, separating and/or highlighting it from the background. These points tend to share similar color or intensity values, making them distinct from their surroundings. In this article, we are going to explore more on contours in computer vision.

Contours in Computer Vision

According to OpenCV documentation, Contours are said to be a curve that simply joins all the continuous points, along the boundary, having the same color or intensity. It can be represented using chain code, Fourier descriptors, shape context etc.

Contours can be defined as the curves or outlines that represent the boundaries of objects or shapes within an image. These curves join all the continuous points (along the boundary) having the same color or intensity, highlighting the structural properties of objects and providing a way to extract and represent shape information from images.

Contours are useful when working with grayscale or binary images where objects are clearly distinguished from the background based on variations in brightness or color. Even with simple images we transform it into grayscale or binary first to detect contours in a simple way.

Properties of Contours

Contours possess several essential properties that make them invaluable in computer vision:

Contour Detection

Contour detection involves identifying and extracting contours from images using various techniques, such as edge detection algorithms (e.g., Canny edge detection) or thresholding methods. Once detected, contours can be represented as a sequence of points or as hierarchies of curves, capturing the shape and structure of objects within the image. Some of the Contour Detection algorithms are:

  1. Canny Edge Detection: A classic edge detection algorithm known for its accuracy and robustness. It involves multiple stages including Gaussian smoothing, gradient calculation, non-maximum suppression, and hysteresis thresholding to detect edges effectively.
  2. Sobel Operator: A gradient-based edge detection method that computes the gradient magnitude and direction at each pixel. It's simple yet effective in highlighting edges in images, particularly useful in scenarios where computational efficiency is a concern.
  3. Laplacian of Gaussian (LoG): This method combines Gaussian smoothing with Laplacian edge detection to identify edges based on zero-crossings in the second derivative of the image. It's particularly good at detecting edges with varying widths and orientations.
  4. Scharr Operator: An enhancement of the Sobel operator, the Scharr operator provides better rotation invariance and edge detection accuracy. It's designed to capture edges more accurately, especially in images with smooth transitions.
  5. Deep Learning-Based Methods: Modern deep learning techniques, particularly Convolutional Neural Networks (CNNs), have shown remarkable performance in contour detection tasks. Deep learning-based methods can learn hierarchical features directly from image data, making them highly effective for complex and diverse datasets.

Contour Manipulation

After detection, contours can be manipulated and processed using a variety of techniques, including:

Contour Detection Using OpenCV

OpenCV provides powerful tools and functions to simplify the process of contour detection in images. With functions like findContours(), programmers can avoid writing lengthy algorithms and focus on the core logic of their applications.

Thresholding-Based Preprocessing

In thresholding based process, it tends to separate objects from the background based on their intensity variations (brightness or color). In this part, the color image (img) is converted to grayscale (gray). Then, adaptive thresholding is applied using cv2.adaptiveThreshold().

#conversion
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(
    gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 21, 5)

Edge-Based Preprocessing

Here, edge detection is implicitly performed as part of the contour detection process using the cv2.findContours() function with the cv2.RETR_TREE mode. Detected contours are drawn on a copy of the original image (detected_contours) using cv2.drawContours().

# Finding contours with RETR_TREE mode
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
detected_contours = img.copy()
cv2.drawContours(detected_contours, contours, -1, (0, 255, 0), -1)

Contour Detection and Masking

In this part, contour detection is explicitly performed using the cv2.findContours() function with cv2.RETR_EXTERNAL mode. Two masks are created:

# Finding contours with RETR_EXTERNAL mode for masking
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Masking with color
highlight = np.ones_like(img)
cv2.drawContours(highlight, contours, -1, (0, 200, 175), cv2.FILLED)

# Masking for extraction
mask = np.zeros_like(img)
cv2.drawContours(mask, contours, -1, (255, 255, 255), cv2.FILLED)
foreground = cv2.bitwise_and(img, mask)

Complete Code:

#imports
import cv2
from matplotlib import pyplot as plt
import numpy as np

#loading img
file = "/content/drive/MyDrive/spiderman.jpg"
img = cv2.imread(file)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()

#conversion
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(
    gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 21, 5)

#Func to find contours
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
detected_contours = img.copy()
cv2.drawContours(detected_contours, contours, -1, (0, 255, 0), -1)
plt.imshow(detected_contours)
plt.title('Detected contours')
plt.show()

contours, _ = cv2.findContours(
    thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

#masking img
highlight = np.ones_like(img)
cv2.drawContours(highlight, contours, -1, (0, 200, 175), cv2.FILLED)
plt.imshow(highlight)
plt.title('Highlight contour with color')
plt.show()

#masking again
mask = np.zeros_like(img)
cv2.drawContours(mask, contours, -1, (255, 255, 255), cv2.FILLED)
foreground = cv2.bitwise_and(img, mask)

#edges
plt.imshow(foreground)
plt.title('Extract contours')
plt.show()

print("\t")

#--main-plot--
contours = {"Original": img, "Detected contours": detected_contours,
            "Color contours": highlight, "Extract contours": foreground}
plt.subplots_adjust(wspace=.2, hspace=.2)
plt.tight_layout()

for i, (key, value) in enumerate(contours.items()):
    plt.subplot(2, 2, i + 1)
    plt.tick_params(labelbottom=False)
    plt.tick_params(labelleft=False)
    plt.title("{}".format(key))
    plt.imshow(value)

plt.show()

Output:

Capture

Applications of Contours

Contours find applications across various computer vision tasks and industries, including:

Limitations and Challenges

While contours are a powerful tool in computer vision, they come with certain limitations and challenges, such as:

Conclusion

Contour detection is a crucial technique in computer vision, that tends to analyze object shapes and boundaries in images. It can easily identify the connected points that define an object's outline allowing to be used in important real-life applications like, object detection and classification, shape analysis, image segmentation etc.

Article Tags :