Размытие изображения с использованием фильтра Гаусса в Matlab без аддитивного шума

Я должен использовать обратный фильтр, чтобы удалить размытие с этого изображения.

Размытое изображение.

К сожалению, мне нужно вычислить передаточную функцию H системы визуализации, используемой для получения этих более четких изображений. Она должна быть гауссовой. Итак, я должен определить приблизительную ширину Гаусса, пробуя разные ширины Гаусса в обратном фильтре и оценивая, какие результирующие изображения выглядят «лучшими».

Наилучший результат будет оптимально четким, т. е. края будут выглядеть четкими, но не будут иметь видимого звона.

Я пробовал, используя 3 подхода:

  1. Я создал передаточную функцию с N измерениями (нечетное число для простоты), создав сетку N измерений, а затем применив к этой сетке функцию Гаусса. После этого мы добавляем к этой передаточной функции нули, чтобы получить тот же размер, что и исходное изображение. Однако после применения фильтра к исходному изображению я вижу только шум (слишком много артефактов).
  2. Я создал передаточную функцию размером с исходное изображение, создав сетку того же размера, что и исходное изображение. Если sigma слишком мало, то величина PSF FFT широкая. В противном случае он становится тоньше. Если sigma мало, то изображение будет еще более размытым, но если мы установим очень высокое значение sigma, то получим такое же изображение (совсем не лучше).
  3. Я использовал функцию fspecial, играя с размерами sigma и h. Но все же у меня не получается ничего более резкого, чем исходное размытое изображение.

Любые идеи?

Вот код, используемый для создания передаточной функции в подходе 1:

%Create Gaussian Filter
function h = transfer_function(N, sigma, I) %N is the dimension of the kernel
%create a 2D-grid that is the same size as the Gaussian filter matrix
grid = -floor(N/2) : floor(N/2);
[x, y] = meshgrid(grid, grid);
arg = -(x.*x + y.*y)/(2*sigma*sigma);
h = exp(arg); %gaussian 2D-function
kernel = h/sum(h(:)); %Normalize so that total weight equals 1

[rows,cols] = size(I);
add_zeros_w = (rows - N)/2;
add_zeros_h = (cols - N)/2;

h = padarray(kernel,[add_zeros_w  add_zeros_h],0,'both'); % h = kernel_final_matrix

end 

И это код для каждого подхода:

I = imread('lena_blur.jpg');
I1 = rgb2gray(I);
figure(1),
I1 = double(I1);
%---------------Approach 1
% N = 5; %Dimension Assume is an odd number
% sigma = 20; %The bigger number, the thinner the PSF in FREQ
% H = transfer_function(N, sigma, I1);
%I1=I1(2:end,2:end); %To simplify operations
imagesc(I1); colormap('gray'); title('Original Blurred Image')

I_fft = fftshift(fft2(I1)); %Shift the image in Fourier domain to let its DC part in the center of the image



% %FILTER-----------Approach 2---------------
% N = 5; %Dimension Assume is an odd number
% sigma = 20; %The bigger number, the thinner the PSF in FREQ
% 
% 
% [x,y] = meshgrid(-size(I,2)/2:size(I,2)/2-1, -size(I,1)/2:size(I,1)/2-1);
% H = exp(-(x.^2+y.^2)*sigma/2);
% %// Normalize so that total area (sum of all weights) is 1
% H = H /sum(H(:));
% 
% %Avoid zero freqs
% for i = 1:size(I,2) %Cols
%     for j = 1:size(I,1) %Rows
%         if (H(i,j) == 0)
%             H(i,j) = 1e-8;
%         end
%     end
% end
% 
% [rows columns z] = size(I);
% G_filter_fft = fft2(H,rows,columns);
%FILTER---------------------------------


%Filter--------- Aproach 3------------
N = 21; %Dimension Assume is an odd number
sigma = 1.25; %The bigger number, the thinner the PSF in FREQ

H = fspecial('gaussian',N,sigma)
[rows columns z] = size(I);
G_filter_fft = fft2(H,rows,columns);

%Filter--------- Aproach 3------------



%DISPLAY FFT PSF MAGNITUDE
figure(2),
imshow(fftshift(abs(G_filter_fft)),[]); title('FFT PSF magnitude 2D');


