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.
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 noisyArithmetic 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_inv3. 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.