使用fft2在Matlab中对两个图像进行线性卷积

Nic*_*nar 7 matlab image-processing convolution

我想拍摄两张图像并使用2D FFT在Matlab中将它们一起卷积,而无需使用该conv2函数.但是,我不确定如何正确填充矩阵并为卷积做好准备.

数学运算如下:

A*B = C.

在上面,*是卷积运算符(维基百科链接).

以下Matlab程序显示了填充和不填充矩阵之间的区别.我怀疑不填充矩阵导致循环卷积,但我想执行线性卷积而没有混叠.

如果我填充两个矩阵,那么如何截断卷积的输出以使CAB的大小相同?

A = rgb2gray(im2double(imread('1.png'))); % input A
B = rgb2gray(im2double(imread('2.png'))); % kernel B

figure;
imagesc(A); colormap gray;
title ('A')

figure;
imagesc(B); colormap gray;
title ('B')

[m,n] = size(A);
mm = 2*m - 1;
nn = 2*n - 1;

C = (ifft2(fft2(A,mm,nn).* fft2(B,mm,nn)));

figure;
imagesc(C); colormap gray;
title ('C with padding')

C0 = (ifft2(fft2(A).* fft2(B)));

figure;
imagesc(C0); colormap gray;
title ('C without padding')
Run Code Online (Sandbox Code Playgroud)

这是程序的输出:

一个 乙 C C0

gev*_*ang 11

如果没有填充,结果将等同于循环卷积,如您所指出的那样.对于线性卷积,在卷积2个图像(2D信号)A*B时,完整输出将具有大小Ma+Mb-1 x Na+Nb-1,其中Ma x Na, Mb x Nb图像A和B的大小相等.

填充到预期大小后,通过乘法和变换,通过ifft2,可以保留结果图像的中心部分(通常对应于A和B中最大的一个).

A = double(imread('cameraman.tif'))./255; % image
B = fspecial('gaussian', [15 15], 2); % some 2D filter function

[m,n] = size(A);
[mb,nb] = size(B); 
% output size 
mm = m + mb - 1;
nn = n + nb - 1;

% pad, multiply and transform back
C = ifft2(fft2(A,mm,nn).* fft2(B,mm,nn));

% padding constants (for output of size == size(A))
padC_m = ceil((mb-1)./2);
padC_n = ceil((nb-1)./2);

% frequency-domain convolution result
D = C(padC_m+1:m+padC_m, padC_n+1:n+padC_n); 
figure; imshow(D,[]);
Run Code Online (Sandbox Code Playgroud)

现在,将上述与空间域卷积进行比较,使用 conv2D

 % space-domain convolution result
 F = conv2(A,B,'same');
 figure; imshow(F,[]);
Run Code Online (Sandbox Code Playgroud)

结果在视觉上是相同的,并且两者之间的总误差(由于四舍五入)的顺序为 e-10.

  • 此外,使用Matlab`xcorr2`函数作为一个慢得多的测试,似乎**A**和**B**矩阵的2D相关可以通过`ifft2(fft2(A,mm,nn)来计算).*fft2(fliplr(flipud(B)),mm,nn));`或等效`ifft2(fft2(A,mm,nn).*fft2(rot90(B,2),mm,nn)) .对此的参考是Steven Smith的DSP书籍:http://www.dspguide.com/ch24/6.htm. (2认同)