function im_deblur = WienerMartin(im, len, angle, SNR)

% Restores Image Using Wiener Filter
%
% im_deblur = WienerMartin(im, len, angle, SNR)
%
% Inputs: im, len, angle, SNR
% Returns: im_deblur
%
% im:    Input Image
% angle: Blur Angle (Degrees) 
% len:   Blur Length (Number of Pixels)
% SNR: SNR of Original Image
%
% im_deblur: Restored Image

% Perform Median Filtering
im = medfilt2(abs(im));

% Converting to Frequency Domain
IM = fft2(im);

% Create psf of Blur
psf = fspecial('motion',len,angle);

% Convert psf to OTF of Desired Size
% OTF is Optical Transfer Function
OTF = psf2otf(psf,size(IM));

% Conjugate
OTFC = conj(OTF);
modOTF = OTF.*OTFC;

% Avoid Divide by Zero
for i = 1:size(OTF, 1)
    for j = 1:size(OTF, 2)
        if OTF(i, j) == 0
            OTF(i, j) = 0.000001;
        end
    end
end

% Deblur Image Using WIENER FILTER
debl = (OTFC ./ ( modOTF + (1/SNR) )).*IM;

% Restored Image
im_deblur = ifft2(debl);