Calibrating Denoisers Using J-Invariance



Calibrating denoisers using J-Invariance is a method for improving the performance of denoising algorithms, specifically for image denoising. The key concept behind this approach is the notion of J-invariance, which ensures that the denoising process is independent of the specific pixel values in the original noisy image.

The scikit image library provides a dedicated function called calibrate_denoiser() within its restoration modulte to calibrate denoisers using the J-Invariance.

Using the skimage.restoration.calibrate_denoiser() function

The restoration.calibrate_denoiser() function is used to calibrate a denoising function and return the optimal J-invariant version. The returned function is partially evaluated with optimal parameter values set for denoising the input image.

Syntax

Following is the syntax of this function −

skimage.restoration.calibrate_denoiser(image, denoise_function, denoise_parameters, *, stride=4, approximate_loss=True, extra_output=False)

Parameters

Here are the details of its parameters −

  • image (ndarray): Input data to be denoised. It is typically recommended to convert the input image using img_as_float before denoising.

  • denoise_function (function): The denoising function that to be calibrated.

  • denoise_parameters (dict of lists): Ranges of parameters for the denoise_function to be calibrated over.

  • stride (int, optional): The stride used in the masking procedure that converts denoise_function to J-invariance. The default value is 4.

  • approximate_loss (bool, optional): A boolean indicating whether to approximate the self-supervised loss used to evaluate the denoiser. If True, the loss is computed on one masked version of the image, which can significantly reduce runtime. If False, the runtime will be longer by a factor of stride**image.ndim but may result in more accurate evaluation.

  • extra_output (bool, optional): If True, the function will return additional information, including parameters and losses. The default value is False.

The output of the function is −

  • best_denoise_function (function): which indicates the optimal J-invariant version of the denoise_function calibrated with the best parameters.

If extra_output is True, the following tuple is also returned −

(parameters_tested, losses) tuple (list of dict, list of int)

  • parameters_tested: A list of dictionaries representing the parameters tested for denoise_function.

  • losses: A list of self-supervised loss values for each set of parameters in parameters_tested.

Example

This example demonstrates the process of calibrating a wavelet denoising function with specific parameters and applying it to denoise a noisy image.

import numpy as np
import matplotlib.pyplot as plt
from skimage import color, io
from skimage.restoration import denoise_wavelet, calibrate_denoiser

# Load an input image 
img = color.rgb2gray(io.imread('Images/Car_2.jpg'))

# Create a random number generator
rng = np.random.default_rng()

# Add Gaussian noise to the image
noisy = img + 0.5 * img.std() * rng.standard_normal(img.shape)

# Define denoising parameters for calibration
parameters = {'sigma': np.arange(0.1, 0.4, 0.02)}

# Calibrate the denoising function using noisy image and denoising parameters
denoising_function = calibrate_denoiser(noisy, denoise_wavelet,
   denoise_parameters=parameters)

# Apply the calibrated denoising function to the original image
denoised_img = denoising_function(img)

# Visualize the original, noisy, and denoised images
fig, axes = plt.subplots(1, 3, figsize=(12, 4))

# Original Image
axes[0].imshow(img, cmap='gray')
axes[0].set_title('Original Image')
axes[0].axis('off')

# Noisy Image
axes[1].imshow(noisy, cmap='gray')
axes[1].set_title('Noisy Image')
axes[1].axis('off')

# Denoised Image
axes[2].imshow(denoised_img, cmap='gray')
axes[2].set_title('Denoised Image (Calibrated)')
axes[2].axis('off')

plt.tight_layout()
plt.show()

Output

calibrating walevet denoiser

Example

The following example demonstrates the calibration of a denoising algorithm (specifically, the Total Variation(TV) Chambolle denoising algorithm) and compares the denoised results with and without calibration.

import numpy as np
import matplotlib.pyplot as plt
from skimage import io
from skimage.restoration import calibrate_denoiser, denoise_tv_chambolle
from skimage.util import img_as_float, random_noise
from functools import partial

# Load the input image
image = img_as_float(io.imread('Images/Tajmahal.jpg'))

# Add noise to the image
sigma = 0.4
noisy = random_noise(image, mode='speckle', var=sigma ** 2)

# Parameters to test when calibrating the denoising algorithm
parameter_ranges_tv = {'weight': np.arange(0.001, 0.02, 0.5),
   'max_num_iter':[100, 300]}

# Calibrate denoiser
calibrated_denoiser = calibrate_denoiser(noisy, denoise_tv_chambolle, denoise_parameters=parameter_ranges_tv)

# Denoised image using default parameters of `denoise_tv_chambolle`
default_output = denoise_tv_chambolle(noisy)

# Denoised image using calibrated denoiser
calibrated_output = calibrated_denoiser(noisy)

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True, figsize=(10, 8))
axes = axes.ravel() 

# Original Image
axes[0].imshow(image)
axes[0].set_title('Original Image')
axes[0].axis('off')

# Noisy Image
axes[1].imshow(noisy)
axes[1].set_title('Noisy Image')
axes[1].axis('off')

# Denoised (Default) Image
axes[2].imshow(default_output)
axes[2].set_title('Denoised (Default)')
axes[2].axis('off')

# Denoised (Calibrated) Image
axes[3].imshow(calibrated_output)
axes[3].set_title('Denoised Image (Calibrated)')
axes[3].axis('off')

plt.tight_layout()
plt.show()

Output

chambolle denoising algorithm
Advertisements