clear all
close

%Steve on Image Processing
%http://blogs.mathworks.com/steve/2007/08/13/image-deblurring-introduction/
%Image deblurring - Introduction

%Image deblurring (or restoration) is an old problem in image processing, but it continues to attract the attention of researchers and practitioners alike. A number of real-world problems from astronomy to consumer imaging find applications for image restoration algorithms. Plus, image restoration is an easily visualized example of a larger class of inverse problems that arise in all kinds of scientific, medical, industrial and theoretical problems. Besides that, it's just fun to apply an algorithm to a blurry image and then see immediately how well you did.

%To deblur the image, we need a mathematical description of how it was blurred. (If that's not available, there are algorithms to estimate the blur. But that's for another day.) We usually start with a shift-invariant model, meaning that every point in the original image spreads out the same way in forming the blurry image. We model this with convolution:

%Form PSF as a disk of radius 3 pixels

figure(1)
h = fspecial('disk',4);
% Read image and convert to double for FFT
cam = im2double(imread('cameraman.tif'));
hf = fft2(h,size(cam,1),size(cam,2));
cam_blur = real(ifft2(hf.*fft2(cam)));
imshow(cam_blur)

%%
%Now we need to add some noise. If we define peak SNR (PSNR) as
%Now we add noise to get a 40 dB PSNR:

figure(2)
sigma_u = 10^(-40/20)*abs(1-0);
cam_blur_noise = cam_blur + sigma_u*randn(size(cam_blur));
imshow(cam_blur_noise)

%%
figure(3)
cam_inv = real(ifft2(fft2(cam_blur_noise)./hf));
imshow(cam_inv)


%%
hf_abs = abs(hf);
surf([-127:128]/128,[-127:128]/128,fftshift(hf_abs))
shading interp, camlight, colormap jet
xlabel('PSF FFT magnitude')


%%
figure(4)
cam_pinv = real(ifft2((abs(hf) > 0.1).*fft2(cam_blur_noise)./hf));
imshow(cam_pinv)
xlabel('pseudo-inverse restoration')


%%
figure(5)
imshow(cam_blur_noise)
xlabel('blurred image with noise')


%%
figure(6)
cam_pinv2 = real(ifft2(fft2(cam_blur_noise).*conj(hf)./(abs(hf).^2 + 1e-2)));
imshow(cam_pinv2)
xlabel('alternative pseudo-inverse restoration')
