Image deblurring using the Wiener deconvolution - matlab

I am trying to deblur the following image by Wiener deconvolution. I was not given the original PSF, and I came up with an arbitrary value for the noise figure. I tried to optimize the code by playing around with the sigma values but I cannot get it to work.
my code...
img = im2double(imread('C:\Users\adhil\Desktop\matlab pics\test.JPG'));
LEN = 2;
THETA = 5;
PSF = fspecial('gaussian', LEN, THETA);
wnr1 = deconvwnr(img, PSF, 0.0000001);
imshow(wnr1);
title('Restored Image');
subplot(1,2,1);imshow(img);title('Before');
subplot(1,2,2);imshow(wnr1);title('After');
here is the result...
please advise

If you have no idea what the point spread function is, or you try an approximation that is far from the actual point spread function, Wiener deconvolution won't work very well, because it relies on knowing the point spread function.
You might have better results trying blind deconvolution (Matlab function):
deconvblind
using an array of ones the same size as your Gaussian PSF guess as the initial PSF (using the array of ones is suggested by the Matlab documentation).

Related

Matlab quadratic equation/convolution

I've got a convolution where the final result is
y=(-t/2)+5t=6
Is there any chance to check this in matlab but not through convolution, I have programmed that part. What I am wondering is it possible to plot the signal using this equation and compare it with the one that I got with coding convolution.
You can plot functions easily in matlab: look at the examles from here.
For example using this code:
t = 0:.1:10
plot(t,(-t/2)+5*t)
will plot you your function between the values x = [0, 10].

Smooth out Image Vector in Matlab

