1. 程式人生 > >Matlab中使用FFT驗證卷積定理

Matlab中使用FFT驗證卷積定理

Matlab中使用快速傅立葉變換(FFT)驗證卷積定理

引言

本科微積分教材中講過卷積定理,公式也非常容易背:
如果:

g=hx
那麼
G=HX
這裡 * 表示卷積,GHX分別表示ghx的傅立葉變換。HX之間為點乘。
公式很容易記住,考試的時候也不在話下。但是當時有很多問題根本沒有往下思考。比如,在二維矩陣中,hx的大小可能不一致,這在卷積操作中沒有問題。但在頻域中(經過傅立葉變換後),HX之間為點乘,而HX的大小分別由空域中的hx決定(相等)。那麼HX大小不等的時候,二者怎麼點乘呢?

原理

所以在要分別對hx做擴充,並使它們擴充之後大小一致。這樣,在頻域中二者就可以點乘了。

1. 擴充

在這裡,我們通過在矩陣水平與垂直正方向補0,把hRc×dxRa×b都擴充至[a+c1,b+d1]。原始的hx資料處於補充矩陣的左上角。

2. 變換

這一步可以跟上一步一起用函式fft2解決

H = fft2(h, a+c-1, b+d-1);
X = fft2(x, a+c-1, b+d-1);

這裡fft2函式會自動擴充,然後進行變換。一開始以為是在原矩陣四周同時補0,後來經過驗證發現MATLAB只在矩陣兩個方向把0補齊即可。

3. 點乘,反變換

直接看程式碼:

G = X.*H;
g = ifft2(G);% 產生最大的結果,對應"full"
% 產生與x大小一致的結果,對應"same" gf = g(floor((c-1)/2+1):floor((c+2*a-1)/2), floor((d-1)/2+1):floor((d+2*b-1)/2));

g的大小與G相同,即擴充後的大小;gf擷取至g,它的大小與原始矩陣x相同。

程式碼

既然是驗證,這裡就附上程式碼和結果以作驗證:

x = imread('horse.jpg'); %讀取原圖片
x = rgb2gray(x);
[a, b] = size(x);
figure, imshow(x); title('原影象');

c=5; 
d=5;
h = fspecial('gaussian'
, [c,d]) %產生點擴散函式 %產生空域卷積結果 gc = conv2(x, h, 'same'); %gc = conv2(x, h);產生最大的結果,對應"full" figure, imshow(gc/255); title('卷積'); % 用fft驗證 H = fft2(h, a+c-1, b+d-1); X = fft2(x, a+c-1, b+d-1); G = X.*H; %點乘 g = ifft2(G);% 與G大小一致的結果,對應"full" % 產生與x大小一致的結果,對應"same" gf = g(floor((c-1)/2+1):floor((c+2*a-1)/2), floor((d-1)/2+1):floor((d+2*b-1)/2)); figure, imshow(gf/255); %% 為了驗證兩種方式結果是否一致,將gf,gc做差顯示出來 figure, imshow(abs(gf-gc)/255);

經過驗證,最後一張影象幾乎全黑,意味這兩種方式計算的結果是一致的。

conv2()函式得到不同大小的卷積結果

C = conv2(x, h, shape);

命令 結果大小
‘full’ [a+c-1, b+d-1]
‘same’ [a, b]
‘valid’ [a-c+1, b-d+1]

抽時間把conv2()具體怎麼計算的講明白。