4.1 梯度與Sobel運算子#
概念說明#
影像 I(x, y) 的梯度 (gradient) 是一階偏微分向量:
∇I = (∂I/∂x, ∂I/∂y)
∂I/∂x 大表示水平方向亮度變化劇烈(垂直邊緣),∂I/∂y 大表示垂直方向變化劇烈(水平邊緣)。兩個純量組合出兩個有用物理量:
- 梯度大小 (magnitude):|∇I| = √(gx² + gy²),數值越大邊緣越強。
- 梯度方向 (orientation):θ = atan2(gy, gx),是亮度增加最快的方向;邊緣本身與之垂直。
數位影像上用小核心近似微分。最簡單是一階差分 [−1, 1],但對雜訊極敏感且無對稱性。Sobel 運算子 (1968) 把差分與平滑合成一個 3×3 核心——中央列/行權重加倍,等價於「先做 3 像素平均平滑、再做中央差分」:
Gx = [[−1, 0, 1], [−2, 0, 2], [−1, 0, 1]] Gy = [[−1, −2, −1], [0, 0, 0], [1, 2, 1]]
注意兩核心都是可分離的:Gx = [1,2,1]ᵀ · [−1,0,1],因此計算很快。Sobel 的優點:(1) 內建平滑,抗雜訊優於純差分;(2) 對稱的權重使方向估計較穩定。
與 Sobel 同期的還有 Prewitt(中央權重為 1)與 Scharr(權重 [3, 10, 3],對小 σ 旋轉不變性更佳)。實務上 3×3 Sobel 是預設選擇;需要更高精度方向時用 Scharr 或更大核心。
門檻化:算出梯度大小後,以門檻 T 分類——|∇I| ≥ T 判為邊緣。T 的選擇是雜訊與漏檢的折衷,這個問題在下一節由 Canny 的雙門檻機制更優雅地解決。
演算法步驟#
- (建議)先做輕度高斯平滑抑制雜訊。
- 用 Gx 對影像做卷積得 gx,用 Gy 得 gy。
- 計算大小 M = √(gx² + gy²),方向 θ = atan2(gy, gx)。
- 將 M 正規化到 0~255 供檢視。
- 以門檻 T 二值化 M,或直接把 M 當作邊緣強度圖使用。
Python 程式碼範例#
import numpy as np
from PIL import Image
# 40x40 影像:左半 50、右半 180 的垂直邊緣 + 少量雜訊
rng = np.random.default_rng(3)
img = np.where(np.arange(40) < 20, 50, 180).astype(np.float64)
img = np.tile(img, (40, 1)) + rng.normal(0, 5, (40, 40))
Gx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float64)
Gy = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]], dtype=np.float64)
def conv(img, K):
r = K.shape[0] // 2
P = np.pad(img, r, mode="edge")
H, W = img.shape
out = np.zeros((H, W))
for y in range(H):
for x in range(W):
out[y, x] = (P[y:y+3, x:x+3] * K).sum()
return out
gx, gy = conv(img, Gx), conv(img, Gy)
mag = np.sqrt(gx**2 + gy**2)
ang = np.degrees(np.arctan2(gy, gx))
print("理論梯度 ∂I/∂x = 130, ∂I/∂y = 0")
print("邊緣處 gx:", gx[20, 20], " gy:", gy[20, 20])
print("梯度大小:", mag[20, 20].round(1), " 方向(度):", ang[20, 20].round(1))
print("均勻區域 mag:", mag[5, 5].round(2))
# 門檻化
T = 100
edge = (mag >= T).astype(np.uint8) * 255
print("門檻", T, "偵測到的邊緣像素數:", (edge > 0).sum())
執行後:邊緣處 gx ≈ 4×130 = 520(Sobel 的 ∂I/∂x 近似值是差分和的 1/8,這裡未除以 8,故為 8×130/2 的尺度),gy ≈ 0,方向接近 0°;均勻區域(雜訊)梯度僅個位數。門檻 100 能把雜訊完全濾掉、只留真正的邊緣線。
複雜度分析#
兩個 3×3 卷積各 O(H·W·9),加上大小與方向的逐像素三角函數 O(H·W),總計 O(H·W)。因 Gx、Gy 可分離,用兩次一維卷積可降至 O(H·W·6) 次乘加。空間 O(H·W)(gx、gy、M 各一份)。若只要大小不要方向,可省 atan2(相對昂貴)。門檻化 O(H·W)。
練習#
- 把範例影像的邊緣改成 45° 斜邊,計算 gx、gy 與方向角,驗證方向是否如理論(邊緣法向 45°)。
- 實作 Scharr 核心 gx = [[−3,0,3],[−10,0,10],[−3,0,3]],與 Sobel 比較在 σ=2 雜訊下邊緣位置估計的穩定度。
- 對一張真實照片的灰階版求梯度大小圖,統計 M 的直方圖;討論門檻 T 該落在直方圖的哪個區域,以及 T 太低/太高各發生什麼。