I have an image that I converted to a vector and plotted:
img = imread(image.png');
grayImage = rgb2gray(img);
grayImage(2:2:end,:)=fliplr(grayImage(2:2:end,:));
B = rot90(grayImage);
C = flipud(B);
[x,y]=size(C);
vector = reshape(C ,1,x*y);
plot(vector);
The problem is that although I can visually see a wave pattern, there is a lot of noise that occurs. By noise I mean the signals rapidly go up and down eventually forming a sinusoidal wave but I want to be able to just connect the crest of each spike to one another in order to create a continuous wave pattern. If anyone understands what I am trying to do, help would be appreciated.
Thank you in advance.
Not 100% sure about what you're asking, but the medfilt1 median filter function might be what you're looking for, it's a 1D smoothing filter. Example usage would be:
vector_filt = medfilt1(vector);
Check out the documentation and example at http://www.mathworks.com/help/signal/ref/medfilt1.html.
I think performing a gaussian convolution on the vector should solve your problem. Here is a link to a stack overflow question that has a very nice answer on how to do a gaussian convolution in matlab: Gaussian Filter on a vector in Matlab

Discrete Approximation to Gaussian smoothing

I am trying to find a discrete approximation to the Gaussian smoothing operation, as shown in the link :
http://bit.ly/1cSgkwt
G is some discrete smoothing kernel, a Gaussian in this case and * is the convolution operation. Basically, I want to apply a smoothing kernel to each pixel in the image. I am doing this in MATLAB and using the following code to create the matrix G, which is naive and hence painfully slow :
z = rgb2gray(imread('train_02463_1.bmp'));
im_sz = size(z);
ksize = 5;
% Gaussian kernel of size ksize*ksize
gw_mat = g_sigma(1,2*ksize+1)'*g_sigma(1,2*ksize+1);
G = sparse(length(ksize+1:im_sz(1)-ksize),prod(im_sz));
for i = ksize+1:im_sz(1)-ksize
for j = ksize+1:im_sz(2)-ksize
[x,y] = meshgrid(i-ksize:i+ksize,j-ksize:j+ksize);
row_num = sub2ind(im_sz,i,j);
colnums = sub2ind(im_sz,x,y);
G(row_num,colnums(:)) = gw_mat(:)';
end
end
Is there a more efficient way to do this ?
EDIT: I should apologize for not complete specifying the problem. Most of the answers below are valid ones, but the issue here is the above approximation is part of a optimization objective where the variable is z. The whole problem looks something like this :
http://goo.gl/rEE02y
Thus, I have to pre-generate a matrix G which approximates a smoothing function in order to feed this objective to a solver. I am using cvx, if that helps.
Typically people do it by applying two 1D Gaussian functions sequentially instead of one 2D function (idea of separable filters). You can approximate 1D horizontal Gaussian pretty fast, apply it to each pixel, save result in temp, and then apply a vertical Gaussian to temp. The expected speed up is quite significant: O(ksize*ksize) -> O(ksize+ksize)
You can use approximate Gaussian smoothing via box filters, e.g see integgaussfilt.m:
This function approximates Gaussian filtering by repeatedly applying
averaging filters. The averaging is performed via integral images which
results in a fixed and very low computational cost that is independent of
the Gaussian size.
The fastest way to apply Spatially Invariant Filter on an image using MATLAB would be using imfilter.
imfilter will automatically notice "Seperable" Kernel and will apply it in 2 steps (Vertically / Horizontally).
For creating some known and useful kernels you may look at fspecial.

Would Richardson–Lucy deconvolution work for recovering the latent kernel?

I am aware that Richardson–Lucy deconvolution is for recovering the latent image, but suppose we have a noisy image and the original image. Can we find the kernel that caused the transformation?
Below is a MATLAB code for Richardson-Lucy deconvolution and I am wondering if it is easy to modify and make it recover the kernel instead of the latent image. My thoughts are that we change the convolution options to valid so the output would represent the kernel, what do you think?
function latent_est = RL_deconvolution(observed, psf, iterations)
% to utilise the conv2 function we must make sure the inputs are double
observed = double(observed);
psf = double(psf);
% initial estimate is arbitrary - uniform 50% grey works fine
latent_est = 0.5*ones(size(observed));
% create an inverse psf
psf_hat = psf(end:-1:1,end:-1:1);
% iterate towards ML estimate for the latent image
for i= 1:iterations
est_conv = conv2(latent_est,psf,'same');
relative_blur = observed./est_conv;
error_est = conv2(relative_blur,psf_hat,'same');
latent_est = latent_est.* error_est;
end
Thanks in advance.
This is a very simple problem. Convolution is commutative. Hence, you don't need to change the implementation of RL deconvolution to obtain PSF, you can simply call it as follows:
psf = RL_deconvolution(observed, latent_est, iterations)

Smoothing of histogram with a low-pass filter in MATLAB

I have an image and my aim is to binarize the image. I have filtered the image with a low pass Gaussian filter and have computed the intensity histogram of the image.
I now want to perform smoothing of the histogram so that I can obtain the threshold for binarization. I used a low pass filter but it did not work. This is the filter I used.
h = fspecial('gaussian', [8 8],2);
Can anyone help me with this? What is the process with respect to smoothing of a histogram?
imhist(Ig);
Thanks a lot for all your help.
I've been working on a very similar problem recently, trying to compute a threshold in order to exclude noisy background pixels from MRI data prior to performing other computations on the images. What I did was fit a spline to the histogram to smooth it while maintaining an accurate fit of the shape. I used the splinefit package from the file exchange to perform the fitting. I computed a histogram for a stack of images treated together, but it should work similarly for an individual image. I also happened to use a logarithmic transformation of my histogram data, but that may or may not be a useful step for your application.
[my_histogram, xvals] = hist(reshape(image_volume), 1, []), number_of_bins);
my_log_hist = log(my_histogram);
my_log_hist(~isfinite(my_log_hist)) = 0; % Get rid of NaN values that arise from empty bins (log of zero = NaN)
figure(1), plot(xvals, my_log_hist, 'b');
hold on
breaks = linspace(0, max_pixel_intensity, numberofbreaks);
xx = linspace(0, max_pixel_intensity, max_pixel_intensity+1);
pp = splinefit(xvals, my_log_hist, breaks, 'r');
plot(xx, ppval(pp, xx), 'r');
Note that the spline is differentiable and you can use ppdiff to get the derivative, which is useful for finding maxima and minima to help pick an appropriate threshold. The numberofbreaks is set to a relatively low number so that the spline will smooth the histogram. I used linspace in the example to pick the breaks, but if you know that some portion of the histogram exhibits much greater curvature than elsewhere, you'd want to have more breaks in that region and less elsewhere in order to accurately capture the shape of the histogram.
To smooth the histogram you need to use a 1-D filter. This is easily done using the filter function. Here is an example:
I = imread('pout.tif');
h = imhist(I);
smooth_h = filter(normpdf(-4:4, 0,1),1,h);
Of course you can use any smoothing function you choose. The mean would simply be ones(1,8).
Since your goal here is just to find the threshold to binarize an image you could just use the graythresh function which uses Otsu's method.