討論索伯算子 Sobel 的 Convolution 問題

Rifur Ni
6 min readMay 10, 2018

--

索伯算子 Sobel Operator 是影像處理中用來做邊緣檢測的一種方法。讀者可以直觀的想像,我們能清楚鮮明地看到照片中的物體,是因為他光影變化明顯,這光影變化在術語上就是所謂「梯度」(gradient),找到梯度之後我們就能更方便進行例如物品識別之類的後續工作,而 sobel operator 就是方便我們計算梯度的工具。

具體做法,是將一個 3x3 的遮罩矩陣 sobel operator,在影像上作卷積(convolution,或迴積。哪個翻譯更妥當?請賜教),就會得到自然影像的梯度變化。經過 sobel operation 之後,將大於設定的門檻值(threshold),也就是變化明顯的部分留下來,得到我們要的邊緣。

這裡產生兩個問題。第一個,原來 Sobel operator 的中文維基百科英文維基百科條目,對於 sobel operator 的矩陣有相反的寫法,這涉及程式計算梯度方向的歧異,請個別參考圖一和圖二,誰對?

圖一:中文維基百科索伯算子
圖二:英文維基百科 sobel operator

第二個問題,關於影像與 sobel operator 乘積的算式也有歧異。按照英文維基百科 Kernel (image)其中一則說明,sobel operator 應該是採用 Hadamard product,也就是左上乘左上、依序一一對應相乘。請參考圖三所示。另外一種,是英文維基百科 Kernel (image) 後續的說明,採用 kernel convolution 的方法,卻是右下乘左上,請參考圖四所示。這不只涉及到 convolution 運算的問題,也涉及到梯度計算正確與否的問題。

圖三:Hadamard Product
圖四:Kernel Convolution

矩陣相反、算式相反,就有四種可能組合,導致截然不同的計算結果。如果不討論清楚,就會讓我們在實作程式時莫衷一是,更枉論有可靠依據判斷程式結果是否正確。<del>為什麼工程需要數學?因為實務上太多不可預測不可控制的東西。人類自古以來天天盼著能掌握大自然運作的原理,而人類偉大的地方之一,就是找到足夠可靠的地基,將系統架在堪稱可靠的數學跟邏輯推演上面。測試、試誤,對人類經驗的累積非常重要,兩者不可偏廢,因為我們既是理型的存有,更面對現象的世界。</del>

我尋著維基百科的指引,找到發明 sobel operator 的 Dr. Irwin Sobel 的一篇論文,〈An Isotropic 3x3 Image Gradient Operator〉。原來 sobel operator 是如何推演、如何有上述的矩陣形式與計算,才能知道兩個問題的歧異與適用的地方。

論文不長,我稍讀了一下論文,大概意思是說,一個自然影像上面會有漸進的亮度變化,計算這個變化量就是梯度(gradient)。Sobel 最早提出 sobel 運算的概念,是為了改進當時流行的 Roberts Cross 方法,以便更有效的計算梯度。

請讀者參考圖五該論文中的八鄰圖,sobel operator 計算中央像素 e 的梯度的方法,是先計算中央像素 e 周圍的四個方向梯度,予以加總取平均後,得到中央像素 e 的梯度方向平均值。

圖五:Dr. Sobel 論文中的八鄰圖(eight-neighbors)

具體而言,Sobel 將中央像素 e 周圍八個鄰近像素,兩兩相對,分為四組:即 a-i, b-h, c-g, f-d,將每組像素組成向量並計算方向導數 (directional derivation),再個別乘上一個該方向的單位向量(derivation’s direction),以得到梯度。

論文定義方向導數:兩像素的差值,再除上兩像素的距離。上下左右四鄰的距離為 2,對角線的距離為 4,所以有 (c-g)/4, (a-i)/4, (b-h)/2, (f-d)/2;

個別再乘上四個單位向量的方向導數,就是 c-g 組的 45 度的 (1,1),a-i 組 315 度的 (-1, 1),b-h 組 0 度的 (0, 1), f-d 組 90 度的 (1, 0)。

所以我們得到四個方向的梯度總和
G = (c-g)/4 * [ 1, 1] + (a-i)/4 * [-1, 1] + (b-h)/2 * [ 0, 1] + (f-d)/2 * [ 1, 0]

整理一下:G = [(c-g-a+i)/4 + (f-d)/2, (c-g+a-i)/4 + (b-h)/2]

論文中說明為了電腦計算方便,同乘 4,得到
G’ = 4*G = [c-g-a+i + 2*(f-d), c-g+a-i + 2*(b-h)]

如果我們用矩陣形式化簡,就得到第一種矩陣,請看圖六:

圖六:Dr. Sobel 論文中的 Sobel operator

並請參考圖六的矩陣形式以及原始的算式,sobel operator 在此矩陣形式下,就是用 Hadamard Product 的方式計算,這才是最原始的 Sobel operator。

其次,如果引入 kernel convolution 的概念去計算,就為了遷就圖四所說的 kernel convolution 右下左上的計算方式,只好把矩陣轉過來,變成如圖三所示的英文維基百科第二種矩陣,才會得到正確的結果。

因此,如果要方便撰寫程式,採用 Hadamard Product 的方式實作,就用第一種 sobel operator。如果要用 kernel convolution 的概念,就用第二種矩陣形式,且如圖四所示右下乘左上開始。

附註:Sobel operator,很多人會把 sobel 唸成「索貝爾」這是錯誤的發音。應當要唸成如「索伯」。

附註:Dr. Irwin Sobel 的論文簡潔易懂,層次分明,非常精彩。有興趣的讀者不妨細讀〈An Isotropic 3x3 Image Gradient Operator〉

--

--

No responses yet