OpenCV & Python – Image Thresholding

OpenCV & Python - Image Thresholding header

Among the fundamental image processing techniques in Image Analysis is Image Thresholding. This technique processes a grayscale image by dividing it into two areas: one white and one black. Which parts of the image should be white or black will depend on a series of factors, more or less complex depending on the technique, all based on a threshold value.

Image Threasholding

Thresholding is an image processing technique that is often used to convert a grayscale image to a binary image. The goal is to separate the image into regions of high and low light intensity. This process is useful in many applications, such as edge detection, object segmentation, and feature extraction.

There are several techniques for applying Image Thresholding. In this article we will see two of them:

  • Simple Thresholding
  • Adaptive Thresholding

which represent excellent examples to better understand this technique. At the end we will see a list of other techniques that perform Image Thresholding, with some in-depth articles where you can consult them in detail.

Simple Thresholding

Simple Thresholding is the most direct method of image thresholding, in which a threshold value is set and image pixels that have an intensity higher than this value are considered white, while those lower than that become black. This approach is especially useful when the image has good contrast and the distribution of gray levels is clear.

The theory of Simple Thresholding involves some basic mathematical concepts. The basic idea is that you choose a threshold value (T) and classify the image pixels into two categories: those above the threshold value and those below the threshold value.

The original image is represented as an array of pixels, each of which has a light intensity (gray) value that can range from 0 to 255. A grayscale image can be represented as a  function f( x, y) , where  x and  y are the pixel coordinates. You choose a threshold value (T), which is a number between 0 and 255. This value separates pixels into two categories: those with light intensity greater than (T) and those with intensity less than (T). Each pixel in the image is compared to the threshold value. If the value of the pixel  f(x, y) is greater than ( T ), the pixel is assigned to the group above the threshold (for example, it turns white), otherwise it is assigned to the group below the threshold (turns black).

This process is represented by the following formula:

g(x, y) =\begin{cases}255 & \text{se } f(x, y) > T \0 & \text{altrimenti}\end{cases}

Where  g(x, y) is the pixel value in the new binary image.

The result is a binary image, where pixels above the threshold are represented by white values (for example, 255) and pixels below the threshold are represented by black values (for example, 0).

Simple Thresholding with Python and OpenCV

As for Python, you can use the OpenCV library through the cv2.threshold function. The choice of threshold value is critical and can greatly influence the effectiveness of thresholding. In some cases, more advanced methods, such as OTSU, can be used to automatically calculate the optimal threshold value.

First we choose an image to undergo the Simple Thresholding process.

leaf-identification

Right-click on the previous image and save it as leaf.jpg. Once downloaded you can use it in the following code.

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

# Read the image in grayscale
image = cv2.imread('leaf.jpg', cv2.IMREAD_GRAYSCALE)

# Apply Simple Thresholding with an arbitrary threshold value
ret, thresholded_image = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY)

