Scikit Image − Unsharp Mask Filter



Unsharp masking is a widely used image sharpening technique in image processing. It is a linear image operation and is known for its numerical stability, making it a preferred choice over deconvolution, which is often an ill-posed problem.

The fundamental concept behind unsharp masking is to enhance image sharpness by isolating the fine details present in the original image but not in a blurred version of it.

The formula for unsharp masking is often expressed as follows −

enhanced image = original + amount * (original - blurred)

To avoid issues like color bleeding while applying this technique to multi-channel images, it's advisable to process only the brightness, lightness, or intensity channel in a suitable color space, such as HSV, HSL, YUV, or YCbCr. This approach can yield more visually pleasing results while preserving color information.

The scikit-image (skimage) library provides a function called unsharp_mask() within its filter module for applying the Unsharp masking filter to images.

Using the skimage.filters.unsharp_mask() function

The unsharp_mask() function is used to apply an unsharp masking filter to an image. The technique finds the fine details by subtracting the blurred image from the original. These details are then adjusted and added back to the original image.

Syntax

Following is the syntax of this function −

skimage.filters.unsharp_mask(image, radius=1.0, amount=1.0, preserve_range=False, *, channel_axis=None)

Parameters

Here's an explanation of the parameters −

  • image ([P, …, ]M[, N][, C] ndarray): This parameter represents the input image to which the unsharp masking filter will be applied. The image can have one or multiple dimensions, including color channels.
  • radius (scalar or sequence of scalars, optional): It determines the extent of blurring applied to the image. If a scalar value is provided, it is used for all dimensions. If a sequence of values is provided, there must be one radius value for each dimension, except for the last dimension (for multichannel images). A radius of 0 means no blurring, and negative values are not allowed.
  • amount (scalar, optional): This parameter controls the amplification factor for enhancing image details. It can be a positive, negative, or zero value. Typically, it is a small positive number (e.g., 1.0) for enhancing details.
  • preserve_range (bool, optional): If set to True, it keeps the original range of values in the output image. If set to False, the input image is converted according to the conventions of img_as_float.
  • channel_axis (int or None, optional): This parameter is used to indicate which axis of the input array corresponds to color channels when dealing with multichannel images. If set to None, it assumes that the image is grayscale (single-channel). This parameter was introduced in scikit-image version 0.19.

Return value

The function returns an ndarray of float values, which represents the image with the unsharp masking filter applied.

Example

Here's an example of how to apply the Unsharp masking to an image using the unsharp_mask() function −

import numpy as np
import matplotlib.pyplot as plt
from skimage.filters import unsharp_mask

# Create an example input array
array = np.ones(shape=(5, 5), dtype=np.uint8) * 100
array[2, 2] = 120

# Apply unsharp_mask function
result = unsharp_mask(array, radius=0.5, amount=2, preserve_range=True)

# Display the input and output images
fig, axes = plt.subplots(1, 2, figsize=(10, 5))
ax = axes.ravel()

ax[0].imshow(array, cmap='gray')
ax[0].set_title('Input Image')
ax[0].axis('off')

ax[1].imshow(result, cmap='gray')
ax[1].set_title('Output after Unsharp Masking')
ax[1].axis('off')

plt.tight_layout()
plt.show()

Output

Unsharp Mask Filter

Example

The following example demonstrates the application of the unsharp masking filter to a color image using different values for the radius and amount parameters −

import matplotlib.pyplot as plt
from skimage import io
from skimage.filters import unsharp_mask

# Load an image 
image = io.imread('Images/group chat.jpg')

# Apply unsharp masking with different parameters
result_1 = unsharp_mask(image, radius=1, amount=1, channel_axis=1)
result_2 = unsharp_mask(image, radius=5, amount=2, channel_axis=1)
result_3 = unsharp_mask(image, radius=20, amount=1, channel_axis=1)

# Create a subplot grid for displaying images
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 10))
ax = axes.ravel()

# Display the original image and enhanced images with titles
ax[0].imshow(image, cmap=plt.cm.gray)
ax[0].set_title('Original image')
ax[0].axis('off')

ax[1].imshow(result_1, cmap=plt.cm.gray)
ax[1].set_title('Enhanced image, radius=1, amount=1.0')
ax[1].axis('off')

ax[2].imshow(result_2, cmap=plt.cm.gray)
ax[2].set_title('Enhanced image, radius=5, amount=2.0')
ax[2].axis('off')

ax[3].imshow(result_3, cmap=plt.cm.gray)
ax[3].set_title('Enhanced image, radius=20, amount=1.0')
ax[3].axis('off')

fig.tight_layout()
plt.show()

Output

Unsharp Mask Filter
Advertisements