Вы выбрали очень маленькое значение для параметра регуляризации k
.Это прекрасно работает в случае 'full'
, потому что нет шума, и вход точно соответствует ожидаемому.Однако в случае 'same'
ввод не совсем совпадает.Если бы вы использовали круговую свертку (например, путем умножения в области Фурье), то вы бы также получили точный результат.
Параметр регуляризации существует, чтобы предотвратить небольшие отклонения от разрушения и повреждения всего выходного изображения.
Я получил разумные результаты, используя k = 1e-2
(1e-1
оставляет изображение размытым, 1e-3
по-прежнему показывает много артефактов по всему изображению, но возможно дальнейшая подстройка этого значения, у меня естьне прилагайте больше усилий, чем это).
Это код, который я использовал, есть некоторые важные различия:
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);
Обратите внимание, что я не использую параметры размера для функций fft2
и ifft2
.В этом случае всегда лучше не дополнять изображения нулями.
Изображение kernel
было дополнено очень особым образом.БПФ предполагает, что источник находится в верхнем левом пикселе ввода.fft2(kernel,dim,dim)
приводит к заполнению ядра справа и снизу нулями, но это оставляет ядро смещенным относительно происхождения FFT.Этот сдвиг также приводит к смещению развернутого изображения (всего на 2 пикселя, это трудно заметить, но посмотрите на img_wiener_ifft-double(img)
код OP и этот код, чтобы увидеть это смещение).