OpenCV Threshold: Guide to Image Thresholding

Image thresholding is one of the most fundamental techniques in image processing and computer vision. OpenCV, the leading open-source library for computer vision, provides a robust set of functions to apply thresholding operations effectively. Whether you are segmenting objects in an image or preprocessing for further analysis, thresholding plays a crucial role.

In this article, we will explore OpenCV threshold, its various techniques, and how you can use them in Python to manipulate and analyze images. By the end, you’ll have a thorough understanding of thresholding and its practical applications.


What is Image Thresholding in OpenCV?

Image thresholding is a technique that converts an image into a binary format (black and white) based on a threshold value. It simplifies the image, making it easier to analyze by isolating specific regions of interest.

At its core, thresholding works by comparing each pixel value to a predefined threshold:

  • If the pixel value is greater than the threshold, it is set to a maximum value (e.g., white).
  • If the pixel value is less than or equal to the threshold, it is set to a minimum value (e.g., black).

This creates a binary image where the foreground (objects of interest) is separated from the background.


Types of Thresholding in OpenCV

OpenCV offers several types of thresholding techniques that are useful for different use cases. Let’s discuss each method in detail.

1. Basic Thresholding

Basic thresholding is the simplest form where a single threshold value is applied globally to all pixels in the image. However, this method can produce poor results for images with varying lighting conditions, as the global threshold may not accurately separate the foreground from the background in different regions of the image.

Code Example:

import cv2
import numpy as np

# Load the grayscale image
image = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)

# Apply basic thresholding
threshold_value = 127
_, thresholded_image = cv2.threshold(image, threshold_value, 255, cv2.THRESH_BINARY)

# Display the original and thresholded images
cv2.imshow("Original Image", image)
cv2.imshow("Thresholded Image", thresholded_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Key Parameters:

  • image: The input grayscale image.
  • threshold_value: The threshold value used for comparison.
  • 255: The maximum value assigned to pixels that exceed the threshold.
  • cv2.THRESH_BINARY: The thresholding type.

Output:

This code creates a binary image where pixels greater than 127 are white, and others are black.

2. Inverse Binary Thresholding

Inverse thresholding is the opposite of basic thresholding:

  • Pixels greater than the threshold are set to the minimum value (black).
  • Pixels less than or equal to the threshold are set to the maximum value (white).

Code Example:

_, inverse_thresholded_image = cv2.threshold(image, threshold_value, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("Inverse Thresholded Image", inverse_thresholded_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. Truncate Thresholding

In truncate thresholding, pixel values greater than the threshold are set to the threshold value, while others remain unchanged.

Code Example:

_, truncated_image = cv2.threshold(image, threshold_value, 255, cv2.THRESH_TRUNC)
cv2.imshow("Truncated Image", truncated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. Threshold to Zero

In this method, pixel values greater than the threshold remain unchanged, while others are set to zero.

Code Example:

_, zero_threshold_image = cv2.threshold(image, threshold_value, 255, cv2.THRESH_TOZERO)
cv2.imshow("Threshold to Zero Image", zero_threshold_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. Inverse Threshold to Zero

Here, pixel values less than or equal to the threshold remain unchanged, and others are set to zero.

Code Example:

_, zero_inverse_image = cv2.threshold(image, threshold_value, 255, cv2.THRESH_TOZERO_INV)
cv2.imshow("Inverse Threshold to Zero Image", zero_inverse_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Adaptive Thresholding

Basic thresholding techniques can fail when lighting conditions vary across the image. To address this issue, OpenCV provides adaptive thresholding, which calculates thresholds for small regions of the image independently.

Code Example:

# Apply Adaptive Thresholding
adaptive_image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)

# Display the result
cv2.imshow("Adaptive Thresholding", adaptive_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Key Parameters:

  • cv2.ADAPTIVE_THRESH_GAUSSIAN_C: Adaptive method based on Gaussian mean.
  • 11: Block size (size of the region considered for thresholding).
  • 2: Constant subtracted from the mean.

Adaptive thresholding works well for images with non-uniform illumination, producing better results than global thresholding. Instead of applying a single threshold to the entire image, it calculates a local threshold for small regions or blocks of the image. This local thresholding is based on either the mean or a weighted sum of pixel intensities (Gaussian method) within each block. The Gaussian-based method gives more weight to pixels closer to the center of the block, making it more effective for images with gradients or varying light conditions.


Otsu’s Binarization

Otsu’s Binarization automatically determines the optimal threshold value by minimizing intra-class variance. It is particularly effective when the histogram of pixel intensities is bimodal, meaning it has two distinct peaks. In such cases, Otsu’s method identifies the threshold that best separates the two classes of pixels, such as the foreground and background. For example, in an image of a dark object on a bright background, the histogram will show one peak for dark pixels and another for bright pixels, making Otsu’s method ideal for determining the threshold automatically.

Code Example:

# Apply Otsu's Binarization
_, otsu_image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# Display the result
cv2.imshow("Otsu's Binarization", otsu_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Otsu’s method is especially useful when the histogram of pixel intensities has a clear bimodal distribution.


Troubleshooting Common Thresholding Issues

  1. Poor Threshold Selection: If the threshold value is not chosen correctly, it can result in incomplete segmentation. Use Otsu’s method or adaptive thresholding for better results.
  2. Lighting Variations: Use adaptive thresholding to handle varying lighting conditions across an image.
  3. Noise in the Image: Apply Gaussian blur or median filtering before thresholding to reduce noise.
  4. Low Contrast: Enhance the image contrast using histogram equalization before thresholding.

Conclusion

Thresholding in OpenCV is a powerful technique for simplifying and analyzing images. Whether you use basic thresholding, adaptive methods, or Otsu’s Binarization, OpenCV provides all the tools needed to achieve optimal results. By understanding these methods and their practical applications, you can effectively tackle a wide range of image processing challenges.

Experiment with different thresholding techniques to determine which works best for your images, and combine them with other OpenCV functions for more advanced image analysis tasks.

Leave a Comment