一、線性濾波與卷積的基本概念
線性濾波可以說(shuō)是圖像處理最基本的方法,它可以允許我們對(duì)圖像進(jìn)行處理,產(chǎn)生很多不同的效果。做法很簡(jiǎn)單。首先,我們有一個(gè)二維的濾波器矩陣(有個(gè)高大上的名字叫卷積核)和一個(gè)要處理的二維圖像。然后,對(duì)于圖像的每一個(gè)像素點(diǎn),計(jì)算它的鄰域像素和濾波器矩陣的對(duì)應(yīng)元素的乘積,然后加起來(lái),作為該像素位置的值。這樣就完成了濾波過(guò)程。
對(duì)圖像和濾波矩陣進(jìn)行逐個(gè)元素相乘再求和的操作就相當(dāng)于將一個(gè)二維的函數(shù)移動(dòng)到另一個(gè)二維函數(shù)的所有位置,這個(gè)操作就叫卷積或者協(xié)相關(guān)。卷積和協(xié)相關(guān)的差別是,卷積需要先對(duì)濾波矩陣進(jìn)行180的翻轉(zhuǎn),但如果矩陣是對(duì)稱的,那么兩者就沒(méi)有什么差別了。
Correlation 和 Convolution可以說(shuō)是圖像處理最基本的操作,但卻非常有用。這兩個(gè)操作有兩個(gè)非常關(guān)鍵的特點(diǎn):它們是線性的,而且具有平移不變性shift-invariant。平移不變性指我們?cè)趫D像的每個(gè)位置都執(zhí)行相同的操作。線性指這個(gè)操作是線性的,也就是我們用每個(gè)像素的鄰域的線性組合來(lái)代替這個(gè)像素。這兩個(gè)屬性使得這個(gè)操作非常簡(jiǎn)單,因?yàn)榫€性操作是最簡(jiǎn)單的,然后在所有地方都做同樣的操作就更簡(jiǎn)單了。
實(shí)際上,在信號(hào)處理領(lǐng)域,卷積有廣泛的意義,而且有其嚴(yán)格的數(shù)學(xué)定義,但在這里不關(guān)注這個(gè)。
2D卷積需要4個(gè)嵌套循環(huán)4-double loop,所以它并不快,除非我們使用很小的卷積核。這里一般使用3x3或者5x5。而且,對(duì)于濾波器,也有一定的規(guī)則要求:
1)濾波器的大小應(yīng)該是奇數(shù),這樣它才有一個(gè)中心,例如3x3,5x5或者7x7。有中心了,也有了半徑的稱呼,例如5x5大小的核的半徑就是2。
2)濾波器矩陣所有的元素之和應(yīng)該要等于1,這是為了保證濾波前后圖像的亮度保持不變。當(dāng)然了,這不是硬性要求了。
3)如果濾波器矩陣所有元素之和大于1,那么濾波后的圖像就會(huì)比原圖像更亮,反之,如果小于1,那么得到的圖像就會(huì)變暗。如果和為0,圖像不會(huì)變黑,但也會(huì)非常暗。
4)對(duì)于濾波后的結(jié)構(gòu),可能會(huì)出現(xiàn)負(fù)數(shù)或者大于255的數(shù)值。對(duì)這種情況,我們將他們直接截?cái)嗟?和255之間即可。對(duì)于負(fù)數(shù),也可以取絕對(duì)值。
二、神奇的卷積核
上面說(shuō)到,對(duì)圖像的濾波處理就是對(duì)圖像應(yīng)用一個(gè)小小的卷積核,那這個(gè)小小的卷積核到底有哪些魔法,能讓一個(gè)圖像從慘不忍睹變得秀色可餐。下面我們一起來(lái)領(lǐng)略下一些簡(jiǎn)單但不簡(jiǎn)單的卷積核的魔法。
2.1、啥也不做
哈哈,大家可以看到啥了嗎?這個(gè)濾波器啥也沒(méi)有做,得到的圖像和原圖是一樣的。因?yàn)橹挥兄行狞c(diǎn)的值是1。鄰域點(diǎn)的權(quán)值都是0,對(duì)濾波后的取值沒(méi)有任何影響。
下面我們動(dòng)點(diǎn)真格的。
2.2、圖像銳化濾波器Sharpness Filter
圖像的銳化和邊緣檢測(cè)很像,首先找到邊緣,然后把邊緣加到原來(lái)的圖像上面,這樣就強(qiáng)化了圖像的邊緣,使圖像看起來(lái)更加銳利了。這兩者操作統(tǒng)一起來(lái)就是銳化濾波器了,也就是在邊緣檢測(cè)濾波器的基礎(chǔ)上,再在中心的位置加1,這樣濾波后的圖像就會(huì)和原始的圖像具有同樣的亮度了,但是會(huì)更加銳利。
我們把核加大,就可以得到更加精細(xì)的銳化效果
另外,下面的濾波器會(huì)更強(qiáng)調(diào)邊緣:
主要是強(qiáng)調(diào)圖像的細(xì)節(jié)。最簡(jiǎn)單的3x3的銳化濾波器如下:
實(shí)際上是計(jì)算當(dāng)前點(diǎn)和周圍點(diǎn)的差別,然后將這個(gè)差別加到原來(lái)的位置上。另外,中間點(diǎn)的權(quán)值要比所有的權(quán)值和大于1,意味著這個(gè)像素要保持原來(lái)的值。
2.3、邊緣檢測(cè)Edge Detection
我們要找水平的邊緣:需要注意的是,這里矩陣的元素和是0,所以濾波后的圖像會(huì)很暗,只有邊緣的地方是有亮度的。
為什么這個(gè)濾波器可以尋找到水平邊緣呢?因?yàn)橛眠@個(gè)濾波器卷積相當(dāng)于求導(dǎo)的離散版本:你將當(dāng)前的像素值減去前一個(gè)像素值,這樣你就可以得到這個(gè)函數(shù)在這兩個(gè)位置的差別或者斜率。下面的濾波器可以找到垂直方向的邊緣,這里像素上和下的像素值都使用:
再下面這個(gè)濾波器可以找到45度的邊緣:取-2不為了什么,只是為了讓矩陣的元素和為0而已。
那下面這個(gè)濾波器就可以檢測(cè)所有方向的邊緣:
為了檢測(cè)邊緣,我們需要在圖像對(duì)應(yīng)的方向計(jì)算梯度。用下面的卷積核來(lái)卷積圖像,就可以了。但在實(shí)際中,這種簡(jiǎn)單的方法會(huì)把噪聲也放大了。另外,需要注意的是,矩陣所有的值加起來(lái)要是0.
2.4、浮雕Embossing Filter
浮雕濾波器可以給圖像一種3D陰影的效果。只要將中心一邊的像素減去另一邊的像素就可以了。這時(shí)候,像素值有可能是負(fù)數(shù),我們將負(fù)數(shù)當(dāng)成陰影,將正數(shù)當(dāng)成光,然后我們對(duì)結(jié)果圖像加上128的偏移。這時(shí)候,圖像大部分就變成灰色了。
下面是45度的浮雕濾波器
我們只要加大濾波器,就可以得到更加夸張的效果了
這種效果非常的漂亮,就像是將一副圖像雕刻在一塊石頭上面一樣,然后從一個(gè)方向照亮它。它和前面的濾波器不同,它是非對(duì)稱的。另外,它會(huì)產(chǎn)生負(fù)數(shù)值,所以我們需要將結(jié)果偏移,以得到圖像灰度的范圍。
A:原圖像。B:銳化。C:邊緣檢測(cè)。D:浮雕
2.5、均值模糊Box Filter (Averaging)
我們可以將當(dāng)前像素和它的四鄰域的像素一起取平均,然后再除以5,或者直接在濾波器的5個(gè)地方取0.2的值即可,如下圖:
可以看到,這個(gè)模糊還是比較溫柔的,我們可以把濾波器變大,這樣就會(huì)變得粗暴了:注意要將和再除以13.
所以,如果你想要更模糊的效果,加大濾波器的大小即可。或者對(duì)圖像應(yīng)用多次模糊也可以。
2.6、高斯模糊
均值模糊很簡(jiǎn)單,但不是很平滑。高斯模糊就有這個(gè)優(yōu)點(diǎn),所以被廣泛用在圖像降噪上。特別是在邊緣檢測(cè)之前,都會(huì)用來(lái)移除細(xì)節(jié)。高斯濾波器是一個(gè)低通濾波器。
2.7、運(yùn)動(dòng)模糊Motion Blur
運(yùn)動(dòng)模糊可以通過(guò)只在一個(gè)方向模糊達(dá)到,例如下面9x9的運(yùn)動(dòng)模糊濾波器。注意,求和結(jié)果要除以9。
這個(gè)效果就好像,攝像機(jī)是從左上角移動(dòng)的右下角。
三、卷積的計(jì)算
對(duì)圖像處理而言,存在兩大類的方法:空域處理和頻域處理!空域處理是指直接對(duì)原始的像素空間進(jìn)行計(jì)算,頻率處理是指先對(duì)圖像變換到頻域,再做濾波等處理。
3.1、空域計(jì)算-直接2D卷積
3.1.1、2D卷積
直接2D卷積就是一開(kāi)始說(shuō)的那樣,對(duì)于圖像的每一個(gè)像素點(diǎn),計(jì)算它的鄰域像素和濾波器矩陣的對(duì)應(yīng)元素的乘積,然后加起來(lái),作為該像素位置的值。
直接的實(shí)現(xiàn)也稱為暴力實(shí)現(xiàn)brute force,因?yàn)樗鼑?yán)格按照定義來(lái)實(shí)現(xiàn),沒(méi)有任何優(yōu)化。當(dāng)然了,在并行實(shí)現(xiàn)里面,它也是比較靈活的。另外,也存在一個(gè)優(yōu)化版本,如果我們的kernel是separable可分的,那么就可以得到一個(gè)快5倍左右的卷積方法。
2.1.2、邊界處理
那卷積核遇到圖像邊緣怎么辦?例如圖像頂部的像素,它的上面已經(jīng)沒(méi)有像素了,那么它的值如何計(jì)算?目前有四種主流的處理方法,我們用一維卷積和均值濾波來(lái)說(shuō)明下。
我們?cè)?D圖像中,用每個(gè)像素和它的二鄰域的平均值來(lái)取代它的值。假設(shè)我們有個(gè)1D的圖像I是這樣的:
對(duì)非圖像邊界的像素的操作比較簡(jiǎn)單。假設(shè)我們對(duì)I的第四個(gè)像素3做局部平均。也就是我們用2,3和7做平均,來(lái)取代這個(gè)位置的像素值。也就是,平均會(huì)產(chǎn)生一副新的圖像J,這個(gè)圖像在相同位置J (4) = (I(3)+I(4)+I(5))/3 = (2+3+7)/3 = 4。同樣,我們可以得到J(3) = (I(2)+I(3)+I(4))/3 =(4+2+3)/3 = 3。需要注意的是,新圖像的每個(gè)像素都取決于舊的圖像,在計(jì)算J (4)的時(shí)候用J (3)是不對(duì)的,而是用I(3),I(4)和I(5)。所以每個(gè)像素都是它和它鄰域兩個(gè)像素的平均。平均是線性的操作,因?yàn)槊總€(gè)新的像素都是舊像素的線性組合。
對(duì)卷積,也有必須要考慮的情況是,在圖像邊界的時(shí)候,怎么辦?J(1)的值應(yīng)該是什么?它取決于I(0),I(1)和I(2)。但是我們沒(méi)有I(0)呀!圖像左邊沒(méi)有值了。有四種方式來(lái)處理這個(gè)問(wèn)題:
1)第一種就是想象I是無(wú)限長(zhǎng)的圖像的一部分,除了我們給定值的部分,其他部分的像素值都是0。在這種情況下,I(0)=0。所以J(1) = (I(0) + I(1) + I(2))/3 = (0 + 5 + 4)/3= 3. 同樣,J(10) = (I(9)+I(10)+I(11))/3 = (3+ 6 + 0)/3 = 3.
2)第二種方法也是想象I是無(wú)限圖像的一部分。但沒(méi)有指定的部分是用圖像邊界的值進(jìn)行拓展。在我們的例子中,因?yàn)閳D像I最左邊的值I(1)=5,所以它左邊的所有值,我們都認(rèn)為是5 。而圖像右邊的所有的值,我們都認(rèn)為和右邊界的值I(10)一樣,都是6。這時(shí)候J(1) = (I(0) + I(1) + I(2))/3 = (5 + 5 + 4)/3= 14/3. 而J(10) = (I(9)+I(10)+I(11))/3 = (3 + 6 + 6)/3 = 5。
3)第三種情況就是認(rèn)為圖像是周期性的。也就是I不斷的重復(fù)。周期就是I的長(zhǎng)度。在我們這里,I(0)和I(10)的值就是一樣的,I(11)的值和I(1)的值也是一樣的。所以J(1) = (I(0) + I(1) + I(2))/3= (I(10) + I(1)+ I(2))/3 = (6 + 5 + 4)/3 = 5 。
4)最后一種情況就是不管其他地方了。我們覺(jué)得I之外的情況是沒(méi)有定義的,所以沒(méi)辦法使用這些沒(méi)有定義的值,所以要使用圖像I沒(méi)有定義的值的像素都沒(méi)辦法計(jì)算。在這里,J(1)和J(10)都沒(méi)辦法計(jì)算,所以輸出J會(huì)比原圖像I要小。
這四種方法有各自的優(yōu)缺點(diǎn)。如果我們想象我們使用的圖像只是世界的一個(gè)小窗口,然后我們需要使用窗口邊界外的值,那么一般來(lái)說(shuō),外面的值和邊界上的值是幾乎相似的,所以第二種方法可能更說(shuō)得過(guò)去。
2.2、頻域計(jì)算-快速傅里葉變換FFT卷積
這個(gè)快速實(shí)現(xiàn)得益于卷積定理:時(shí)域上的卷積等于頻域上的乘積。所以將我們的圖像和濾波器通過(guò)算法變換到頻域后,直接將他們相乘,然后再變換回時(shí)域(也就是圖像的空域)就可以了。
o表示矩陣逐元素相乘。那用什么方法將空域的圖像和濾波器變換到頻域了。那就是鼎鼎大名的Fast Fourier Transformation 快速傅里葉變換FFT(其實(shí),在CUDA里面,已經(jīng)實(shí)現(xiàn)了FFT了)。
要在頻域中對(duì)一副圖像進(jìn)行濾波,濾波器的大小和圖像的大小必須要匹配,這樣兩者的相乘才容易。因?yàn)橐话銥V波器的大小比圖像要小,所以我們需要拓展我們的kernel,讓它和圖像的大小一致。
因?yàn)镃UDA中的FFT實(shí)現(xiàn)是周期的,所以kernel的值也要安排成這樣,以支持這種周期性。
為了保證圖像邊界的像素也可以得到響應(yīng)輸出,我們也需要拓展我們的輸入圖像。同時(shí),拓展的方式也要支持周期表達(dá)。
如果只是使用卷積定理,沒(méi)有對(duì)輸入進(jìn)行任何修改的話,那么我們得到的是周期卷積的結(jié)果。但這可能不是我們要的,因?yàn)橹芷诰矸e會(huì)對(duì)輸入數(shù)據(jù)進(jìn)行周期填補(bǔ),引入一些artifacts。
給定N長(zhǎng)度的I和K,為了得到線性卷積,我們需要對(duì)I和K進(jìn)行zero padding。為什么要補(bǔ)0,因?yàn)镈FT假定了輸入是無(wú)限和周期的,周期是N。
如上圖,對(duì)于I和K,如果沒(méi)有padding的話,隱含著會(huì)假定I和K是周期的,以他們的長(zhǎng)度N為周期。圖中本來(lái)N長(zhǎng)度的I和K都是黑色虛線的部分,然后如果沒(méi)有padding,隱含著就會(huì)在N之外,加上同樣的無(wú)數(shù)個(gè)I,如紅色虛線部分,加上了一個(gè)周期。對(duì)K也是這樣。如果是zero padding的話,在黑色虛線的其他地方都全是0了,如圖中藍(lán)色部分。將I和K卷積,如果沒(méi)有padding,如黑色虛線,會(huì)有紅色那部分的artifact。如果有padding,就是藍(lán)色實(shí)線。
四、實(shí)驗(yàn)代碼
這是第二部分的Matlab實(shí)驗(yàn)代碼:
clear,close all, clc
%% readimage
image =imread('test.jpg');
%% definefilter
% -----Identity filter -----
kernel =[0, 0, 0
0, 1, 0
0, 0, 0];
% -----Average Blur -----
kernel =[0, 1, 0
1, 1, 1
0, 1, 0] / 5;
% -----Gaussian Blur -----
kernel =fspecial('gaussian', 5 , 0.8);
% -----Motion Blur -----
kernel =[1, 0, 0, 0, 0
0, 1, 0, 0, 0
0, 0, 1, 0, 0
0, 0, 0, 1, 0
0, 0, 0, 0, 1] / 5;
% -----Edges Detection -----
kernel =[-1, -1, -1
-1, 8, -1
-1, -1, -1];
% -----Sharpen filter -----
kernel =[-1, -1, -1
-1, 9, -1
-1, -1, -1];
% -----Emboss filter -----
kernel =[-1, -1, 0
-1, 0,1
0, 1,1];
%% convolethe image with defined kernel or filter
result =zeros(size(image));
result(:,:, 1) = conv2(double(image(:, :, 1)), double(kernel), 'same');
result(:,:, 2) = conv2(double(image(:, :, 2)), double(kernel), 'same');
result(:,:, 3) = conv2(double(image(:, :, 3)), double(kernel), 'same');
%% showthe result
imshow(image);
figure
imshow(uint8(result))
審核編輯:郭婷
-
濾波器
+關(guān)注
關(guān)注
161文章
7853瀏覽量
178510
原文標(biāo)題:圖像卷積與濾波的一些知識(shí)點(diǎn)
文章出處:【微信號(hào):vision263com,微信公眾號(hào):新機(jī)器視覺(jué)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論