Session 09🌊
Advanced Edge Detection
Laplacian of Gaussian (LoG) for scale-aware edge detection and zero-crossing analysis.
Learning Objectives
- ✓Understand LoG as a second-derivative edge detector
- ✓Apply LoG convolution to images
- ✓Perform local maxima suppression
- ✓Detect zero-crossings and superimpose on original
Laplacian of Gaussian (LoG)
LoG combines Gaussian smoothing (to suppress noise) with the Laplacian (second derivative) to detect edges. Edges appear as zero-crossings in the LoG response. The Gaussian σ controls the scale of detected edges.
Ex9_1 — LoG convolutionPython
import cv2
import numpy as np
from scipy.ndimage import gaussian_laplace
img = cv2.imread('scene.jpg', cv2.IMREAD_GRAYSCALE).astype(np.float32)
# LoG with sigma=2
sigma = 2.0
log_response = gaussian_laplace(img, sigma=sigma)Local Maxima Suppression (LMS)
After LoG, suppress all non-maximum values to thin edge responses to single-pixel width. Compare each pixel to its neighbors; only keep values that are local maxima (or minima for negative responses).
Ex9_1 — Local maxima suppressionPython
from scipy.ndimage import maximum_filter, minimum_filter
# Threshold for significance
threshold = 0.5 * np.max(np.abs(log_response))
# Local maxima (positive LoG)
local_max = (log_response == maximum_filter(log_response, size=3))
significant_max = local_max & (log_response > threshold)
# Local minima (negative LoG)
local_min = (log_response == minimum_filter(log_response, size=3))
significant_min = local_min & (log_response < -threshold)
edge_map = significant_max | significant_minZero-Crossing Detection
A zero-crossing in the LoG response marks where the second derivative changes sign — the location of an edge. We detect these by checking sign changes between neighboring pixels.
Ex9_1 — Superimpose edges on originalPython
# Create output: original image with detected edges in red
img_rgb = cv2.cvtColor(img.astype(np.uint8), cv2.COLOR_GRAY2RGB)
output = img_rgb.copy()
# Mark edges in red
output[edge_map, 0] = 255 # R channel
output[edge_map, 1] = 0 # G channel
output[edge_map, 2] = 0 # B channel
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 4))
plt.subplot(1,3,1), plt.imshow(img, cmap='gray'), plt.title('Original'), plt.axis('off')
plt.subplot(1,3,2), plt.imshow(log_response, cmap='RdBu'), plt.title('LoG'), plt.axis('off')
plt.subplot(1,3,3), plt.imshow(output), plt.title('Edges'), plt.axis('off')
plt.tight_layout()
plt.show()