-->

Image deblurring using gaussian filter in matlab w

2019-07-24 19:19发布

问题:

I have to use an inverse filter to remove the blurring from this image

.

Unfortunately, I have to figure out the transfer function H of the imaging system used to get these sharper images, It should be Gaussian. So, I should determine the approximate width of the Gaussian by trying different Gaussian widths in an inverse filter and judging which resulting images look the “best”.

The best result will be optimally sharp – i.e., edges will look sharp but will not have visible ringing.

I tried by using 3 approaches:

  1. I created a transfer function with N dimensions (odd number, for simplicity), by creating a grid of N dimensions, and then applying the Gaussian function to this grid. After that, we add zeroes to this transfer function in order to get the same size as the original image. However, after applying the filter to the original image, I just see noise (too many artifacts).
  2. I created the transfer function with size as high as the original image, by creating a grid of the same size as the original image. If sigma is too small, then the PSF FFT magnitude is wide. Otherwise it gets thinner. If sigma is small, then the image is even more blurred, but if we set a very high sigma value then we get the same image (not better at all).
  3. I used the fspecial function, playing with sizes of sigma and h. But still I do not get anything sharper than the original blurred image.

Any ideas?

Here is the code used for creating the transfer function in Approach 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 

And this is the code for every approach:

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')

回答1:

A possible solution is deconvwr. I will first show its performance starting from an undistorted lena image. So, I know exactly the gaussian blurring function. Note that setting estimated_nsr to zero will destroy the performance completely due to quantisation noise.

 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, []);

The best parameters I found for your problem by trial and error.

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

EDIT: calculating exactly the used blurring filter

If you download an undistorted lena (I_original_fft), you can calculate the used blurring filter as follows:

G_filter_fft = I_fft./I_original_fft