I'm trying to remove a Gaussian noise from an image. I've added the noise myself using:
nImg = imnoise(img,'gaussian',0,0.01);
I now need to remove the noise using my own filter, or at least reduce it. In theory, as I understand, using a convolution matrix of ones(3)/9 should help and using a Gaussian convolution matrix like [1 2 1; 2 4 2; 1 2 1]/9 or fspecial('gaussian',3) should be better. Yet, they really don't do the trick so well:
Am I missing something important? I need to use convolution, by the way.
You are not missing anything!
Obviously, you can't remove the noise completely. You can try different filters, but all of them will have a tradeoff:
More Noise + Less blur VS Less Noise + More blur
It becomes more obvious if you think of this in the following way:
Any convolution based method assumes that all of the neighbors have the same color.
But in real life, there are many objects in the image. Thus, when you apply the convolution you cause blur by mixing pixels from different adjacent objects.
There are more sophisticated denoising methods like:
Median denoising
Bilateral filter
Pattern matching based denoising
They are not using only convolution. By the way, even they can't do magic.
you can use wiener2 which works best when the noise is constant-power ("white") additive
noise, such as Gaussian noise.
You made a mistake with the Gaussian convolution matrix. You need to divide it by 16, not 9, so that it's sum equals 1. That's why the resulting image using that matrix is so light.
Related
I have a gray image with noise. I am new in deleting noise from an image so I don't know the type of noise and how I can remove it from image. My aim is to convert image to binary mode by using local threshold after removing the noise.
Is there anybody who has any idea about type of noise and has a method to remove this noise?
The image:
Typically in microscopy noise comes from 2 sources:
1) Gaussian/electronic noise
This type of noise come from the fluctuations in the detector due to quantum effects in the electronics. It is randomly generated and follows a gaussian distribution. Therefore in that case using a gaussian filter might be optimal to remove it.
2) Shot noise
Photons arriving at the detector are converted to electric signal through the photoelectric effect, and the fluctuations in the number of photons arriving at the detector create shot noise, which you can hardly eliminate and is usually predominant during acquisition. It follows a Poisson distribution which looks like a Gaussian, so in this case a gaussian filter might be the appropriate as well.
So to come back to your question, it does look like a gaussian filter would be the most intuitive choice, although an average filter could be used as well. Here is a sample code that you could try and play around with:
clear
close all
clc
A = imread('http://i.stack.imgur.com/IlqAi.jpg');
BW = im2bw(A,.9); %//Treshold image
h = fspecial('gaussian', [5 5],.8); %// Create gaussian filter
BW2 = imfilter(BW,h); %// Apply filter
imshow(BW2); %// Display image
which results in the following:
You can change the filter parameters (i.e. the size of the kernel and the sigma value) and see how they affect the outcome. Here are other filters you can use as well:
Median:
BW2 = medfilt2(BW,[3 3]); %// Median filter
or average:
h = fspecial('average', 3) %//average filter
BW2 = imfilter(BW,h);
You might be interested in this link on the Mathworks website that talks about removing noise in images.
Hope that helps!
Let's say For each pixel, the gradient ∇g= [∂f/∂x, ∂f/∂y]. Then the first derivative should be measured by two operators like 1/2[1,0,1;0,0,0;-1,0,-1] & 1/2[-1,0,1;0,0,0;-1,0,-1]
then:
[i,j]=gradient(im);
filt1=[1,0,1;0,0,0;-1,0,-1];
filt2=[-1,0,1;0,0,0;-1,0,-1];
ii=(1./2).*(conv2(filt1,i));
jj=(1./2).*(conv2(filt2,j));
G_x=conv2(ii,im);
G_y=conv2(jj,im);
Is it correct or I should first multiply 1/2 to the operators, and then convolve them?
since associativity (with scalars) is a quality of convolutions the order of the multiplication should not play any rolle.
On the other hand your filters don't seem to me like they perform a differentiation. The classical filter for the discrete differentiation would be a Sobel that looks something like this:
[1,0,-1
2,0,-2
1,0,-1]
and
[1,2,1
0,0,0
-1,-2,-1]
For the purposes of optimizing the computation, it helps to apply the scaling of 1/2 directly to the filter kernels
filt1 = filt1/2;
Otherwise, if done afterward, N^2 additional multiplications have to be done to the NxN image pixels, instead of just 9 multiplications to a 3x3 kernel.
Beyond that, I agree with McMa. Your computations don't look anything like a differentiation. In fact, you already apply gradient() in the very first line, so I don't understand what more you need.
I'd be inclined to use the imgradient and imgradientxy functions in MATLAB. If you want directional gradients, use imgradientxy and if you want gradient magnitude and direction components, use imgradient.
You can choose to have derivatives computed using Sobel,Prewitt or Roberts gradient kernels or using central or intermediate differences.
Here's an example:
[Gx,Gy] = imgradientxy(im,'Sobel');
Instead if you want to continue using conv2, you can get gradient kernels using the fspecial function.
kernelx = fspecial('sobel');
kernely = kernelx';
I was given this task, I am a noob and need some pointers to get started with centroid calculation in Matlab:
Instead of an image first I was asked to simulate a Gaussian distribution(2 dimensional), add noise(random noise) and plot the intensities, now the position of the centroid changes due to noise and I need to bring it back to its original position by
-clipping level to get rid of the noise, noise reduction by clipping or smoothing, sliding average (lpf) (averaging filter 3-5 samples ), calculating the means or using Convolution filter kernel - which does matrix operations which represent the 2-D images
Since you are a noob, even if we wrote down the answer verbatim you probably won't understand how it works. So instead I'll do what you asked, give you pointers and you'll have to read the related documentation :
a) to produce a 2-d Gaussian use meshgrid or ndgrid
b) to add noise to the image look into rand ,randn or randi, depending what exactly you need.
c) to plot the intensities use imagesc
d) to find the centroid there are several ways, try to further search SO, you'll find many discussions. Also you can check TMW File exchange for different implementations for that.
Is there a 3D eqivalent of imfilter available for MATLAB? I wish to apply Gaussian filtering to a 3D histogram. I was going to implement it myself, by creating a (3D) Gaussian filter, then looping over each element in my histogram, and summing up the corresponding data entries.
However, I didn't want to implement it myself in a slow and inefficient way if there's something already out there, or a cleverer way of doing it.
There are two ways to solve this in order to do the filtering in an efficient manner:
(1) Use CONVN three times to filter your data with three 1D Gaussians, one x-by-1-by-1, one 1-by-y-by-1, and one 1-by-1-by-z.
(2) If you have the signal processing toolbox, use FFTFILT to perform filtering in inverse space (or use any one of the fft-convolution algorithms on the file exchange).
[(3) Send me an email and I'll send you my fftFilterImage, which does 3D Gauss filtering.]
imfilter can already do 3D filtering, as long as the data matrix and the filter you give it are 3D. See the imfilter page.
This task can be handled with the new (as of R2015a) imgaussfilt3 function.
The basic syntax is as follows:
B = imgaussfilt3(A,sigma)
There are also a number of name-value pair arguments:
'FilterSize': Size of the Gaussian filter, defaulting to a cube of size 2*ceil(2*sigma)+1.
'Padding': Type of padding ('replicate' (default) | 'circular' | 'symmetric').
'FilterDomain': Perform convolution in domain: 'frequency' or 'spatial' (default auto).
Does the 'gaussian' filter in MATLAB convolve the image with the Gaussian kernel? Also, how do you choose the parameters hsize (size of filter) and sigma? What do you base it on?
You first create the filter with fspecial and then convolve the image with the filter using imfilter (which works on multidimensional images as in the example).
You specify sigma and hsize in fspecial.
Code:
%%# Read an image
I = imread('peppers.png');
%# Create the gaussian filter with hsize = [5 5] and sigma = 2
G = fspecial('gaussian',[5 5],2);
%# Filter it
Ig = imfilter(I,G,'same');
%# Display
imshow(Ig)
#Jacob already showed you how to use the Gaussian filter in Matlab, so I won't repeat that.
I would choose filter size to be about 3*sigma in each direction (round to odd integer). Thus, the filter decays to nearly zero at the edges, and you won't get discontinuities in the filtered image.
The choice of sigma depends a lot on what you want to do. Gaussian smoothing is low-pass filtering, which means that it suppresses high-frequency detail (noise, but also edges), while preserving the low-frequency parts of the image (i.e. those that don't vary so much). In other words, the filter blurs everything that is smaller than the filter.
If you're looking to suppress noise in an image in order to enhance the detection of small features, for example, I suggest to choose a sigma that makes the Gaussian just slightly smaller than the feature.
In MATLAB R2015a or newer, it is no longer necessary (or advisable from a performance standpoint) to use fspecial followed by imfilter since there is a new function called imgaussfilt that performs this operation in one step and more efficiently.
The basic syntax:
B = imgaussfilt(A,sigma) filters image A with a 2-D Gaussian smoothing kernel with standard deviation specified by sigma.
The size of the filter for a given Gaussian standard deviation (sigam) is chosen automatically, but can also be specified manually:
B = imgaussfilt(A,sigma,'FilterSize',[3 3]);
The default is 2*ceil(2*sigma)+1.
Additional features of imgaussfilter are ability to operate on gpuArrays, filtering in frequency or spacial domain, and advanced image padding options. It looks a lot like IPP... hmmm. Plus, there's a 3D version called imgaussfilt3.