Проверить теорему свертки

Моя главная цель — показать, что теорема о свёртке работает (напомню: теорема о свёртке означает, что 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. Я думаю, что мне не хватает приведения, потому что я получаю числа в матрице ближе друг к другу, если я использую приведение к двойному. Может у меня какая-то ошибка в месте литья или прокладки?


person Gilad    schedule 24.12.2012    source источник
comment
Я не вижу здесь вопроса. Все, что я вижу, это дамп кода и заявление о том, что вы что-то упускаете. Ну да, вы, вероятно, и мы тоже - а именно четкое описание вашей проблемы.   -  person Ilmari Karonen    schedule 25.12.2012
comment
@IlmariKaronen Я попытался прояснить свой вопрос. пожалуйста, просмотрите его снова.   -  person Gilad    schedule 25.12.2012
comment
@Androidy - все еще неясно. Преобразуйте свои im и b в двойные.   -  person Shai    schedule 25.12.2012
comment
@Shai Я хочу запрограммировать в Matlab простую демонстрацию, чтобы показать, что теорема свертки работает. моя идея состояла в том, чтобы сделать изображение свертки с маской b. а с другой стороны ifft2(fft2(im).*fft2(b)). а затем сравнить значения двух результатов. однако моя проблема в том, что в результате я получаю две разные матрицы.   -  person Gilad    schedule 25.12.2012
comment
Можно ли использовать два вектора разной длины   -  person Bharat    schedule 27.07.2017


Ответы (1)


  1. Для вычисления линейной свертки с помощью ДПФ необходимо добавить к обоим сигналам нули, иначе результатом будет круговая свертка< /а>. Однако вам не нужно вручную дополнять сигнал, 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

Достаточно близко.

person Eitan T    schedule 25.12.2012