OpenCV: Segmentation using Thresholding
In the realm of computer vision, image segmentation is a fundamental task that involves partitioning an image into multiple regions or segments. These segments often correspond to different objects or parts of an object in the image. One of the simplest and most widely used techniques for image segmentation is thresholding. OpenCV, a powerful open - source computer vision library, provides a variety of thresholding methods that can be easily applied to images. This blog will delve into the concept of image segmentation using thresholding in OpenCV, covering different types of thresholding, common practices, best practices, and providing example code for better understanding.
Table of Contents#
- What is Thresholding?
- Types of Thresholding in OpenCV
- Binary Thresholding
- Binary Inverted Thresholding
- Truncated Thresholding
- Threshold to Zero
- Threshold to Zero Inverted
- Adaptive Thresholding
- Otsu's Thresholding
- Common Practices
- Best Practices
- Example Usage
- Conclusion
- References
What is Thresholding?#
Thresholding is a technique that involves comparing each pixel value in an image to a fixed threshold value. Based on this comparison, pixels are either assigned a new value (e.g., 0 or 255 in the case of a binary image) or kept as they are. The goal of thresholding is to create a binary image where the objects of interest are separated from the background.
Types of Thresholding in OpenCV#
Binary Thresholding#
In binary thresholding, if the pixel value is greater than the threshold, it is set to a maximum value (usually 255), and if it is less than the threshold, it is set to 0.
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Read the image in grayscale
image = cv2.imread('your_image.jpg', 0)
threshold_value = 127
max_value = 255
_, binary_image = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_BINARY)
plt.imshow(binary_image, cmap='gray')
plt.show()Binary Inverted Thresholding#
This is the opposite of binary thresholding. Pixels greater than the threshold are set to 0, and pixels less than the threshold are set to the maximum value.
_, binary_inverted_image = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_BINARY_INV)
plt.imshow(binary_inverted_image, cmap='gray')
plt.show()Truncated Thresholding#
For pixels greater than the threshold, their value is set to the threshold. Pixels less than the threshold remain unchanged.
_, truncated_image = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TRUNC)
plt.imshow(truncated_image, cmap='gray')
plt.show()Threshold to Zero#
Pixels less than the threshold are set to 0, and pixels greater than the threshold remain unchanged.
_, threshold_to_zero_image = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TOZERO)
plt.imshow(threshold_to_zero_image, cmap='gray')
plt.show()Threshold to Zero Inverted#
Pixels greater than the threshold are set to 0, and pixels less than the threshold remain unchanged.
_, threshold_to_zero_inv_image = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TOZERO_INV)
plt.imshow(threshold_to_zero_inv_image, cmap='gray')
plt.show()Adaptive Thresholding#
The fixed thresholding methods mentioned above work well when the lighting conditions are uniform across the image. However, in real - world scenarios, lighting can vary significantly. Adaptive thresholding calculates different thresholds for different regions of the image based on the local pixel statistics.
# Adaptive thresholding
adaptive_mean = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
adaptive_gaussian = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
plt.subplot(121)
plt.imshow(adaptive_mean, cmap='gray')
plt.title('Adaptive Mean Thresholding')
plt.subplot(122)
plt.imshow(adaptive_gaussian, cmap='gray')
plt.title('Adaptive Gaussian Thresholding')
plt.show()Otsu's Thresholding#
Otsu's method automatically calculates the optimal threshold value that separates the image into two classes (foreground and background). It works by minimizing the intra - class variance of the two classes.
# Otsu's thresholding
_, otsu_image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
plt.imshow(otsu_image, cmap='gray')
plt.show()Common Practices#
- Pre - processing: Before applying thresholding, it is often a good idea to perform pre - processing steps such as blurring the image to reduce noise. For example, you can use Gaussian blur:
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)- Convert to Grayscale: Since thresholding is usually applied to single - channel images, convert the input image to grayscale if it is a color image.
if len(image.shape) == 3:
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)Best Practices#
- Choose the Right Thresholding Method: Consider the characteristics of your image. If the lighting is uniform, fixed thresholding might work well. For non - uniform lighting, use adaptive or Otsu's thresholding.
- Experiment with Parameters: When using adaptive thresholding, experiment with different block sizes and constants to get the best results.
Example Usage#
Let's assume we want to segment a handwritten digit from a scanned document.
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Read the image
image = cv2.imread('handwritten_digit.jpg', 0)
# Pre - processing: blur the image
blurred = cv2.GaussianBlur(image, (5, 5), 0)
# Otsu's thresholding
_, segmented_image = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
plt.subplot(121)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.subplot(122)
plt.imshow(segmented_image, cmap='gray')
plt.title('Segmented Image')
plt.show()Conclusion#
Thresholding is a simple yet powerful technique for image segmentation in OpenCV. By understanding the different types of thresholding methods, common practices, and best practices, you can effectively segment objects from the background in various images. Whether you are dealing with simple images with uniform lighting or complex images with non - uniform lighting, OpenCV provides the necessary tools to achieve good segmentation results.
References#
- OpenCV documentation: https://docs.opencv.org/
- Digital Image Processing books, e.g., "Digital Image Processing" by Rafael C. Gonzalez and Richard E. Woods.