Assignment Chef icon Assignment Chef
All English tutorials

Programming lesson

Digital Image Processing Tutorial: Filtering, Restoration, and Compression with OpenCV (2026)

Master frequency domain filtering, image restoration, and Huffman coding in this comprehensive digital image processing tutorial. Includes OpenCV DFT, ideal filters, noise removal, and compression with practical examples.

digital image processing tutorial OpenCV DFT example frequency domain filtering ideal low pass filter ideal high pass filter salt and pepper noise removal median filter vs mean filter inverse filtering image restoration Huffman coding compression ratio image compression quantization Python image processing assignment OpenCV idft inverse transform Gaussian blur deblurring phase angle vs magnitude spectrum ringing artifacts ideal filter JPEG compression tutorial

Introduction to Digital Image Processing in 2026

Digital image processing is more relevant than ever in 2026, powering everything from AI-generated art to autonomous vehicle vision systems. This tutorial covers three core assignments: frequency domain filtering, image degradation and restoration, and data compression using Huffman coding. We'll use Python and OpenCV to implement these techniques, with examples inspired by current trends like real-time video filters in social apps and medical imaging advancements.

1. Filtering in the Frequency Domain

Applying 2D DFT with OpenCV

The 2D Discrete Fourier Transform (DFT) converts an image from spatial domain to frequency domain, revealing which frequency components make up the image. In OpenCV, cv2.dft() computes the DFT. The skeleton code assignment2_1.py requires filling lines 19-22 to compute and visualize the Fourier power spectrum and phase angle.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('image.png', 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1]))
phase = np.angle(dft_shift[:,:,0] + 1j * dft_shift[:,:,1])

The power spectrum shows the magnitude of each frequency component, while the phase angle encodes the location of edges and textures. A typical example: in a selfie from a popular AI photo app, the low frequencies represent smooth skin tones, while high frequencies capture hair strands and eyelashes.

Phase Angle vs Power Spectrum

The power spectrum indicates how much of each frequency is present. The phase angle is critical for image structure; without it, the image becomes unrecognizable. For instance, swapping phases between a cat and a dog image produces a cat-like structure with dog textures. Frequency components relate to image content: low frequencies correspond to slowly varying regions (e.g., sky), high frequencies to edges and noise.

Ideal Low-Pass and High-Pass Filters

An ideal low-pass filter (ILPF) keeps frequencies below a cutoff (here 30) and removes higher ones. Conversely, an ideal high-pass filter (IHPF) does the opposite. After filtering, use cv2.idft() to transform back. In the skeleton code, lines 48-58 implement ILPF, and lines 60-64 implement IHPF.

rows, cols = img.shape
crow, ccol = rows//2, cols//2
mask_low = np.zeros((rows, cols, 2), np.uint8)
mask_low[crow-30:crow+30, ccol-30:ccol+30] = 1
fshift_low = dft_shift * mask_low
f_ishift_low = np.fft.ifftshift(fshift_low)
img_low = cv2.idft(f_ishift_low)
img_low = cv2.magnitude(img_low[:,:,0], img_low[:,:,1])

Ideal filters cause ringing artifacts (Gibbs phenomenon) due to sharp cutoff, making them unsuitable for real-world applications like medical image denoising where smooth transitions are needed. Practical filters (e.g., Gaussian) are preferred.

2. Image Degradation and Restoration

Salt-and-Pepper Noise Degradation

Salt-and-pepper noise randomly sets pixels to white (salt) or black (pepper). In the skeleton code assignment2_2.py, lines 22-30 add noise with probability 0.25 for each. This mimics corrupted sensor data, common in low-light photography from smartphone cameras in 2026.

def add_noise(img, prob_salt=0.25, prob_pepper=0.25):
    noisy = img.copy()
    total = img.size
    # Salt
    num_salt = int(total * prob_salt)
    coords = [np.random.randint(0, i-1, num_salt) for i in img.shape]
    noisy[coords[0], coords[1]] = 255
    # Pepper
    num_pepper = int(total * prob_pepper)
    coords = [np.random.randint(0, i-1, num_pepper) for i in img.shape]
    noisy[coords[0], coords[1]] = 0
    return noisy

Arithmetic Mean Filter vs Median Filter

The arithmetic mean filter (kernel 7x7) replaces each pixel with the average of its neighborhood, reducing noise but blurring edges. The median filter replaces with the median, effectively removing salt-and-pepper noise while preserving edges—like a smart photo editor in a social media app. For a 7x7 kernel, median filter outperforms mean filter in restoration quality.

Inverse Filtering for Gaussian Blur

When an image is blurred by a known low-pass Gaussian filter, inverse filtering can restore it. However, noise amplification occurs near zeros in the filter's frequency response. By applying a cutoff radius (e.g., 40 and 110), we limit the inversion to frequencies with significant signal. A radius of 110 retains more detail but may amplify noise; radius 40 gives smoother results. This trade-off is crucial in satellite image deblurring used in climate monitoring.

# Inverse filter with cutoff
H = np.load('gaussian_low_pass.npy')
cutoff = 40
H_inv = np.where(np.abs(H) > 1e-6, 1/H, 0)
H_inv[np.abs(H) < 1e-6] = 0
# Apply inverse
F_hat = F * H_inv

3. Data Compression via Huffman Coding

Huffman Tree Construction

Given the string 'AAABBCCCCCCCDDDAAAAA', we count frequencies: A=9, B=2, C=7, D=3. Build a min-heap, combine lowest frequencies, assign codes (e.g., A=0, C=11, D=101, B=100). Hand-draw the tree for your report.

Compression Ratio Calculation

Original bits: 21 characters × 8 = 168 bits. After Huffman: A:9×1=9, B:2×3=6, C:7×2=14, D:3×3=9, total=38 bits. Compression ratio = 168/38 ≈ 4.42:1. This principle is used in JPEG image compression, which is foundational for streaming high-resolution video on platforms like YouTube.

JPEG-Like Compression with Quantization

In assignment2_3.py, adjust quantization tables (lines 29-55) to change compression level. Higher quantization values discard more high-frequency data, reducing file size but causing block artifacts. For a 512x512 RGB image, lowering quantization yields near-lossless quality for medical imaging, while higher values are acceptable for social media thumbnails.

Conclusion

This tutorial demonstrates key digital image processing techniques: frequency domain filtering, noise restoration, and compression. Understanding these concepts is essential for developing modern image-based applications, from AI photo enhancement to efficient data storage. Practice with the provided skeleton codes to solidify your skills.