1

私の主な目標は、畳み込み定理が機能することを示すことです(念のため、畳み込み定理はそれを意味し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。キャストを使用してdoubleを使用している場合、マトリックス内の数値が互いに近くなるため、キャストが欠落していると思います。たぶん、キャスティングやパディングの場所に間違いがありますか?

4

1 に答える 1

7
  1. DFTを使用して線形畳み込みを計算するには、両方の信号にゼロを後置する必要があります。そうしないと、結果は巡回畳み込みになります。ただし、手動でシグナルをパディングする必要はありませんfft2。次のように、関数呼び出しにパラメーターを追加すると、パディングを行うことができます。

    fft2(X, M, N)
    

    これは、変換を実行する前に、信号をパディング(または切り捨て)XしてM行N列の信号を作成します。
    各次元の各信号を、両方の信号の長さの合計に等しい長さにパディングします。つまり、次のようになります。

    M = size(im, 1) + size(mask, 1);
    N = size(im, 2) + size(mask, 2);
    
  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

十分近い。

于 2012-12-25T16:42:25.753 に答える