Edge Detection
簡單介紹
edge detection (邊緣檢測) 要檢測出圖像中的突然變化或者說是不連續情況。這樣好處是:
- 從邊緣中可以獲得圖像的語義信息和形狀信息;
- 邊緣信息比圖像像素信息更緊湊;
當然邊緣肯定也會丟失相應的紋理信息,但是在某些不關心紋理的任務上比較合適,如果說最近比較火的無人車的車道檢測。
圖像中邊緣產生有幾種原因如下:
邊緣檢測輸入是單通道圖像(灰度圖、RGB每個通道或者HSV的每個通道都可以),輸出是和原圖大小一致的二值化的邊緣檢測結果,每個像素點邊緣檢測結果取值 {0,1},分別表示該像素點是不是邊緣點。同時檢測的邊緣寬度需要儘可能小。
有限差分濾波器
邊緣是圖像中像素強度快速變化的地方,所以爲了要評估的是變化值,需要對像素強度求一階導數,一階導數極大值和極小值就是要找的邊緣,如下圖所示:
對於連續函數 f(x,y) 來說,x 的一階偏導數公式爲:
∂x∂f(x,y)=ε→0limεf(x+ε,y)−f(x,y)
但對於圖像這種離散函數 f(x,y) 來說,使用有限差分來估計 x 的一階偏導數,公式爲:
∂x∂f(x,y)≈1f(x+1,y)−f(x,y)
其中 f(x,y) 表示該點的像素值,一般是灰度值。
需要在整張圖上做相應的操作,可以轉化成濾波器和圖像做卷積,如下圖所示:
x 方向的濾波器爲 [−1,1],y 方向的濾波器爲 [−1,1]T。
後面爲了優化效果和魯棒性,提出了一些改進版本的有限差分濾波器,也就是常說的邊緣檢測算子。
Prewitt 算子
Mx=⎣⎡−1−1−1000111⎦⎤;My=⎣⎡10−110−110−1⎦⎤
Sobel 算子
Mx=⎣⎡−1−2−1000121⎦⎤;My=⎣⎡10−120−210−1⎦⎤
Roberts 算子
Mx=[0−110];My=[100−1]
方向和強度
圖像梯度公式爲:
∇f=[∂x∂f,∂y∂f]
那不同的方向梯度如下圖所示:
上面紅色箭頭表示梯度方向,是圖像像素變化最快的方向,也就是和邊緣垂直的方向,這樣邊緣方向通過圖像梯度也確定了。梯度方向角度爲:
θ=tan−1(∂y∂f/∂x∂f)(1.1)
同理邊緣強度可以由梯度幅度確定:
∥∇f∥=(∂x∂f)2+(∂y∂f)2(1.2)
噪聲平滑
圖像邊緣檢測基本流程沒問題了,但是在實際使用過程中會受到噪聲的影響,導致檢測出來很多錯誤的邊緣,如下圖所示:
上圖只考慮圖像的一行或者一列來進行求偏導,從偏導值來看沒法確定邊緣的位置,或者說每個像素都是邊緣。
解決這個問題就是需要把那些微小的像素值的變化也就是噪聲平滑掉,所以在求偏導之前先進行圖像的平滑,那麼效果如下圖所示:
這樣平滑後偏導的峯值就是要檢測的邊緣。
由卷積導數定理得到,參考:
dxd(f∗g)=f∗dxdg
所以操作減少一個,如下圖所示:
這樣得到的峯值和上面相同,但是實際情況下(Canny)還是使用第一種方案,先對圖像進行高斯模糊,在利用算子求圖像梯度,確定方向和強度,後面精確定位邊緣以及稀疏化都會用到這些值。
經過上面討論確定高斯模糊是邊緣檢測必須的一個操作,但是高斯核大小如何確定,直觀來看,高斯核尺寸越大,對噪聲越不敏感,魯棒性越強,但是會使圖像變得更加模糊,邊緣精確位置誤差會增大,如下圖所示:
經驗來說,一般設置高斯模核大小爲 3。
邊緣檢測器
這樣整個流程就明確了,給定圖像 I,根據應用需求選定一個邊緣檢測算子(有限差分濾波器),得到 x,y 方向上的一階偏導圖,利用公式 (1.1) 和 (1.2) 得到每個像素點對應的邊緣方向和強度值。
但是從上面的結果到最後得到精確到二值化邊緣檢測結果還需要非極大值抑制、雙閾值檢測以及抑制某些孤立點等,這個其實就是經典的 Canny 邊緣檢測算法的主要過程。有篇博客講的非常好,這裏就不再重複了,具體鏈接:https://www.cnblogs.com/techyan1990/p/7291771.html。