第2章 图像梯度基础
数学概念 · 一阶与二阶导数 · 梯度幅值与方向
2.1 图像梯度的数学概念
图像梯度本质上是像素强度在空间上的变化率。对于连续函数 f(x, y),梯度向量定义为:
在数字图像中,我们用离散差分近似偏导数。梯度幅值表示边缘强度,梯度方向垂直于边缘走向。
2.2 一阶导数与二阶导数
一阶导数:检测边缘的位置(极值点)。常用算子:Sobel、Prewitt、Roberts。
二阶导数:通过零交叉定位边缘,对噪声更敏感。典型算子:Laplacian。
| 导数阶数 | 数学表达 (离散) | 边缘响应 | 典型算子 |
|---|---|---|---|
| 一阶 | Gx = I(x+1,y) − I(x,y) | 峰值 / 谷值 | Sobel, Scharr |
| 二阶 | ∇²I = ∂²I/∂x² + ∂²I/∂y² | 零交叉 | Laplacian |
一阶导数产生“粗”边缘,二阶导数能更精确地定位边缘中心,但容易放大噪声。
2.3 梯度幅值与方向的计算
给定水平梯度 Gx 和垂直梯度 Gy,幅值和方向为:
实际计算中常用值近似幅值:|G| ≈ |Gx| + |Gy| 以提升速度。
Python 实现:梯度幅值与方向
import cv2
import numpy as np
# 读取灰度图像
img = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)
# 计算一阶梯度 (Sobel)
grad_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
grad_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
# 梯度幅值
magnitude = np.sqrt(grad_x**2 + grad_y**2)
# 梯度方向 (弧度)
angle = np.arctan2(grad_y, grad_x)
# 将幅值归一化到 0~255
magnitude = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
print("梯度幅值形状:", magnitude.shape)
方向角通常用于非极大值抑制(Canny 边缘检测的核心步骤),将连续角度离散为 0°、45°、90°、135°。
常见一阶梯度算子对比
| 算子 | 核心 (3×3) | 特点 |
|---|---|---|
| Sobel | Gx: [[-1,0,1],[-2,0,2],[-1,0,1]] | 平滑+差分,抑制噪声 |
| Scharr | Gx: [[-3,0,3],[-10,0,10],[-3,0,3]] | 更精确的梯度,弱噪声 |
| Prewitt | Gx: [[-1,0,1],[-1,0,1],[-1,0,1]] | 无加权,简单快速 |
| Roberts | 2×2 核: [[1,0],[0,-1]] | 边缘定位准,对噪声敏感 |