How to add and remove noise from an image

折月煮酒 提交于 2019-12-04 19:38:59

Judging from the context of your comments and the question you're asking, you wish to completely remove the noise from an already corrupted image. You can only do a complete removal if you know the impulse response / point spread function (PSF) of the noise input process in the first place. Knowing the PSF and doing a noise removal with this is commonly known as deconvolution. Because the PSF of a random noise process is seldom known in practice and the fact that noise is a random process, it is practically impossible to completely remove all the noise. There are certainly models of noise that exist, but knowing the exact parameters of the noise model that corrupted your image is very difficult (if not, impossible...) to determine.

You can certainly remove most of it and you will not get the original image back, but you can mitigate the noise through standard noise filtering techniques. To remove Gaussian noise, you can simply use any standard low-pass filtering method, such as average filtering or Gaussian filtering. You can also use Wiener filtering where it is an adaptive filter. It analyzes the pixel neighbourhoods of your image and computes the variance of each neighbourhood. If the variance is small, more smoothing is performed and vice-versa. Take a look at this link for a good example.


Now, in your code you have posted, you have opted to use conv2. One small thing I will point out is that your filtering code does not do median filtering. You are implementing an average filter. If you want to use median filtering, use medfilt2 instead.

In any case, though conv2 is great for any 2D signal in general, I would recommend you use imfilter instead. It is specifically designed to filter images (linear filtering actually...), and it also takes advantage of the Intel's IPP library should your computer / processor support its use. I tried running your code (using conv2) on my machine with the standard cameraman.tif image and I get an output that isn't blank as mentioned in your comments. My guess is that you're getting a blank image due to the casting to uint8. L was most likely converted to a double precision image that ranges between [0,1] and when you simply cast to uint8, you'll only get an image that has intensities of 0 or 1 which is why you don't see anything. Try converting your image using im2uint8 so that you can contrast normalize the intensities to [0,255] instead for suitable display with imshow.

However, if you use imfilter, there is no need to convert types as imfilter will respect whatever the type of the input image was and will use that same type for the output image. As such, make your code look something like this:

L = imread('cameraman.tif'); %// Load in image from MATLAB system path 
P =0;  %mean
Q =0.01; %variance
R = imnoise(L,'gaussian',P,Q); %L-image
subplot(2,1,1);
imshow(R);
title('Gaussian Noise');

U = imfilter(R, ones(3)/9, 'replicate');   %// Change - Use imfilter
subplot(2,1,2);
imshow(U);
title('Average Filtered Image'); %// Changed title to be correct

This is what I get:


Now, to answer your questions about the different kinds of noise you want to filter, Poisson noise can be filtered by low-pass filters as well (average, Gaussian, etc.). Salt and pepper noise is best filtered with median filtering. Here's a great example on how median filtering works for salt and pepper noise.

As to what "extent" you can remove the noise, that totally depends on trial and error. You simply have to keep filtering your image with different filter sizes and parameters until you get what you believe is perceptually good quality or using the image with the highest PSNR out of all of your trials. Obviously, the more noisy your image is, the more aggressive you need to make your filter, but you risk not being able to recognize what the original image looked like in the first place.

This is mostly a trial and error process, so you'll have to play around with the parameters and see what you get.


I hope this has adequately answered your questions. Good luck!

Based on your comment it seems acceptable to save the original, unmodified image data from imread() into a separate array variable, which is used when the image with the noise completely removed is needed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!