使用fft2在Matlab中对两个图像进行线性卷积 [英] Linear convolution of two images in Matlab using fft2
问题描述
我想拍摄两张图像并使用2D FFT在Matlab中将它们组合在一起,而无需使用 conv2
函数。但是,我不确定如何正确填充矩阵并为卷积做好准备。
I would like to take two images and convolve them together in Matlab using the 2D FFT without recourse to the conv2
function. However, I am uncertain with respect to how the matrices should be properly padded and prepared for the convolution.
数学运算如下:
A * B = C
在上面,*是卷积运算符(维基百科链接)。
In the above, * is the convolution operator (Wikipedia link).
以下Matlab程序显示填充和不填充之间的区别矩阵。我怀疑没有填充矩阵导致循环卷积,但我想执行线性卷积而没有别名。
The following Matlab program shows the difference between padding and not padding the matrices. I suspect that not padding the matrices results in a circular convolution, but I would like to perform a linear convolution without aliasing.
如果我这样做填充两个矩阵,然后如何截断卷积的输出,使 C 与 A 和 B 的大小相同?
If I do pad the two matrices, then how do I truncate the output of the convolution so that C is the same size as A and B?
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')
这是程序的输出:
推荐答案
如果没有填充,结果将等同于循环卷积。对于线性卷积,在卷积2个图像(2D信号)A * B时,完整输出的大小 Ma + Mb-1 x Na + Nb-1
,其中 Ma x Na,Mb x Nb
图像A和B的大小。
Without padding the result will be equivalent to circular convolution as you point out. For linear convolution, in convolving 2 images (2D signals) A*B the full output will be of size Ma+Mb-1 x Na+Nb-1
, where Ma x Na, Mb x Nb
the sizes of images A and B resp.
填充到预期大小后,通过 ifft2
进行乘法和转换,可以保持中心部分得到的图像(通常对应于A和B中最大的一个)。
After padding to the expected size, multiplying and transforming back, via ifft2
, you can keep the central part of the resulting image (usually corresponding to the largest one of A and 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,[]);
现在,使用 conv2D <将上述内容与空间域卷积进行比较/ code>
Now, compare the above with doing spatial-domain convolution, using conv2D
% space-domain convolution result
F = conv2(A,B,'same');
figure; imshow(F,[]);
结果在视觉上是相同的,两者之间的总误差(由于四舍五入)在 e-10。
Results are visually the same, and total error between the two (due to rounding) on the order of e-10.
这篇关于使用fft2在Matlab中对两个图像进行线性卷积的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!