π‘ Problem Formulation: Image thresholding is a fundamental technique in computer vision used to simplify visual data by converting grayscale images into binary images. Suppose you have a grayscale image, and you want to extract certain features from it. The input is the grayscale image, and the desired output is a binary image where the pixels of interest are white (255) and the rest are black (0). This article explains how to achieve this using various thresholding techniques in Python with the OpenCV library.
Method 1: Basic Thresholding
Basic thresholding is straightforward in OpenCV. The cv2.threshold()
function takes an image, a threshold value, and a maximum value. Pixels above the threshold are set to the maximum value, while those below are set to zero.
Here’s an example:
import cv2 # Load image in grayscale image = cv2.imread('image.jpg', 0) # Apply simple thresholding ret, thresholded = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY) cv2.imshow('Basic Thresholding', thresholded) cv2.waitKey(0) cv2.destroyAllWindows()
Output: A window displaying the binary image after basic thresholding.
This code snippet loads an image in grayscale, applies basic thresholding with a predefined threshold value of 127 and a maximum pixel value of 255 (white). Pixels below 127 are set to 0 (black), and those above to 255 (white), resulting in a stark binary image.
Method 2: Inverse Thresholding
Inverse Thresholding is a variation where instead of setting the pixel value to maximum if it’s above the threshold, it’s set to zero. Conversely, values below the threshold are set to the maximum value. This is useful when you’re interested in darker regions of an image.
Here’s an example:
import cv2 # Load image in grayscale image = cv2.imread('image.jpg', 0) # Apply inverse thresholding ret, thresholded = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV) cv2.imshow('Inverse Thresholding', thresholded) cv2.waitKey(0) cv2.destroyAllWindows()
Output: A window displaying the binary image after inverse thresholding.
This snippet loads an image in grayscale, and thresholding is applied such that pixels with a value lower than 127 are set to 255 (white), focusing on the darker elements of the image while the lighter parts become black.
Method 3: Truncation Thresholding
Truncation Thresholding in OpenCV does not create a binary image but rather truncates pixel values at the threshold. Pixel values above the threshold are set to the threshold value; others remain unchanged.
Here’s an example:
import cv2 # Load image in grayscale image = cv2.imread('image.jpg', 0) # Apply truncation thresholding ret, thresholded = cv2.threshold(image, 127, 255, cv2.THRESH_TRUNC) cv2.imshow('Truncation Thresholding', thresholded) cv2.waitKey(0) cv2.destroyAllWindows()
Output: A window displaying the image after truncation thresholding.
Using the cv2.THRESH_TRUNC
option, any pixel value in the image that’s higher than 127 gets replaced with the threshold value itself; other pixels remain unchanged. This can be good for highlighting the structure of objects in images without making it binary.
Method 4: To Zero Thresholding
‘To Zero’ Thresholding sets pixel values to zero if they are below the threshold; otherwise, they remain unchanged. This type of thresholding preserves all of the lighter pixels while dismissing the darker ones.
Here’s an example:
import cv2 # Load image in grayscale image = cv2.imread('image.jpg', 0) # Apply to zero thresholding ret, thresholded = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO) cv2.imshow('To Zero Thresholding', thresholded) cv2.waitKey(0) cv2.destroyAllWindows()
Output: A window displaying the image after to zero thresholding.
This code determines how pixels below the threshold are nullified and the remaining are preserved. It is particularly useful when you need to drop the background of an image but keep the details of the objects.
Bonus One-Liner Method 5: Adaptive Thresholding
Adaptive Thresholding allows for different thresholds for different regions of the image. The cv2.adaptiveThreshold()
function calculates the threshold for small regions, which provides flexibility across an image with varying lighting conditions.
Here’s an example:
import cv2 # Load image in grayscale image = cv2.imread('image.jpg', 0) # Apply adaptive thresholding thresholded = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, \ cv2.THRESH_BINARY, 11, 2) cv2.imshow('Adaptive Thresholding', thresholded) cv2.waitKey(0) cv2.destroyAllWindows()
Output: A window displaying the binary image after adaptive thresholding.
This line applies adaptive thresholding to account for variations in lighting by defining different threshold values over different regions. This method is powerful for images with different lighting conditions or shadows.
Summary/Discussion
- Method 1: Basic Thresholding. Simple and fast. Good for high-contrast images. Not suitable for varying lighting conditions.
- Method 2: Inverse Thresholding. Effective for highlighting dark areas against light backgrounds. Not ideal for detail preservation in bright areas.
- Method 3: Truncation Thresholding. Useful for visualizing the detailed structure in bright objects. Does not produce a clean binary result.
- Method 4: To Zero Thresholding. Preserves details in bright regions. Loses information in darker areas.
- Method 5: Adaptive Thresholding. Handles varying lighting well. More computationally intensive than global thresholding methods.