# Display the original and thresholded image
plt.subplot(1, 2, 1), plt.imshow(image, cmap='gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])

plt.subplot(1, 2, 2), plt.imshow(thresholded_image, cmap='gray')
plt.title('Simple Thresholding'), plt.xticks([]), plt.yticks([])

plt.show()

In the code above, cv2.threshold takes as input the grayscale image (image), the threshold value (150), the maximum value (255, represents white in the new binary image) and the threshold type (cv2. THRESH_BINARY). Running the code you get the following result:

OpenCV & Python - Simple Thresholding

You can adjust the threshold value based on your specific image and problem needs. The effectiveness of Simple Thresholding depends greatly on the distribution of gray levels in the image, and is often used when the image is well contrasted. To better understand this concept, let’s modify the previous example by checking the different images produced by Simple Thresholding, changing the value of 50 in 50 from 0 to 255 (value range from white to black).

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

# Read the image in grayscale
image = cv2.imread('leaf.jpg', cv2.IMREAD_GRAYSCALE)

# Create a subplot grid
plt.figure(figsize=(12, 8))

# List of threshold values to test
threshold_values = [50, 100, 150, 200]

# Iterate through the threshold values and display the resulting images
for i, threshold_value in enumerate(threshold_values):
# Apply Simple Thresholding
    ret, thresholded_image = cv2.threshold(image, threshold_value, 255, cv2.THRESH_BINARY)

# Plot the thresholded image
    plt.subplot(2, 3, i + 1), plt.imshow(thresholded_image, cmap='gray')
    plt.title(f'Threshold = {threshold_value}'), plt.xticks([]), plt.yticks([])

# Add the original image to the grid
plt.subplot(2, 3, 6), plt.imshow(image, cmap='gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])

# Show subplot grid
plt.show()

Executing this results in a series of 4 images of the leaf subjected to Simple Thresholding with the thresholds of (50,100,150 and 200).

OpenCV & Python - Simple Thresholding 02

Adaptive Thresholding

Adaptive Thresholding is an image thresholding technique that locally adapts to brightness variations in the image. Unlike Simple Thresholding, where a fixed value is used throughout the image, Adaptive Thresholding calculates the threshold based on local regions of the image. This is especially useful when there are significant lighting variations in different parts of the image.

The most common method of Adaptive Thresholding is based on the average or weighted sum of the intensity of the pixels within a local window (or block) centered on each pixel. The general formula for calculating the threshold in Adaptive Thresholding can be expressed as follows:

 T(x, y) = \text{{funzione}}(\text{{blocco}}(x, y) - C)

Where:

  • T(x, y) is the threshold value calculated for the pixel at position ((x, y)),
  • \text{{function}} is a function that calculates the threshold using the average or weighted sum of the pixels within the block,
  • \text{{block}}(x, y) represents the local window centered on the pixel ((x, y)),
  • C is a constant that can be subtracted from the calculated threshold.

The two main functions used are:

Local average (Mean):

 \text{{function}}(\text{{block}}(x, y)) = \frac{1}{\text{{block size}}} \sum_{i} \sum_{j} \text{{block}}(x+i, y+j)

Local weighted average (Gaussian):

 \text{{function}}(\text{{block}}(x, y)) = \frac{\sum_{i} \sum_{j} w(i, j) \cdot \text{{block}}(x+i, y+j)}{\sum_{i} \sum_{j} w(i, j)}

Where w(i, j) is the weight assigned to the pixel at position ((i, j)) within the block. The block size and value of (C) can be adjusted according to image characteristics and specific needs.

Adaptive Thresholding helps manage local variations in brightness or contrast in images, improving accuracy in segmentation and object detection. Let’s therefore write another code in which we will apply Adaptive Thresholding to the same image used previously and we will see how the results will vary compared to Simple Thresholding.

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

# Read the image in grayscale
image = cv2.imread('leaf.jpg', cv2.IMREAD_GRAYSCALE)

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

# Display the original image and the one with Adaptive Thresholding
plt.subplot(1, 2, 1), plt.imshow(image, cmap='gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])

plt.subplot(1, 2, 2), plt.imshow(adaptive_threshold, cmap='gray')
plt.title('Adaptive Thresholding'), plt.xticks([]), plt.yticks([])

plt.show()

In this example, cv2.adaptiveThreshold takes as input the grayscale image (image), the maximum value (255, represents white in the new binary image), the type of Adaptive Thresholding (cv2.ADAPTIVE_THRESH_MEAN_C which uses the average of local zone), the threshold type (cv2.THRESH_BINARY), the block size (11, specifies the size of the local window to calculate the threshold), and a constant (2, subtracts this constant from the calculated average). Running the code you get the following result:

OpenCV & Python - Adaptive Thresholding

As you can see, compared to Simple Thresholding we have a completely different result.

Other types of Thresholding

There are several other types of thresholding used based on specific application needs and image characteristics. Some of these include:

Otsu’s Binarization (OTSU): This technique is used to automatically determine the optimal threshold value, minimizing the intra-class variance. In OpenCV, you can use cv2.threshold with the cv2.THRESH_OTSU flag.

the Otsu Binarization OpenCV Python main

IN-DEPTH ARTICLE

Otsu Binarization

Binary Inverted Thresholding: This type of thresholding is the opposite of standard binary thresholding. Pixels above the threshold turn black, while those below turn white.

Truncated Thresholding: In this technique, pixels exceeding the threshold are set to the maximum value, while those below retain their original value.

Tozero Thresholding: Pixels below the threshold are set to zero, while those above it retain their original value.

Tozero Inverted Thresholding: This is the inversion of Tozero Thresholding. Pixels below the threshold retain their original value, while those above the threshold are set to zero.

Adaptive Mean Thresholding: Similar to Adaptive Thresholding, but uses the weighted average of the local region to calculate the threshold.

Adaptive Gaussian Thresholding: Similar to Adaptive Thresholding, but uses a Gaussian weighted average to calculate the threshold.

Yen’s Thresholding: Another thresholding method based on maximizing entropy between classes.

Each type of thresholding has its applications and can be chosen based on specific image characteristics and analysis goals. Experimenting with different approaches can be helpful in achieving desired results in specific contexts.

Possible applications of Image Thresholding

Image Thresholding is a fundamental technique in image processing and has several applications in various fields. Below are some of its common applications:

  • Object Segmentation: Image Thresholding is often used to separate objects of interest from the background or other objects in the image. This segmentation is useful in many applications, such as edge detection, object measurement, and analysis of objects in an image.
  • Edge Detection: Binarizing images using thresholding simplifies the edge detection process. The outlines of objects become more evident in the binary version, making it easier to identify and extract geometric information.
  • OCR Character Recognition: In Optical Character Recognition (OCR), Image Thresholding is used to convert the text image to binary, facilitating character identification and improving character recognition performance.
  • Biometrics: In biometrics, Image Thresholding can be used to isolate key features, such as fingerprints, faces or irises, facilitating subsequent analysis and comparison.
  • Medical Image Processing: In the field of medical imaging, Image Thresholding is used to segment anatomical structures, identify lesions or tumors, and improve image quality for further diagnostic analysis.
  • Satellite Image Analysis: In satellite image analysis, Image Thresholding can be applied to detect specific terrain features, identify environmental changes and improve the understanding of satellite images.
  • Inline Quality Control: In industrial applications, Image Thresholding can be used to inspect products on the production line, identifying defects or anomalies based on differences in color or brightness.
  • Security and Surveillance: Image Thresholding can be used in the security field for motion detection in surveillance cameras, allowing you to identify relevant events and reduce false positives.

These are just a few examples of the many applications of Image Thresholding. The flexibility of this technique makes it a valuable tool in various sectors, contributing to the improvement of the analysis and interpretation of digital images.

Leave a Reply