According to the literature, zero mean noises are those whose expected value is zero. But what does this mean in the context of images. Let us consider grayscale for now. The intensity values ranging from 0 to 255. The noise will also have values between 0 and 255. How can then the mean be zero?
The image pixel values will be between 0 and 255 for 8 bit values.
There is nothing stopping the additive noise from increasing or decreasing the pixel values. Obviously you can't increase the pixel values above 255 or reduce them below 0, but it still allows the noise to be zero mean.
To get a nice visualisation lets consider a colour image with zero mean noise & standard deviation 20! Which means the values of each RGB component can randomly vary from +20 to -20. So pixels will be added with this noise.
Here is the code for generating noise to an Image using opencv c++
Mat mSource_Bgr,mNoise_Bgr; mSource_Bgr= imread(FileName_S,1); // We need to work with signed images (as noise can be // negative as well as positive). We use 16 bit signed // images as otherwise we would lose precision. Mat mGaussNoise_Bgr(mSource_Bgr.size(), CV_16SC3); double StdDev=10; randn(mGaussNoise_Bgr, Scalar::all(0), Scalar::all(StdDev)); Mat mTemp; mSource_Bgr.convertTo(mTemp,CV_16SC3); addWeighted(mTemp, 1.0, mGaussNoise_Bgr, 1.0, 0.0, mTemp); mTemp.convertTo(mNoise_Bgr,mSource_Bgr.type()); mGaussNoise_Bgr.convertTo(mGaussNoise_Bgr,CV_8UC3); imshow("Noise Image",mGaussNoise_Bgr); imshow("Original Image",mSource_Bgr); imshow("Original Image + Noise",mNoise_Bgr);
I think it would be helpful to NOT think of images generally as having pixels with integer values between 0 and 255.
Think of images (and signals) as having floating point values of unlimited range.
A particular representation of an image -- in memory, on disk, or dictated by a particular file format -- might be to store values as one byte per channel, interpreted as an unsigned integer (between 0 and 255). But by doing so, you are severely limiting the set of possible images that you can represent.
As an example, if you were storing images as OpenEXR files (16 or 32 bit floating point values), or TIFF with float pixels, or FITS with float pixels, or any number of other higher-fidelity formats, it would be obvious that you could have negative values and a 0-mean signal. It is only because of the limitation of ancient 8 bit integer image file formats that it appears to be a problem.