Image Processing: Gradients, Filtering, Edge Detection, Frequency Domain, Histograms
762 words
4 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Image Processing: Gradients, Filtering, Edge Detection, Frequency Domain, Histograms ## 🎯 Learning Objectives - Compute image gradients and apply edge detection (Sobel, Canny) - Understand convolution filtering in spatial domain - Apply Fourier transform for frequency domain analysis - Use histogram equalization...

Image Processing: Gradients, Filtering, Edge Detection, Frequency Domain, Histograms
🎯 Learning Objectives
- Compute image gradients and apply edge detection (Sobel, Canny)
- Understand convolution filtering in spatial domain
- Apply Fourier transform for frequency domain analysis
- Use histogram equalization for contrast enhancement
- Bridge classical image processing with deep learning
📋 Prerequisites
- CNN Fundamentals (Week 1): Convolution operation
- Basic calculus: Partial derivatives, gradients
1. 📖 Core Content
1.1 Intuition: Why Classical IP for DL?
Deep learning learns filters from data, but classical image processing provides:
- Preprocessing: Normalize illumination, enhance contrast
- Feature engineering: Edge features for medical/industrial imagery
- Data augmentation: Filter-based augmentation
- Understanding: Gradient-based explanations (Saliency maps)
1.2 Image Gradients and Edge Detection
python# runnable import cv2 import numpy as np # Load image img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE) # Sobel gradients (x and y directions) grad_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) grad_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) # Gradient magnitude and direction magnitude = np.sqrt(grad_x**2 + grad_y**2) direction = np.arctan2(grad_y, grad_x) # Canny edge detection edges = cv2.Canny(img, threshold1=50, threshold2=150) print(f"Edge pixels: {np.sum(edges > 0)} of {edges.size}")
1.3 Frequency Domain Analysis
python# runnable import numpy as np import cv2 img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE) # Fourier transform f = np.fft.fft2(img) fshift = np.fft.fftshift(f) # Center low frequencies magnitude_spectrum = np.log(np.abs(fshift) + 1) # High-pass filter (edge enhancement) rows, cols = img.shape crow, ccol = rows // 2, cols // 2 mask = np.ones((rows, cols), np.uint8) r = 30 # Radius to block low frequencies mask[crow-r:crow+r, ccol-r:ccol+r] = 0 fshift_filtered = fshift * mask img_filtered = np.fft.ifft2(np.fft.ifftshift(fshift_filtered)) img_filtered = np.real(img_filtered) print(f"High-pass filtered: preserves edges, removes smooth regions")
1.4 Histogram Equalization
python# runnable import cv2 import numpy as np img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE) # Global histogram equalization equalized_global = cv2.equalizeHist(img) # CLAHE (adaptive, prevents noise amplification) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) equalized_clahe = clahe.apply(img) print(f"Original intensity range: [{img.min()}, {img.max()}]") print(f"Equalized range: [{equalized_global.min()}, {equalized_global.max()}]")
1.5 Classical Filters in Deep Learning Pipelines
python# runnable import torch import torch.nn.functional as F # Sobel filter as PyTorch layer class SobelFilter(torch.nn.Module): def __init__(self): super().__init__() # Sobel kernels sobel_x = torch.tensor([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1](/courses/bsda5006/notes/%5B-1%2C%200%2C%201%5D%2C%20%5B-2%2C%200%2C%202%5D%2C%20%5B-1%2C%200%2C%201)], dtype=torch.float32) sobel_y = torch.tensor([[-1, -2, -1], [0, 0, 0], [1, 2, 1](/courses/bsda5006/notes/%5B-1%2C%20-2%2C%20-1%5D%2C%20%5B0%2C%200%2C%200%5D%2C%20%5B1%2C%202%2C%201)], dtype=torch.float32) self.register_buffer('kernel_x', sobel_x.view(1, 1, 3, 3)) self.register_buffer('kernel_y', sobel_y.view(1, 1, 3, 3)) def forward(self, x): # x: (B, C, H, W), process each channel independently B, C, H, W = x.shape x = x.view(B*C, 1, H, W) grad_x = F.conv2d(x, self.kernel_x, padding=1) grad_y = F.conv2d(x, self.kernel_y, padding=1) magnitude = torch.sqrt(grad_x**2 + grad_y**2) return magnitude.view(B, C, H, W)
1.6 Why This Matters
Classical image processing is not obsolete — it's foundational. Modern architectures like Gabor filters in early vision layers, Fourier-based token mixing (FNet), and histogram-based preprocessing in medical imaging all build on these principles.
2. 📐 Key Formulas / Concepts
| Operation | Formula | Application |
|---|---|---|
| Sobel X | Gx=−1−2−1000121∗I | Vertical edge detection |
| Sobel Y | Gy=−101−202−101∗I | Horizontal edge detection |
| Gradient magnitude | $\ | G\ |
| Fourier transform | F(u,v)=∑∑f(x,y)e−j2π(ux/M+vy/N) | Frequency analysis |
| Histogram equalization | T(r)=∫0rp(w)dw | Contrast enhancement |
3. ⚠️ Common Pitfalls
Pitfall 1: Applying Filters Before Normalization
Mistake: Applying Sobel/Canny to unnormalized uint8 images without scaling.
Why: The filter responses depend on intensity ranges. A bright image produces larger gradients than a dark one with the same edge content.
Fix: Normalize image intensity (e.g., [0, 1]) before applying filters, or use gradient ratios.
Pitfall 2: Using Fourier Transform on Non-Periodic Images
Mistake: Applying FFT without windowing (Hamming/Hann).
Why: The FFT assumes the image is periodic. Image boundaries create high-frequency artifacts (spectral leakage).
Fix: Apply a window function before FFT:
img_windowed = img * np.hanning(rows).reshape(-1, 1) * np.hanning(cols).4. 📝 Practice Questions
Q1: An image has poor contrast — 80% of pixels are between [100, 120] out of [0, 255]. Which technique improves it?Histogram equalization is designed for this. It redistributes pixel intensities to use the full [0, 255] range:pythonimport cv2 equalized = cv2.equalizeHist(img)For extreme cases (like this), use CLAHE (adaptive histogram equalization) which operates on local tiles and prevents noise amplification:pythonclahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8)) result = clahe.apply(img)
5. 🔗 Cross-References
- Previous: Data Augmentation (Week 8)
- Next: Diffusion Models (Week 9)
- Related: CNN Fundamentals (Week 1) Join Discord PreviousVision TransformersNextDiffusion Models for CV