Scikit image − Multi-Otsu Thresholding



Multi-Otsu Thresholding is an algorithm used to categorize the pixels within an image into several different classes based on their gray-level intensities. It calculates multiple thresholds based on the desired number of classes. If the desired number of classes is three then the resulting threshold values will be two.

The scikit image library provides a function called threshold_multiotsu() within its filters module to separate the pixels of a grayscale image into several different classes.

Using the skimage.filters.threshold_multiotsu() function

This function generates class-1 threshold values to divide the gray levels in an image into multiple classes, using Otsu's method for multiple classes. The thresholds are selected to maximize the total sum of pairwise variances between the thresholded gray-level classes.

It requires either the image or hist parameter to be provided. If hist is provided, it uses the provided histogram to determine the thresholds. If the image is provided, it computes the histogram from the image.

Syntax

Following is the syntax of this function −

skimage.filters.threshold_multiotsu(image=None, classes=3, nbins=256, *, hist=None)

Parameters

The function accepts the following parameters −

  • Image (N, M[, …, P]) ndarray: An optional grayscale input image.
  • Classes (int): An optional integer specifying the number of classes to be thresholded, i.e., the number of resulting regions.
  • nbins (int): An optional integer specifying the number of bins used to calculate the histogram. This value is ignored for integer arrays.
  • hist (array, or 2-tuple of arrays): An optional input histogram from which to determine the threshold, and optionally, a corresponding array of bin center intensities. If no histogram is provided, the function will compute it from the image.

Return value

The function returns an array containing the threshold values for the desired classes. Additionally, the function can raise a ValueError if the input image contains fewer grayscale values than the desired number of classes.

Example

The following example demonstrates how to perform multi-level thresholding using Otsu's method on a grayscale image using the threshold_multiotsu() function and then colorize the regions using the label2rgb() function −

import numpy as np
import matplotlib.pyplot as plt
from skimage.color import label2rgb, rgb2gray
from skimage.filters import threshold_multiotsu
from skimage import io, color

# Load the input image
image = rgb2gray(io.imread('Images/python logo2.jpg'))

# Calculate multi-Otsu thresholds using the threshold_multiotsu function
# Generating three classes by default
thresholds = threshold_multiotsu(image)

# Digitize the image into regions based on the calculated thresholds
regions = np.digitize(image, bins=thresholds)

# Colorize the regions for visualization
regions_colorized = label2rgb(regions)

# Plot the original image and the result
fig, axes = plt.subplots(1, 2, figsize=(15, 5))
ax = axes.ravel()

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

# Display the colorized regions
ax[1].imshow(regions_colorized)
ax[1].set_title('Colorized regions')
ax[1].axis('off')

plt.tight_layout()
plt.show()

Output

Otsu Threshold

Example

The following example applies the Multi-Otsu thresholding algorithm to a grayscale image to segment it into "5" regions by setting classes=5

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

# Load the grayscale image 
image = color.rgb2gray(io.imread('Images/group chat.jpg'))

# Calculate multi-Otsu thresholds, and generate 5 classes by specifying classes=5
thresholds = threshold_multiotsu(image, classes=5)

# Digitize the image into 5 regions based on the calculated thresholds.
regions = np.digitize(image, bins=thresholds)

# Create subplots for original image, histogram, and Multi-Otsu result.
fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(12, 4))

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

# Plot the histogram and mark the four thresholds obtained from multi-Otsu.
ax[1].hist(image.ravel(), bins=255)
ax[1].set_title('Histogram')
for thresh in thresholds:
    ax[1].axvline(thresh, color='r')

# Plot the Multi-Otsu result with color mapping.
ax[2].imshow(regions, cmap='jet')
ax[2].set_title('Multi-Otsu result')
ax[2].axis('off')

plt.subplots_adjust()
plt.show()

Output

Otsu Threshold
Advertisements