% Yest = Y_blurred/Gaussian_Filter
I_restoration_fft = I_fft./G_filter_fft;
I_restoration = (ifft2(I_restoration_fft));
I_restoration = abs(I_restoration);




I_fft = abs(I_fft);

% Display of Frequency domain (To compare with the slides) 
figure(3),
subplot(1,3,1); 
imagesc(I_fft);colormap('gray');title('|DFT Blurred Image|')
subplot(1,3,2)
imshow(log(fftshift(abs(G_filter_fft))+1),[]) ;title('| Log DFT Point Spread Function + 1|');
subplot(1,3,3)
imagesc(abs(I_restoration_fft));colormap('gray'); title('|DFT Deblurred|')
% imshow(log(I_restoration+1),[])

%Display PSF FFT in 3D
figure(4)
hf_abs = abs(G_filter_fft);
%270x270
surf([-134:135]/135,[-134:135]/135,fftshift(hf_abs));
% surf([-134:134]/134,[-134:134]/134,fftshift(hf_abs));
shading interp, camlight, colormap jet
xlabel('PSF FFT magnitude')

%Display Result (it should be the de-blurred image)
figure(5),
%imshow(fftshift(I_restoration));
imagesc(I_restoration);colormap('gray'); title('Deblurred Image')

%Pseudo Inverse restoration
% cam_pinv = real(ifft2((abs(G_filter_fft) > 0.1).*I_fft./G_filter_fft));
% imshow(fftshift(cam_pinv));
% xlabel('pseudo-inverse restoration')

person Javiss    schedule 09.03.2017    source источник
comment
На веб-странице Matlab есть решения: blogs.mathworks.com/ steve/2007/08/13/ , вы смотрели на это??   -  person Konstantinos Monachopoulos    schedule 09.03.2017
comment
Также может быть интересно изучить deconwnr.   -  person m7913d    schedule 09.03.2017
comment
@monakons да, на самом деле мои решения частично основаны на этом блоге. Дело в том, что у меня вообще нет шума. Изображение просто размыто (не аддитивный шум).   -  person Javiss    schedule 09.03.2017
comment
@ m7913d у меня нет шума...   -  person Javiss    schedule 09.03.2017
comment
Вы можете использовать его для изображения без шумов, просто установите NSR на ноль. Обратите внимание, что у вас всегда есть шум квантования.   -  person m7913d    schedule 09.03.2017
comment
Тем не менее, не имея каких-либо полезных результатов. I = imread('lena_blur.jpg'); Н = 19; %Dimension Предположим, что это нечетное число sigma = 0,75; %Чем больше число, тем тоньше ФРТ в FREQ H = fspecial('gaussian',N,sigma) Assessment_nsr = 0; wnr3 = deconvwnr(I, H, оценка_nsr); Figure, imshow(wnr3) title('Восстановление размытого, зашумленного изображения с помощью оценки NSR');   -  person Javiss    schedule 09.03.2017


Ответы (1)


Возможным решением является deconvwr. Сначала я покажу его работу, начиная с неискаженного изображения Лены. Итак, я точно знаю функцию размытия по Гауссу. Обратите внимание, что установка estimated_nsr на ноль полностью разрушит производительность из-за шума квантования.

 I_ori = imread('lenaTest3.jpg'); % Download an original undistorted lena file
 N = 19;
 sigma = 5;
 H = fspecial('gaussian',N,sigma) 
 estimated_nsr = 0.05;

 I = imfilter(I_ori, H)

 wnr3 = deconvwnr(I, H, estimated_nsr); 
 figure
 subplot(1, 4, 1);
 imshow(I_ori) 
 subplot(1, 4, 2);
 imshow(I) 
 subplot(1, 4, 3);
 imshow(wnr3) 
 title('Restoration of Blurred, Noisy Image Using Estimated NSR'); 
 subplot(1, 4, 4);
 imshow(H, []);

Методом проб и ошибок лучшие параметры для вашей задачи я нашел.

 N = 19; 
 sigma = 2; 
 H = fspecial('gaussian',N,sigma) 
 estimated_nsr = 0.05;

EDIT: точное вычисление используемого фильтра размытия

