Сбой фильтра Винера для размытого изображения из-за свертки того же размера - PullRequest
1 голос
/ 27 мая 2019

Я тестирую фильтр Винера в MATLAB, чтобы восстановить размытое изображение.Я использовал conv2 (), чтобы размыть исходное изображение.Если я использую опцию 'full' для conv2 (), все работает хорошо.Но когда я изменяю на «тот же» или «действительный», внезапно в восстановленном образе появилось много артефактов, и фильтр Винера вышел из строя.См. Ниже размытое изображение, восстановление из «полной» свертки, восстановление из «такой же» свертки.

Blurred image Restoration full Restoration same

Вот моя реализация фильтра Винера:

% load image
img = rgb2gray(imread('cameraman.jpg'));
[W, H] = size(img);
dim = 300;
img_fft = fft2(img,dim,dim);
% create blur kernel
kernel = ones(5) / 25;
kernel_fft = fft2(kernel,dim,dim);
% The option here makes huge difference 'same'/'full'/'valid'
img_blur = conv2(img,kernel,'same');
img_blur_fft = fft2(img_blur,dim,dim);
% Wiener filtering
k = 1e-5;
kernel_fft_conj = conj(kernel_fft);
img_wiener_freq = kernel_fft_conj .* img_blur_fft ./ (kernel_fft .* kernel_fft_conj + k);
img_wiener_ifft = ifft2(img_wiener_freq);
img_wiener_ifft = img_wiener_ifft(1:W,1:H);

Как и в реальной жизни, размытое изображение никогда не имеет формы круговой или полной свертки, как я могу правильно реализовать Винерфильтр, чтобы он не зависел от границы изображения?

1 Ответ

1 голос
/ 27 мая 2019

Вы выбрали очень маленькое значение для параметра регуляризации k.Это прекрасно работает в случае 'full', потому что нет шума, и вход точно соответствует ожидаемому.Однако в случае 'same' ввод не совсем совпадает.Если бы вы использовали круговую свертку (например, путем умножения в области Фурье), то вы бы также получили точный результат.

Параметр регуляризации существует, чтобы предотвратить небольшие отклонения от разрушения и повреждения всего выходного изображения.

Я получил разумные результаты, используя k = 1e-2 (1e-1 оставляет изображение размытым, 1e-3 по-прежнему показывает много артефактов по всему изображению, но возможно дальнейшая подстройка этого значения, у меня естьне прилагайте больше усилий, чем это).

deconvolved 'cameraman' image


Это код, который я использовал, есть некоторые важные различия:

img = imread('cameraman.tif');
% create blur kernel
kernel = ones(5) / 25;
% The option here makes huge difference 'same'/'full'/'valid'
img_blur = conv2(img,kernel,'same');
img_blur_fft = fft2(img_blur);
% Wiener filtering
kernel_fft = padarray(kernel,size(img)-size(kernel),0,'post');
kernel_fft = circshift(kernel_fft,-floor(size(kernel)/2));
kernel_fft = fft2(kernel_fft);
k = 1e-2;
kernel_fft_conj = conj(kernel_fft);
img_wiener_freq = kernel_fft_conj .* img_blur_fft ./ (kernel_fft .* kernel_fft_conj + k);
img_wiener_ifft = ifft2(img_wiener_freq);
  1. Обратите внимание, что я не использую параметры размера для функций fft2 и ifft2.В этом случае всегда лучше не дополнять изображения нулями.

  2. Изображение kernel было дополнено очень особым образом.БПФ предполагает, что источник находится в верхнем левом пикселе ввода.fft2(kernel,dim,dim) приводит к заполнению ядра справа и снизу нулями, но это оставляет ядро ​​смещенным относительно происхождения FFT.Этот сдвиг также приводит к смещению развернутого изображения (всего на 2 пикселя, это трудно заметить, но посмотрите на img_wiener_ifft-double(img) код OP и этот код, чтобы увидеть это смещение).

...