Правильная реализация размытия по Гауссу через БПФ

Я прочитал много вопросов по SO о размытии по Гауссу и БПФ, но нет ответа, как реализовать его шаги (но есть комментарии вроде «это твоя домашняя работа»). Я хочу знать, как правильно заполнить ядро ​​и использовать БПФ и ОБПФ для ядра и изображения. Можете ли вы предоставить псевдокод или реализацию на любом языке, например Java, Python и т. Д., Как это сделать, или хотя бы какой-нибудь хороший учебник, как это понять:

1. FFT the image
2. FFT the kernel, padded to the size of the image
3. multiply the two in the frequency domain (equivalent to convolution in the spatial domain)
4. IFFT (inverse FFT) the result

Шаги скопированы из размытия по Гауссу и БПФ


person Guy Fawkes    schedule 18.05.2014    source источник


Ответы (1)


Пример Matlab. Это должно быть хорошее место для вас.

Загрузите картинку:

%Blur Demo

%Import image in matlab default image set.
origimage = imread('cameraman.tif');

%Plot image
figure, imagesc(origimage)
axis square
colormap gray
title('Original Image')
set(gca, 'XTick', [], 'YTick', [])

Весь процесс:

%Blur Kernel
ksize = 31;
kernel = zeros(ksize);

%Gaussian Blur
s = 3;
m = ksize/2;
[X, Y] = meshgrid(1:ksize);
kernel = (1/(2*pi*s^2))*exp(-((X-m).^2 + (Y-m).^2)/(2*s^2));

%Display Kernel
figure, imagesc(kernel)
axis square
title('Blur Kernel')
colormap gray

%Embed kernel in image that is size of original image
[h, w] = size(origimage);
kernelimage = zeros(h,w);
kernelimage(1:ksize, 1:ksize) = kernel;

%Perform 2D FFTs
fftimage = fft2(double(origimage));
fftkernel = fft2(kernelimage);

%Set all zero values to minimum value
fftkernel(abs(fftkernel)<1e-6) = 1e-6;

%Multiply FFTs
fftblurimage = fftimage.*fftkernel;

%Perform Inverse 2D FFT
blurimage = ifft2(fftblurimage);

%Display Blurred Image
figure, imagesc(blurimage)
axis square
title('Blurred Image')
colormap gray
set(gca, 'XTick', [], 'YTick', [])

Перед изображением:  Перед изображением, без размытия

После изображения:  После изображения, размыто

Обратите внимание: поскольку при заполнении нуля ядро ​​не центрируется, вы получаете смещение. Этот ответ объясняет проблему с упаковкой. размытие по Гауссу с БПФ

person Mansueli    schedule 26.05.2014
comment
Отличный пример кода. У меня есть несколько предложений, чтобы сделать это еще лучше. (1) Покажите пример результата, используя реальное изображение, с которым мы можем протестировать. Вы используете imread с локальным изображением, к которому у нас нет доступа. (2) Не используйте просто красный канал для преобразования в оттенки серого. Используйте rgb2gray, чтобы сделать это за вас. (3) Если у вас есть время, включите цветные изображения, где вы бы выполняли фильтрацию отдельно для каждого канала. (4) Установка всех нулевых значений на минимальное значение с помощью find немного неэффективна. Вместо этого используйте логическое индексирование: fftkernel(fftkernel == 0) = 1e-6; Вам не нужно find здесь. - person rayryeng; 19.08.2016