Module 2: Image Processing
Comprehensive image processing operations including filtering, morphology, edge detection, and histogram analysis.
Topics Covered
- Image filtering (blur, sharpen)
- Morphological operations
- Edge detection
- Contour detection and analysis
- Color spaces and histograms
Algorithm Explanations
1. Convolution (Filtering)
What it does: Applies a kernel (filter) to an image by sliding it over each pixel.
Mathematical Formula:
G(x,y) = Σᵢ Σⱼ K(i,j) × I(x+i, y+j)
Where:
G(x,y): output pixelK: kernel (filter matrix)I: input image- Sum over kernel dimensions
Convolution Process Visualization:
Input Image Kernel (3×3)
┌───┬───┬───┬───┬───┬───┐ ┌────┬────┬────┐
│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ │ k00│ k01│ k02│
├───┼───┼───┼───┼───┼───┤ ├────┼────┼────┤
│ 7 │ 8 │ 9 │10 │11 │12 │ │ k10│ k11│ k12│
├───┼───┼───┼───┼───┼───┤ ├────┼────┼────┤
│13 │14 │15 │16 │17 │18 │ │ k20│ k21│ k22│
├───┼───┼───┼───┼───┼───┤ └────┴────┴────┘
│19 │20 │21 │22 │23 │24 │
└───┴───┴───┴───┴───┴───┘
Step 1: Position kernel Step 2: Multiply & Sum Step 3: Slide kernel
┌───────────────┐ Output = k00×1 + k01×2 ┌───────────────┐
│┌───┬───┬───┐ │ + k02×3 + k10×7 │ ┌───┬───┬───┐│
││ 1 │ 2 │ 3 │ │ + k11×8 + k12×9 │ │ 2 │ 3 │ 4 ││
│├───┼───┼───┤ │ + k20×13 + k21×14 │ ├───┼───┼───┤│
││ 7 │ 8 │ 9 │ │ + k22×15 │ │ 8 │ 9 │10 ││
│├───┼───┼───┤ │ │ │ ├───┼───┼───┤│
││13 │14 │15 │ │ ▼ │ │14 │15 │16 ││
│└───┴───┴───┘ │ Output[1,1] │ └───┴───┴───┘│
└───────────────┘ └───────────────┘
Repeat...
2. Box Filter (Averaging)
What it does: Replaces each pixel with the average of its neighborhood.
Kernel (3×3):
1 [1 1 1]
K = ─── [1 1 1]
9 [1 1 1]
Effect Visualization:
Before (sharp edge): After (blurred edge):
┌────────────────────┐ ┌────────────────────┐
│████████│ │ │████████▓▓░░ │
│████████│ │ ──► │████████▓▓░░ │
│████████│ │ │████████▓▓░░ │
└────────────────────┘ └────────────────────┘
Gradual transition
OpenCV: cv2.blur(src, (ksize, ksize))
3. Gaussian Blur
What it does: Weighted average where center pixels have more influence (bell curve).
Gaussian Kernel Formula:
G(x,y) = (1 / 2πσ²) × exp(-(x² + y²) / 2σ²)
Gaussian Bell Curve (1D cross-section):
Weight
▲
1.0│ ╭─────╮
│ ╱ ╲
│ ╱ ╲
0.5│ ╱ ╲
│ ╱ ╲
│ ╱ ╲
0.0│──╱─────────────────╲──►
-3σ -σ 0 σ 3σ Distance from center
Center pixel
has most weight
5×5 Gaussian Kernel (σ ≈ 1):
1 [ 1 4 7 4 1] Visualized:
K = ─── [ 4 16 26 16 4] ░ = low weight
273 [ 7 26 41 26 7] ▓ = medium
[ 4 16 26 16 4] █ = high weight
[ 1 4 7 4 1]
[░ ░ ▓ ░ ░]
[░ ▓ █ ▓ ░]
[▓ █ █ █ ▓]
[░ ▓ █ ▓ ░]
[░ ░ ▓ ░ ░]
OpenCV: cv2.GaussianBlur(src, (ksize, ksize), sigma)
4. Median Filter
What it does: Replaces each pixel with the median of its neighborhood.
Algorithm:
Neighborhood: Sorted values: Result:
┌─────┬─────┬─────┐
│ 120 │ 35 │ 115 │ [35, 98, 105, 110, Center pixel
├─────┼─────┼─────┤ 115, 115, 118, 120, replaced with
│ 105 │[255]│ 98 │ 255] median = 115
├─────┼─────┼─────┤ ↑
│ 110 │ 115 │ 118 │ middle value
└─────┴─────┴─────┘
Spike noise (255) is completely removed!
Salt-and-Pepper Noise Removal:
With Noise Gaussian Blur Median Filter
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ ▪ ▪ ▪ │ │ still visible │ │ │
│ ▪ ▪ │ ──► │ blurred spots │ │ Clean image! │
│ ▪ ▪ ▪ │ │ everywhere │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
(poor) (excellent)
OpenCV: cv2.medianBlur(src, ksize)
5. Bilateral Filter
What it does: Smooths while preserving edges using both spatial and intensity distance.
How it works:
Spatial Weight Intensity Weight
(distance-based) (similarity-based)
× ×
Near pixels Similar intensity
weighted more weighted more
│ │
▼ ▼
┌───────┐ ┌───────┐
│ █ █ █ │ │ █ ░ █ │
│ █ ● █ │ × │ █ ░ █ │ = Final weight
│ █ █ █ │ │ █ ░ █ │
└───────┘ └───────┘
Distance from Different intensity
center pixel = low weight
Edge Preservation:
┌────────────────────┐ ┌────────────────────┐
│███████████│░░░░░░░░│ ──► │███████████│░░░░░░░░│
│███████████│░░░░░░░░│ │███████████│░░░░░░░░│
│███████████│░░░░░░░░│ │███████████│░░░░░░░░│
└────────────────────┘ └────────────────────┘
Sharp edge Edge preserved!
(only similar pixels averaged)
OpenCV: cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)
6. Sharpening
What it does: Enhances edges and fine details.
Sharpening Kernel:
[ 0 -1 0]
K = [-1 5 -1] Center = 5, neighbors = -1
[ 0 -1 0] Sum = 1 (maintains brightness)
How sharpening works:
Original: Blurred: Original - Blurred = Edges:
┌───────────┐ ┌───────────┐ ┌───────────┐
│░░░░████░░░│ │░░░▓▓▓▓▓░░░│ │ ▓▓ ▓▓ │
│░░░░████░░░│ - │░░░▓▓▓▓▓░░░│ = │ ▓▓ ▓▓ │ (edge detail)
│░░░░████░░░│ │░░░▓▓▓▓▓░░░│ │ ▓▓ ▓▓ │
└───────────┘ └───────────┘ └───────────┘
Original + α × Edges = Sharpened:
┌───────────┐
│░░░░████░░░│ + edges = Enhanced edges!
│░░░░████░░░│
└───────────┘
7. Morphological Operations
Structuring Element (Kernel)
Rectangle: Ellipse: Cross: Diamond:
[1 1 1] [0 1 0] [0 1 0] [0 0 1 0 0]
[1 1 1] [1 1 1] [1 1 1] [0 1 1 1 0]
[1 1 1] [0 1 0] [0 1 0] [1 1 1 1 1]
[0 1 1 1 0]
[0 0 1 0 0]
Erosion
What it does: Shrinks white regions, removes small noise.
Original: Erosion: Effect:
┌─────────────────┐ ┌─────────────────┐
│ ████████████ │ │ ████████ │ - Shrinks objects
│ ████████████ │──► │ ████████ │ - Removes small spots
│ ████████████ │ │ ████████ │ - Separates touching objects
│ ▪ ▪ ▪ │ │ │
└─────────────────┘ └─────────────────┘
Small spots removed!
Dilation
What it does: Expands white regions, fills small holes.
Original: Dilation: Effect:
┌─────────────────┐ ┌─────────────────┐
│ ████████ │ │ ████████████ │ - Expands objects
│ █▪█▪████ │──► │ ████████████ │ - Fills small holes
│ ████████ │ │ ████████████ │ - Connects nearby objects
└─────────────────┘ └─────────────────┘
Holes filled!
Opening = Erosion → Dilation
Original Erode Dilate
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ ████████████ │ │ ████████ │ │ ████████████ │
│ ████████████ │──►│ ████████ │──►│ ████████████ │
│ ▪ ▪ ▪ │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Noise removed Shape restored
Closing = Dilation → Erosion
Original Dilate Erode
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ ████████ │ │ ████████████ │ │ ████████ │
│ █▪█▪████ │──►│ ████████████ │──►│ ████████ │
│ ████████ │ │ ████████████ │ │ ████████ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Holes filled Shape restored
Morphological Gradient = Dilation - Erosion
Original Dilation - Erosion = Gradient (Edge)
┌─────────────────┐ ┌─────────────────┐
│ │ │ │
│ ████████ │──►│ ┌──────┐ │ Only boundaries
│ ████████ │ │ │ │ │ are visible!
│ ████████ │ │ └──────┘ │
│ │ │ │
└─────────────────┘ └─────────────────┘
8. Edge Detection
Sobel Operator
What it does: Computes first derivative (gradient) in X or Y direction.
Kernels:
Sobel X (vertical edges): Sobel Y (horizontal edges):
[-1 0 1] [-1 -2 -1]
[-2 0 2] [ 0 0 0]
[-1 0 1] [ 1 2 1]
Direction Detection:
Sobel X detects │ Sobel Y detects ───
│
┌───────────────────────┼───────────────────────┐
│ │ │
│ Detects: █ │ ░ │ Detects: ████ │
│ █ │ ░ │ ──── │
│ █ │ ░ │ ░░░░ │
│ │ │
└───────────────────────┴───────────────────────┘
Gradient Magnitude and Direction:
Gx Gy
──► ──►
G = √(Gx² + Gy²) θ = arctan(Gy/Gx)
│ │
▼ ▼
Edge strength Edge direction
Canny Edge Detection Pipeline
Step 1: Gaussian Blur Step 2: Gradient (Sobel)
┌─────────────────┐ ┌─────────────────┐
│ Noisy image │ ──► │ Gradient magnitude│
│ with edges │ │ and direction │
└─────────────────┘ └─────────────────┘
│ │
▼ ▼
Step 3: Non-Max Suppression Step 4: Double Threshold
┌─────────────────┐ ┌─────────────────┐
│ Thin edges to │ ──► │ Strong / Weak │
│ 1-pixel width │ │ edge pixels │
└─────────────────┘ └─────────────────┘
│ │
▼ ▼
Step 5: Hysteresis Final Output
┌─────────────────┐ ┌─────────────────┐
│ Connect weak to │ ──► │ Clean, thin │
│ strong edges │ │ edge map │
└─────────────────┘ └─────────────────┘
Non-Maximum Suppression Detail:
Gradient direction: →
┌───┬───┬───┐ Only keep if pixel is
│ a │ b │ c │ maximum along gradient
├───┼───┼───┤ direction:
│ d │[P]│ e │ ──► Keep P if P > d AND P > e
├───┼───┼───┤
│ f │ g │ h │
└───┴───┴───┘
Double Threshold:
Pixel Intensity
▲
│ ┌──────────────────── Strong Edge (keep)
High │......│......................
│ │
│ │ Weak Edge (maybe keep)
Low │------│----------------------
│ │
│ │ Non-edge (discard)
0 └──────┴─────────────────────►
Pixels
9. Contour Detection
What it does: Finds continuous curves bounding objects.
Contour Hierarchy:
Image with nested contours:
┌─────────────────────────────────────────┐
│ ┌─────────────────────────────────┐ │
│ │ Contour 0 (outer) │ │
│ │ ┌───────────────────────┐ │ │
│ │ │ Contour 1 (hole) │ │ │
│ │ │ ┌───────────────┐ │ │ │
│ │ │ │ Contour 2 │ │ │ │
│ │ │ │ (nested) │ │ │ │
│ │ │ └───────────────┘ │ │ │
│ │ └───────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
Hierarchy: [Next, Previous, First_Child, Parent]
Contour 0: [-1, -1, 1, -1] ◄── Has child 1
Contour 1: [-1, -1, 2, 0] ◄── Parent is 0, has child 2
Contour 2: [-1, -1, -1, 1] ◄── Parent is 1, no children
Contour Approximation (Douglas-Peucker):
Original contour: Approximated:
●───●───● ●─────●
/ \ / \
● ● ──► ● ●
\ / \ /
●───●───● ●─────●
Reduces number of points while preserving shape
epsilon controls simplification level
10. Color Spaces
BGR to HSV Conversion:
BGR HSV
┌───────────────┐ ┌───────────────┐
│ Blue:0-255 │ │ Hue: 0-180 │ ◄── Color type
│ Green:0-255 │ ──► │ Sat: 0-255 │ ◄── Color purity
│ Red:0-255 │ │ Val: 0-255 │ ◄── Brightness
└───────────────┘ └───────────────┘
HSV Color Wheel:
Red(0)
╱╲ Saturation: center=0, edge=255
╱ ╲ Value: dark=0, bright=255
Yellow Magenta
╲ ╱
╲ ╱
Green──Cyan──Blue
(60) (90) (120)
Common HSV Color Ranges:
Color H (Hue) S (Sat) V (Val)
─────────────────────────────────────────────────
Red 0-10, 170-180 100-255 100-255
Orange 10-25 100-255 100-255
Yellow 25-35 100-255 100-255
Green 35-85 100-255 100-255
Blue 85-130 100-255 100-255
Purple 130-170 100-255 100-255
11. Histogram Operations
Histogram Visualization
Pixel count
▲
200 │ ┌──┐
│ │ │
150 │ ┌──┤ │ ┌──┐
│ │ │ │ │ │
100 │ │ │ ├──┐ │ │
│ │ │ │ │ │ ├──┐
50 │ │ │ │ ├──┤ │ │
│ │ │ │ │ │ │ │
0 └─┴──┴──┴──┴──┴──┴──┴──►
0 32 64 96 128 160 192 255
Pixel intensity
Histogram Equalization
Before (low contrast): After (equalized):
▲ Concentrated ▲ Spread out
200 │ ████ 200│ ┌┐┌┐┌┐┌┐┌┐┌┐┌┐
│ ████ │ ││││││││││││││
100 │ ████ ──► 100│ ││││││││││││││
│ ████ │ ││││││││││││││
0 └────────────► 0 └────────────────►
0 128 255 0 128 255
Image appears to use Pixels spread across
only middle gray values full intensity range
= low contrast = better contrast
CLAHE (Adaptive Histogram Equalization)
Standard Equalization: CLAHE (tile-based):
┌───────────────────┐ ┌────┬────┬────┬────┐
│ │ │ eq │ eq │ eq │ eq │
│ Single histogram │ vs ├────┼────┼────┼────┤
│ for entire image │ │ eq │ eq │ eq │ eq │
│ │ ├────┼────┼────┼────┤
│ │ │ eq │ eq │ eq │ eq │
└───────────────────┘ └────┴────┴────┴────┘
Each tile equalized
May over-amplify noise separately, then
in homogeneous regions interpolated at borders
Filter Comparison
Original Box Blur Gaussian Median Bilateral
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│Sharp │ │Uniform │ │Smooth │ │Salt& │ │Smooth │
│edges │──► │blur │ │blur │ │pepper │ │but │
│+ noise │ │+ edges │ │+ edges │ │removed │ │edges │
│ │ │blurred │ │softened │ │ │ │preserved│
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
Fastest Good balance Best for Best edge
impulse noise preservation
Tutorial Files
| File | Description |
|---|---|
01_filtering.py |
Box blur, Gaussian, median, bilateral, custom kernels, sharpening |
02_morphology.py |
Erosion, dilation, opening, closing, gradient, top/black hat |
03_edges_contours.py |
Sobel, Laplacian, Canny, contour detection and analysis |
04_color_histogram.py |
Color spaces, HSV, histograms, CLAHE, color segmentation |
Key Functions Reference
| Function | Description |
|---|---|
cv2.blur() |
Box filter |
cv2.GaussianBlur() |
Gaussian blur |
cv2.medianBlur() |
Median filter |
cv2.bilateralFilter() |
Edge-preserving smooth |
cv2.filter2D() |
Custom kernel |
cv2.erode() |
Morphological erosion |
cv2.dilate() |
Morphological dilation |
cv2.morphologyEx() |
Opening, closing, gradient, etc. |
cv2.Sobel() |
Sobel derivatives |
cv2.Laplacian() |
Laplacian operator |
cv2.Canny() |
Canny edge detection |
cv2.findContours() |
Find contours |
cv2.drawContours() |
Draw contours |
cv2.cvtColor() |
Color space conversion |
cv2.calcHist() |
Calculate histogram |
cv2.equalizeHist() |
Histogram equalization |
cv2.createCLAHE() |
Adaptive equalization |