imnoise normalization

26 views (last 30 days)
Jaime
Jaime on 15 Apr 2012
Dear Matlab-community,
currently i am working with the function imnoise, however i don't fully understand why is it needed to normalize both the input images and the optional arguments to the range [0,1]. Since i would like to preserve the mean gray value of the images after noise addition (which should be at least close to the mean gray value of the noiseless image), i would like to skip normalization.
When i use the following two functions (see below) before and after imnoise for both the noiseless image and the input parameters i get noisy images which are completely offscale, i.e. the mean gray value is totally different from the orginal one.
For any hint thanks in advance, Jaime
function output = rescale(orig_image, input)
output = ( input - min(orig_image(:)) )./( max(orig_image(:)) - min(orig_image(:)) );
end
function output = rescale_back(sc_image, input)
output = input.*( max(sc_image(:)) - min(sc_image(:)) ) + min(sc_image(:));
end
  2 Comments
Image Analyst
Image Analyst on 15 Apr 2012
What is syntim? Wouldn't you just multiply by 255 and cast to uint8 to get your normalized image back to 0-255?
Jaime
Jaime on 16 Apr 2012
it's a typo, i meant sc_image

Sign in to comment.

Accepted Answer

Jaime
Jaime on 25 Apr 2012
Dear Matlab community,
so after several trial and error using imnoise and rethinking my orginal question over again, i think the function imnoise is not suitable when your image includes negative values which you would like to "preserve" after noise addition.
For example if you would use a imnoise with a 'gaussian' with a mean value close to zero, say 0.01, and then use a sigma of 0.1 , pixel values that lie below zero will be truncated to zero. This means that after you scale back your image you would have a trend toward higher pixel values since the "negative truncated pixels are not there". That is why in this case the mean gray value of the noisy image will be larger than the one in the noiseless image.
Regards,
Jaime
  1 Comment
Walter Roberson
Walter Roberson on 25 Apr 2012
Correct, imnoise does internally move negative values up to 0.
The code for adding gaussian noise is simple: the noise is randn() times sqrt(variance), plus the mean.
If you had a particular negative value that you wanted to clip against, set the mean to be abs() of that, run imnoise, and subtract that abs() back off. This will of course still be biased, as true gaussian noise can produce down to -inf.

Sign in to comment.

More Answers (2)

Image Analyst
Image Analyst on 15 Apr 2012
Use im2double. Try this demo and I think you'll see how to do it. I do it for two different levels of noise and display the original and the two noisy images, and calculate the mean of all three images.
clc; % Clear the command window.
workspace; % Make sure the workspace panel is showing.
clearvars;
fontSize = 20;
format compact;
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'cameraman.tif';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows columns numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')
% Calculate the mean
mean0 = mean(grayImage(:))
% Add noise to image
normalizedGrayImage = im2double(grayImage);
noiseStDev = 0.01;
noisyImage1 = uint8(255 * imnoise(normalizedGrayImage,'gaussian', 0, 0.01));
% Display the image.
subplot(2,2,2);
imshow(noisyImage1, []);
noiseGrayLevels = noiseStDev * 255.
caption = sprintf('Image with added noise of\n%.2f * 255 = %.2f',...
noiseStDev, noiseGrayLevels);
title(caption, 'FontSize', fontSize);
% Calculate the mean
mean1 = mean(noisyImage1(:))
% Add noise to image
noiseStDev = 0.04;
noisyImage2 = uint8(255 * imnoise(normalizedGrayImage,'gaussian', 0, noiseStDev));
% Display the image.
subplot(2,2,3);
imshow(noisyImage2, []);
noiseGrayLevels = noiseStDev * 255.
caption = sprintf('Image with added noise of\n%.2f * 255 = %.2f',...
noiseStDev, noiseGrayLevels);
title(caption, 'FontSize', fontSize);
% Calculate the mean
mean2 = mean(noisyImage2(:))
message = sprintf('Original mean = %.3f\nImage1 mean = %.3f\nImage2 mean = %.3f',...
mean0, mean1, mean2);
msgbox(message);

Jaime
Jaime on 17 Apr 2012
Hello,
thanks for the answer and the demo. However, i might be missing something here. I have an image which has negative values and i would like to conserve them after i get my noisy images back. Here's some snippet code of what i tried following your suggestion. Still the mean gray levels after noise addition are way off of what i expect.
function [syn_noise1, syn_noise2, syn_noise3] = imnoise_demo_matlabQuestion(syntim)
%syntim is a 2D image with gray values ranging from -100 to 1000 or even higher
if ~strcmpi(class(syntim), 'double')
disp('casting image to double type');
syntim = double(syntim);
end
noise_var = [ 1. 10. 50. ]; %noise levels in original units
mean_var = 0.; %mean level in original units
disp('Creating Noisy Images with Gaussian Noise....using function *imnoise*');
disp(['mean = ' num2str(mean_var) '; variance = ' num2str(noise_var) ] );
% Use this values for mapping, just making sure they are above and below
% my image min and max values, respectively.
minInt16Scale = double(intmin('int16'));
maxInt16Scale = double(intmax('int16'));
% Normalization allowing for negative values in the range i am expecting
normalizedSyntim = double( (syntim - minInt16Scale)./(maxInt16Scale - minInt16Scale) );
normalizedNoise_var = double( (noise_var - minInt16Scale)./(maxInt16Scale - minInt16Scale) );
normalizedMean_var = double( (mean_var - minInt16Scale)./(maxInt16Scale - minInt16Scale) );
% Add noise
syn_noise1(:,:) = imnoise(normalizedSyntim, 'gaussian', normalizedMean_var, normalizedNoise_var(1));
syn_noise2(:,:) = imnoise(normalizedSyntim, 'gaussian', normalizedMean_var, normalizedNoise_var(2));
syn_noise3(:,:) = imnoise(normalizedSyntim, 'gaussian', normalizedMean_var, normalizedNoise_var(3));
% Rescaling back the images.
syn_noise1 = syn_noise1.*(maxInt16Scale - minInt16Scale) + minInt16Scale ;
syn_noise2 = syn_noise2.*(maxInt16Scale - minInt16Scale) + minInt16Scale ;
syn_noise3 = syn_noise3.*(maxInt16Scale - minInt16Scale) + minInt16Scale ;
end
  1 Comment
Image Analyst
Image Analyst on 17 Apr 2012
How much are they off? You are adding noise so the mean won't be EXACTLY the same, but it should be close.

Sign in to comment.

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!