卷積在信號(hào)處理領(lǐng)域有極其廣泛的應(yīng)用,也有嚴(yán)格的物理和數(shù)學(xué)定義。本文只討論卷積在數(shù)字圖像處理中的應(yīng)用。
在數(shù)字圖像處理中,有一種基本的處理方法:線(xiàn)性濾波。待處理的平面數(shù)字圖像可被看做一個(gè)大矩陣,圖像的每個(gè)像素對(duì)應(yīng)著矩陣的每個(gè)元素,假設(shè)我們平面的分辨率是 1024 * 768,那么對(duì)應(yīng)的大矩陣的行數(shù)= 1024,列數(shù)=768 。
用于濾波的是一個(gè)濾波器小矩陣(也叫卷積核),濾波器小矩陣一般是個(gè)方陣,也就是行數(shù)和列數(shù)相同,比如常見(jiàn)的用于邊緣檢測(cè)的 Sobel 算子 就是兩個(gè) 3*3 的小矩陣.
進(jìn)行濾波就是對(duì)于大矩陣中的每個(gè)像素,計(jì)算它周?chē)袼睾蜑V波器矩陣對(duì)應(yīng)位置元素的乘積,然后把結(jié)果相加到一起,最終得到的值就作為該像素的新值,這樣就完成了一次濾波。
上面的處理過(guò)程可以參考這個(gè)示意圖:
圖像卷積計(jì)算示意圖:
對(duì)圖像大矩陣和濾波小矩陣對(duì)應(yīng)位置元素相乘再求和的操作就叫卷積(Convolution)或協(xié)相關(guān)(Correlation).
協(xié)相關(guān)(Correlation)和卷積(Convolution)很類(lèi)似,兩者唯一的差別就是卷積在計(jì)算前需要翻轉(zhuǎn)卷積核,而協(xié)相關(guān)則不需要翻轉(zhuǎn).
以 Sobel 算子為例
Sobel 算子 也叫 Sobel 濾波, 是兩個(gè) 3*3 的矩陣,主要用來(lái)計(jì)算圖像中某一點(diǎn)在橫向/縱向上的梯度,看了不少網(wǎng)絡(luò)上講解 Sobel 算子 的文章,發(fā)現(xiàn)人們常常把它的橫向梯度矩陣和縱向梯度矩陣混淆。這可能與 Sobel 算子 在它的兩個(gè)主要應(yīng)用場(chǎng)景中的不同用法有關(guān)。
Sobel 算子的兩個(gè)梯度矩陣: Gx 和 Gy
這里以 Wiki 資料為準(zhǔn),Sobel 算子 有兩個(gè)濾波矩陣:Gx 和 Gy, Gx 用來(lái)計(jì)算橫向的梯度,Gy 用來(lái)計(jì)算縱向的梯度, 下圖就是具體的濾波器:
? 注意:這里列出的這兩個(gè)梯度矩陣對(duì)應(yīng)于橫向從左到右,縱向從上到下的坐標(biāo)軸,也就是這種:
原點(diǎn) O -------> x軸 | | | V y軸
Sobel 算子的用途
它可以用來(lái)對(duì)圖像進(jìn)行邊緣檢測(cè), 或者用來(lái)計(jì)算某個(gè)像素點(diǎn)的法線(xiàn)向量. 這里需要注意的是:
邊緣檢測(cè)時(shí):Gx 用于檢測(cè)縱向邊緣,Gy 用于檢測(cè)橫向邊緣。
計(jì)算法線(xiàn)時(shí):Gx 用于計(jì)算法線(xiàn)的橫向偏移,Gy 用于計(jì)算法線(xiàn)的縱向偏移。
計(jì)算展開(kāi)
假設(shè)待處理圖像的某個(gè)像素點(diǎn)周?chē)南袼厝缦拢?/p>
那么用 Gx 計(jì)算展開(kāi)為:
橫向新值 = (-1)*[左上] + (-2)*[左] + (-1)*[左下] + 1*[右上] + 2*[右] + 1*[右下]
用 Gy 計(jì)算展開(kāi)為:
縱向新值 = (-1)*[左上] + (-2)*[上] + (-1)*[右] + 1*[左下] + 2*[下] + 1*[右下]
前面說(shuō)過(guò),做圖像卷積時(shí)需要翻轉(zhuǎn)卷積核,但是我們上面的計(jì)算過(guò)程沒(méi)有顯式翻轉(zhuǎn),這是因?yàn)?Sobel 算子 繞中心元素旋轉(zhuǎn) 180 度后跟原來(lái)一樣。不過(guò)有些 卷積核 翻轉(zhuǎn)后就變了,下面我們?cè)敿?xì)說(shuō)明如何翻轉(zhuǎn)卷積核。
卷積核翻轉(zhuǎn)
前面說(shuō)過(guò), 圖像卷積計(jì)算, 需要先翻轉(zhuǎn)卷積核, 也就是繞卷積核中心旋轉(zhuǎn) 180度, 也可以分別沿兩條對(duì)角線(xiàn)翻轉(zhuǎn)兩次, 還可以同時(shí)翻轉(zhuǎn)行和列, 這3種處理都可以得到同樣的結(jié)果.
對(duì)于第一種卷積核翻轉(zhuǎn)方法, 一個(gè)簡(jiǎn)單的演示方法是把卷積核寫(xiě)在一張紙上, 用筆尖固定住中心元素, 旋轉(zhuǎn) 180 度, 就看到翻轉(zhuǎn)后的卷積核了.
下面演示后兩種翻轉(zhuǎn)方法, 示例如下:
假設(shè)原始卷積核為:
方法2:沿兩條對(duì)角線(xiàn)分別翻轉(zhuǎn)兩次
先沿左下角到右上角的對(duì)角線(xiàn)翻轉(zhuǎn), 也就是 a和i, b和f, d和h交換位置, 結(jié)果為:
再沿左上角到右下角的對(duì)角線(xiàn)翻轉(zhuǎn),最終用于計(jì)算的卷積核為:
方法3:同時(shí)翻轉(zhuǎn)行和列
在 Wiki 中對(duì)這種翻轉(zhuǎn)的描述:
convolution is the process of flipping both the rows and columns of the kernel and then multiplying locationally similar entries and summing.
也是把卷積核的行列同時(shí)翻轉(zhuǎn),我們可以先翻轉(zhuǎn)行,把 a b c跟 g h i 互換位置, 結(jié)果為:
再翻轉(zhuǎn)列, 把 g d a 和 i f c 互換位置,結(jié)果為:
在 Wiki 中有一個(gè)計(jì)算展開(kāi)式,也說(shuō)明了這種翻轉(zhuǎn):
? 注意:這里要跟矩陣乘法區(qū)分開(kāi),這里只是借用了矩陣符號(hào),實(shí)際做的是對(duì)應(yīng)項(xiàng)相乘,再求和。
圖像邊緣像素的處理
以上都默認(rèn)待處理的像素點(diǎn)周?chē)加邢袼兀菍?shí)際上圖像邊緣的像素點(diǎn)周?chē)南袼鼐筒煌暾热珥敳康南袼卦谒戏骄蜎](méi)有像素點(diǎn)了,而圖像的四個(gè)角的像素點(diǎn)的相鄰像素更少,我們以一個(gè)圖像矩陣為例:
位于左上角的像素點(diǎn)的周?chē)椭挥杏覀?cè)和下方有相鄰像素,遇到這種情況,就需要補(bǔ)全它所缺少的相鄰像素,具體補(bǔ)全方法請(qǐng)參考下一節(jié)的代碼。
用GPU進(jìn)行圖像卷積
如果在 CPU 上實(shí)現(xiàn)圖像卷積算法需要進(jìn)行4重循環(huán),效率比較差,所以我們?cè)囍堰@些卷積計(jì)算放到 GPU 上,用 shader 實(shí)現(xiàn),結(jié)果發(fā)現(xiàn)性能相當(dāng)好,而且因?yàn)轫旤c(diǎn)著色器和片段著色器本質(zhì)就是一個(gè)循環(huán)結(jié)構(gòu),我們甚至不需要顯式的循環(huán),代碼也清晰了很多。
圖像卷積在代碼中的實(shí)際應(yīng)用,下面是一個(gè) GLSL 形式的著色器,它可以根據(jù)紋理貼圖生成對(duì)應(yīng)的法線(xiàn)圖:
-
濾波器
+關(guān)注
關(guān)注
160文章
7749瀏覽量
177735 -
圖像處理
+關(guān)注
關(guān)注
27文章
1282瀏覽量
56657
原文標(biāo)題:徹底理解數(shù)字圖像處理中的卷積——以Sobel算子為例
文章出處:【微信號(hào):Imgtec,微信公眾號(hào):Imagination Tech】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論