Если вы загружаете неискаженную лену (I_original_fft), вы можете рассчитать используемый фильтр размытия следующим образом:

G_filter_fft = I_fft./I_original_fft
person m7913d    schedule 09.03.2017
comment
Спасибо за Ваш ответ. Но мне нужно работать именно с этим изображением, которое я разместил на первом изображении. Как я уже писал: я должен определить приблизительную ширину Гаусса, пробуя разные ширины Гаусса в ОБРАТНОМ фильтре и оценивая, какие результирующие изображения выглядят «лучшими». Это означает, что если я напишу: I_restoration_fft = I_fft./G_filter_fft; Тогда обратное БПФ должно быть изображением, которое я хочу. Я достигаю этого, находя правильные параметры Гаусса. deconwnr бесполезен (меня не просили поработать над шумом или использовать винеровский фильтр) - person Javiss; 10.03.2017
comment
Как я показал в примере выше. рекомендуется предположить некоторый шум на изображении. Если вы запустите приведенный выше пример, вы получите очень плохой результат, если установите estimated_nsr равным нулю, даже если фильтр размытия по Гауссу точно известен. Если я правильно посмотрел ваш код, вы в основном реализуете deconwnr с нулевым шумом. Моя вторая часть кода — это параметры, которые немного повышают резкость вашего изображения. - person m7913d; 10.03.2017
comment
В любом случае, если вы используете: I = imfilter(I_ori, H), вы выполняете свертку в пространственной области. и что я должен сделать, так это точечное разделение в частотной области, т. Е. I_restoration_fft = I_fft./G_filter_fft, что не то же самое, что свертка в пространственной области. - person Javiss; 10.03.2017
comment
Обратите внимание, что я использовал imfilter для размытия неискаженного изображения Лены, поэтому я знаю точную функцию размытия и могу протестировать deconvwnr. Я использую deconvwnr для восстановления изображения без необходимости самому писать кучу кода. Во-вторых, обратите внимание, что вы сказали, что ваш метод основан на этом сообщении., который очень похож на метод Винера, описанный в комментариях к этому сообщению. - person m7913d; 10.03.2017
comment
Ох, хорошо. Что ж, вы, вероятно, получаете хороший результат, поскольку вы уже знаете гауссиану (когда вы размываете изображение) и устраняете размытие размытого изображения, используя ту же гауссиану. Суть здесь в том, чтобы УГАДАТЬ параметры гаусса, поскольку вам дается размытое изображение (которое было размыто гауссианом с определенными параметрами; те же параметры, которые вы должны угадать). Итак, будьте моим гостем и попробуйте deconwnr с МОИМ ИЗОБРАЖЕНИЕМ, тем же, что я разместил в первом посте. вы увидите, что deconwnr не дает хорошего результата. - person Javiss; 10.03.2017
comment
Это именно то, что я пробовал со своим вторым блоком кода. Это сделает лицо несколько четче, но края изображения исказятся. Я включил первый блок кода, чтобы показать вам максимальную производительность этого метода. - person m7913d; 10.03.2017
comment
@Javiss Я добавил метод для точного расчета фильтра размытия. - person m7913d; 10.03.2017
comment
Я думаю, что это не то, что я ищу. То, что вы делаете, это размывает уже размытую Лену (моя оригинальная картинка). Я хочу сделать исходное изображение более четким. В конечном итоге вы получаете более четкое изображение по сравнению с размытой версией моего размытого исходного изображения (так что оно как бы дважды размыто). Однако, если сравнивать с моей оригинальной размытой Леной, то у вас конечный результат ничуть не резче, а даже больше размытия. - person Javiss; 10.03.2017
comment
Этот последний блок кода действительно полезен, мне не пришло в голову использовать его. Но, тем не менее... Мне нужно обсудить значения sigma и hsize, которых вы не знаете (Вы просто получаете уже построенный PSF). - person Javiss; 10.03.2017
comment
Под исходным изображением я имел в виду неискаженную версию Лены, которую вы легко найдете в Интернете. Что касается остальных ваших замечаний, я оставлю это кому-то другому, чтобы ответить на ваши вопросы, который, надеюсь, даст вам ответ, который лучше соответствует тому, что вы хотите. - person m7913d; 10.03.2017