Scikit Image − Hysteresis Thresholding



Hysteresis is a concept involving delayed or lagging effects, much like inertia. In thresholding, it means that regions above a lower threshold are considered valid if they are connected to regions above a higher, more stringent, threshold. Then they can be seen as extensions of these high-confidence regions.

Hysteresis thresholding, widely used in automatic edge detection, computes both low and high thresholds to generate a final edge map. It provides better results than using single thresholding if the low and high thresholds are reasonably calculated and their thresholded images are processed properly.

The scikit image library provides a function called apply_hysteresis_threshold() within its filter module for applying the Hysteresis thresholding to images.

Using the skimage.filters.apply_hysteresis_threshold() function

The apply_hysteresis_threshold() function is used for applying the hysteresis thresholding to an image.

This algorithm identifies regions in an image where the pixel intensity is either above a high threshold or above a low threshold and is connected to a region with intensity above the high threshold.

Syntax

Following is the syntax of this function −

skimage.filters.apply_hysteresis_threshold(image, low, high)

Parameters

The function accepts the following parameters −

  • Image: This parameter should be a grayscale input image, represented as a NumPy array with shape (M, [N, ..., P])
  • low: The lower threshold value. It can be a single float value or an array of the same shape as the image.
  • high: The higher threshold value. It can be a single float value or an array of the same shape as the image.

Return value

The function returns a thresholded array of boolean values, with the same shape as the input image. In the output array, True indicates the locations where the image's pixel values meet the hysteresis threshold.

Example

Here is an example of applying the apply_hysteresis_threshold() function to perform hysteresis thresholding on an Ndarray −

import numpy as np
from skimage.filters import apply_hysteresis_threshold

# define an array
array = np.array([[1, 2, 4, 2, 1, 3, 1, 3, 2],
                  [2, 4, 1, 2, 3, 2, 4, 1, 3]])
print('Input array:')
print(array)

# Apply hysteresis thresholding with low=1.5 and high=2.5
thresholded_result = apply_hysteresis_threshold(array, 1.5, 2.5).astype(int)

# Print the result
print("Array after applying the Hysteresis thresholding with low=1.5 and high=2.5:")
print(thresholded_result)

Output

Input array:
[[1 2 4 2 1 3 1 3 2]
 [2 4 1 2 3 2 4 1 3]]

Array after applying the Hysteresis thresholding with low=1.5 and high=2.5:
[[0 1 1 1 0 1 0 1 1]
 [1 1 0 1 1 1 1 0 1]]

Example

This example compares normal thresholding to hysteresis thresholding using the apply_hysteresis_threshold() function. Hysteresis thresholding can enhance edge detection by effectively ignoring noise in the image −

import matplotlib.pyplot as plt
from skimage import io, filters, color

# Load the input image
image = io.imread('Images/black rose.jpg')

# convert image to grayscale
grayscale_image = color.rgb2gray(image)

# Apply the Sobel filter to find edges in the image
edges = filters.sobel(grayscale_image)

# Define the low and high threshold values
low = 0.1
high = 0.35

# Apply thresholding to the edges
low_thresholded = (edges > low).astype(int)
high_thresholded = (edges > high).astype(int)

# Apply hysteresis thresholding to the edges
hysteresis_thresholded = filters.apply_hysteresis_threshold(edges, low, high)

# Plot the original and resultant images
fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(10,8))

# Display the original image 
ax[0, 0].imshow(grayscale_image, cmap='gray')
ax[0, 0].set_title('Original image')
ax[0, 0].axis('off')

# Display the Sobel edges
ax[0, 1].imshow(edges, cmap='magma')
ax[0, 1].set_title('Sobel edges')
ax[0, 1].axis('off')

# Display the result of the low threshold 
ax[1, 0].imshow(low_thresholded, cmap='magma')
ax[1, 0].set_title('Low threshold')
ax[1, 0].axis('off')

# Display the result of the hysteresis threshold
ax[1, 1].imshow(high_thresholded + hysteresis_thresholded, cmap='magma')
ax[1, 1].set_title('Hysteresis threshold')
ax[1, 1].axis('off')

plt.tight_layout()
plt.show()

Output

Hysteresis Threshold
Advertisements