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.
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,[]);
Now, compare the above with doing spatial-domain convolution, using conv2D
% space-domain convolution result
F = conv2(A,B,'same');
figure; imshow(F,[]);
Results are visually the same, and total error between the two (due to rounding) on the order of e-10.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…