2
votes

I am trying to remove noise from an already noisy RGB image. I've seen some examples where salt & pepper noise is added to a clean image and then removed again as an example, but I'm reading in an already noisy image if that makes sense. This code isn't making any changes to the original image for some reason. No noise has been removed at all. Any help would be appreciated.

train.jpg

p = imread("train.jpg");

redChannel = p(:, :, 1);
greenChannel = p(:, :, 2);
blueChannel = p(:, :, 3);

% Median Filter the channels:
redMF = medfilt2(redChannel, [3 3]);
greenMF = medfilt2(greenChannel, [3 3]);
blueMF = medfilt2(blueChannel, [3 3]);

% Find the noise in the red.
noiseImage = (redChannel == 0 | redChannel == 255);
% Get rid of the noise in the red by replacing with median.
noiseFreeRed = redChannel;
noiseFreeRed(noiseImage) = redMF(noiseImage);
% Find the noise in the green.
noiseImage = (greenChannel == 0 | greenChannel == 255);
% Get rid of the noise in the green by replacing with median.
noiseFreeGreen = greenChannel;
noiseFreeGreen(noiseImage) = greenMF(noiseImage);
% Find the noise in the blue.
noiseImage = (blueChannel == 0 | blueChannel == 255);
% Get rid of the noise in the blue by replacing with median.
noiseFreeBlue = blueChannel;
noiseFreeBlue(noiseImage) = blueMF(noiseImage);
% Reconstruct the noise free RGB image
rgbFixed = cat(3, noiseFreeRed, noiseFreeGreen, noiseFreeBlue);

figure, imshow(rgbFixed);
1
You're only replacing pixels with full colour (R/G/B=255) or no colour (R/G/B=0) for a given channel, with the locally filtered value - I suspect there are very few pixels which meet this criteria, so you're not removing a lot! If you changed the noiseImage condition, you may see a larger change. Try setting it to completely true (i.e. redChannel >= 0), then you'll see the overall effect of the medfilt2 function, and decide where it's even going to be effective.Wolfie
Thanks. I can see this isn't going to be very effective for heavily noised images. Is there anohter method you would recommend? I've looked into converting to hsv and remvoing the noise from each channel, but I'm not exactly sure how to do it.Premier Hottubs
This scope update puts the question outside my area, and likely makes it too broad for stackoverflow...Wolfie
@PremierHottubs while salt and pepper noise is nice for illustrative purposes, it is very uncommon in natural images (unless your camera is broken). Now, image denoising has been an active area of research for the last 30 years, so there is not "how to do it", or better said, there are thousands of ways on "how to do it". What you really need is a good book in image processing/image denoising!Ander Biguri

1 Answers

4
votes

As Ander Biguri commented, there are many methods to reduce noise in an image. Enumerating them all here is out of scope for Stack Overflow. But I will suggest one way: median filtering. I suggest this because you are already doing it!

You are applying medfilt2 to each channel of the input image. Simply skip all the stuff that comes after, and keep only the very last line: joining the channels back into an RGB image.

p = imread("train.jpg");

redChannel = p(:, :, 1);
greenChannel = p(:, :, 2);
blueChannel = p(:, :, 3);

% Median Filter the channels:
redMF = medfilt2(redChannel, [3 3]);
greenMF = medfilt2(greenChannel, [3 3]);
blueMF = medfilt2(blueChannel, [3 3]);

rgbFixed = cat(3, redMF, greenMF, blueMF)

figure, imshow(rgbFixed);

Since your image is very noisy, you might want to increase the size of the filter. But you will be compromising between noise and blurriness.