第3章 · 图像梯度与导数
一阶导数 · 二阶导数 · Sobel · Scharr · 梯度幅值与方向
1. 一阶导数与二阶导数
图像可以视为二元函数 f(x, y),导数描述灰度变化率。一阶导数检测边缘的存在(变化剧烈处),二阶导数的零交叉点对应边缘中心。离散图像中,差分近似微分:
一阶差分: ∂f/∂x ≈ f(x+1) − f(x) | ∂f/∂y ≈ f(y+1) − f(y)
二阶差分: ∂²f/∂x² ≈ f(x+1) + f(x-1) − 2f(x)
二阶差分: ∂²f/∂x² ≈ f(x+1) + f(x-1) − 2f(x)
2. Sobel算子
Sobel 结合高斯平滑与差分,对噪声有抑制作用。常用 3×3 核:
| 方向 | 卷积核 | 特性 |
|---|---|---|
| Gx (水平) | [[-1,0,1],[-2,0,2],[-1,0,1]] | 检测垂直边缘 |
| Gy (垂直) | [[-1,-2,-1],[0,0,0],[1,2,1]] | 检测水平边缘 |
梯度幅值 |G| = √(Gx² + Gy²),方向 θ = atan2(Gy, Gx)。
3. Scharr算子
Scharr 算子优化了旋转对称性,对弱边缘响应更强。3×3 核系数:
| Gx | Gy |
|---|---|
[[-3,0,3],[-10,0,10],[-3,0,3]] | [[-3,-10,-3],[0,0,0],[3,10,3]] |
相比 Sobel,Scharr 各向同性更优,适合需要精确梯度方向的场景。
4. 梯度幅值与方向计算
对每个像素,合并 Gx 与 Gy 得到幅值图和方向图。方向通常量化为 0°, 45°, 90°, 135°。
OpenCV 快速实现
import cv2
import numpy as np
img = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)
# Sobel
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
mag = np.sqrt(sobel_x**2 + sobel_y**2)
phase = np.arctan2(sobel_y, sobel_x)
# Scharr (ksize=-1 自动使用 Scharr)
scharr_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=-1)
scharr_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=-1)
5. 算子对比总结
| 算子 | 类型 | 核大小 | 特点 |
|---|---|---|---|
| 一阶差分 | 基础梯度 | 2×1 / 1×2 | 对噪声敏感 |
| Sobel | 平滑+差分 | 3×3 (可扩展) | 常用,抑制噪声 |
| Scharr | 优化各向同性 | 3×3 | 更精确的方向响应 |
| 二阶 (Laplacian) | 二阶导数 | 3×3 | 零交叉定位 |