我的主要目标是证明卷积定理是有效的(只是一个提醒:卷积定理意味着idft(dft(im) .* dft(mask)) = conv(im, mask)
)。我正试着编程呢
function displayTransform( im )
% This routine displays the Fourier spectrum of an image.
%
% Input: im - a grayscale image (values in [0,255])
%
% Method: Computes the Fourier transform of im and displays its spectrum,
% (if F(u,v) = a+ib, displays sqrt(a^2+b^2)).
% Uses display techniques for visualization: log, and stretch values to full range,
% cyclic shift DC to center (use fftshift).
% Use showImage to display and fft2 to apply transform.
%displays the image in grayscale in the Frequency domain
imfft = fft2(im);
imagesc(log(abs(fftshift(imfft))+1)), colormap(gray);
% building mask and padding it with Zeros in order to create same size mask
b = 1/16*[1 1 1 1;1 1 1 1; 1 1 1 1; 1 1 1 1];
paddedB = padarray(b, [floor(size(im,1)/2)-2 floor(size(im,2)/2)-2]);
paddedB = fft2(paddedB);
C = imfft.*paddedB;
resIFFT = ifft2(C);
%reguler convolution
resConv = conv2(im,b);
showImage(resConv);
end
我想比较resIFFT
和resConv
。我认为我错过了一些铸造,因为我得到的数字在矩阵更接近另一个,如果我使用铸造双重。也许我在铸型或填充的地方有一些错误?
-
为了使用DFT计算线性卷积,你需要在两个信号后置零,否则结果将是圆卷积。您不必手动填充信号,如果您在函数调用中添加额外的参数,
fft2
可以为您完成此操作,如下所示:fft2(X, M, N)
在进行变换之前填充(或截断)信号
X
以创建m × n信号。
将每个维度中的每个信号填充到等于两个信号长度之和的长度,即:M = size(im, 1) + size(mask, 1); N = size(im, 2) + size(mask, 2);
-
只是为了更好的实践,而不是:
b = 1 / 16 * [1 1 1 1; 1 1 1 1; 1 1 1 1; 1 1 1 1];
你可以写:
b = ones(4) / 16;
im = fix(255 * rand(500)); % # Generate a random image
mask = ones(4) / 16; % # Mask
% # Circular convolution
resConv = conv2(im, mask);
% # Discrete Fourier transform
M = size(im, 1) + size(mask, 1);
N = size(im, 2) + size(mask, 2);
resIFFT = ifft2(fft2(im, M, N) .* fft2(mask, M, N));
resIFFT = resIFFT(1:end-1, 1:end-1); % # Adjust dimensions
% # Check the difference
max(abs(resConv(:) - resIFFT(:)))
你应该得到的结果应该是零:
ans =
8.5265e-014
足够近。