2D Image Smoothing#

We use the smooth module to smooth a 2D image.

Imports#

import numpy as np
import matplotlib.pyplot as plt
from splineops.denoise.smoothing_spline import smoothing_spline_nd

2D Image Smoothing#

import requests
from io import BytesIO
from PIL import Image

def create_image():
    """
    Loads a real grayscale image.
    """
    url = 'https://r0k.us/graphics/kodak/kodak/kodim06.png'
    response = requests.get(url)
    img = Image.open(BytesIO(response.content))
    data = np.array(img, dtype=np.float64)
    data /= 255.0  # Normalize to [0, 1]

    return data

def add_noise(img, snr_db):
    """
    Adds Gaussian noise to the image based on the desired SNR in dB.
    """
    signal_power = np.mean(img ** 2)
    sigma = np.sqrt(signal_power / (10 ** (snr_db / 10)))
    noise = np.random.randn(*img.shape) * sigma
    noisy_img = img + noise
    return noisy_img

def compute_snr(clean_signal, noisy_signal):
    """
    Compute the Signal-to-Noise Ratio (SNR).

    Parameters:
    clean_signal (np.ndarray): Original clean signal.
    noisy_signal (np.ndarray): Noisy signal.

    Returns:
    float: SNR value in decibels (dB).
    """
    signal_power = np.mean(clean_signal ** 2)
    noise_power = np.mean((noisy_signal - clean_signal) ** 2)
    snr = 10 * np.log10(signal_power / noise_power)
    return snr

def demo_image():
    # Parameters
    lambda_ = 0.1  # Regularization parameter
    gamma = 2.0     # Order of the spline operator
    snr_db = 10.0   # Desired SNR in dB

    # Load image
    img = create_image()
    noisy_img = add_noise(img, snr_db)
    smoothed_img = smoothing_spline_nd(noisy_img, lambda_, gamma)

    # Compute SNRs
    snr_noisy = compute_snr(img, noisy_img)
    snr_smooth = compute_snr(img, smoothed_img)
    snr_improvement = snr_smooth - snr_noisy

    print("Image:")
    print(f"SNR of noisy image: {snr_noisy:.2f} dB")
    print(f"SNR after smoothing: {snr_smooth:.2f} dB")
    print(f"SNR improvement: {snr_improvement:.2f} dB\n")

    # Visualization for image
    plt.figure(figsize=(12, 4))
    plt.subplot(1, 3, 1)
    plt.imshow(img, cmap='gray')
    plt.title('Original Image')
    plt.axis('off')

    plt.subplot(1, 3, 2)
    plt.imshow(noisy_img, cmap='gray')
    plt.title(f'Noisy Image (SNR={snr_noisy:.2f} dB)')
    plt.axis('off')

    plt.subplot(1, 3, 3)
    plt.imshow(smoothed_img, cmap='gray')
    plt.title(f'Smoothed Image (SNR={snr_smooth:.2f} dB)')
    plt.axis('off')

    plt.tight_layout()
    plt.show()

# Run the image demo
demo_image()
Original Image, Noisy Image (SNR=10.00 dB), Smoothed Image (SNR=17.69 dB)
Image:
SNR of noisy image: 10.00 dB
SNR after smoothing: 17.69 dB
SNR improvement: 7.69 dB

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers). Got range [-0.6702387206030012..1.76025280954446].
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers). Got range [-0.09837255519596473..1.1837520472210685].

Total running time of the script: (0 minutes 1.474 seconds)

Gallery generated by Sphinx-Gallery