Generation » Noise generation module

Adding noise to an image

Contents

Functions

void dip::UniformNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat lowerBound = 0.0, dip::dfloat upperBound = 1.0)
Adds uniformly distributed white noise to the input image.
void dip::GaussianNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat variance = 1.0)
Adds normally distributed white noise to the input image.
void dip::PoissonNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat conversion = 1.0)
Adds Poisson-distributed white noise to the input image.
void dip::BinaryNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat p10 = 0.05, dip::dfloat p01 = 0.05)
Adds noise to the binary input image.
void dip::SaltPepperNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat p0 = 0.05, dip::dfloat p1 = 0.05, dip::dfloat white = 1.0)
Adds salt-and-pepper noise to the input image.
void dip::FillColoredNoise(dip::Image& out, dip::Random& random, dip::dfloat variance = 1.0, dip::dfloat color = -2.0)
Fills out with colored (Brownian, pink, blue, violet) noise.
void dip::ColoredNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat variance = 1.0, dip::dfloat color = -2.0)
Adds colored (Brownian, pink, blue, violet) noise to in.

Function documentation

void dip::UniformNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat lowerBound = 0.0, dip::dfloat upperBound = 1.0)

Adds uniformly distributed white noise to the input image.

The uniformly distributed noise added to the image is taken from the half-open interval [lowerBound, upperBound). That is, for each pixel it does in += uniformRandomGenerator( lowerBound, upperBound ). The output image is of the same type as the input image.

random is used to generate the random values needed by the first thread. If the algorithm runs in multiple threads, portions of the image processed by additional threads take their random values from random.Split(), which is essentially a copy of random set to a different random stream. Given a dip::Random object in an identical state before calling this function, the output image will be different depending on the number of threads used.

void dip::GaussianNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat variance = 1.0)

Adds normally distributed white noise to the input image.

The normally distributed noise added to the image is defined by variance, and has a zero mean. That is, for each pixel it does in += gaussianRandomGenerator( 0, std::sqrt( variance )). The output image is of the same type as the input image.

random is used to generate the random values needed by the first thread. If the algorithm runs in multiple threads, portions of the image processed by additional threads take their random values from random.Split(), which is essentially a copy of random set to a different random stream. Given a dip::Random object in an identical state before calling this function, the output image will be different depending on the number of threads used.

void dip::PoissonNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat conversion = 1.0)

Adds Poisson-distributed white noise to the input image.

The Poisson-distributed noise is added to the image scaled by conversion. That is, for each pixel it does in = poissonRandomGenerator( in * conversion ) / conversion. conversion can be used to relate the pixel values with the number of counts. For example, the simulate a photon-limited image acquired by a CCD camera, the conversion factor specifies the relation between the number of photons recorded and the pixel value. Note that the input pixel values must be positive for the noise to be generated. Pixels with a value of 0 or less will always result in an output value of 0.

The output image is of the same type as the input image.

random is used to generate the random values needed by the first thread. If the algorithm runs in multiple threads, portions of the image processed by additional threads take their random values from random.Split(), which is essentially a copy of random set to a different random stream. Given a dip::Random object in an identical state before calling this function, the output image will be different depending on the number of threads used.

void dip::BinaryNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat p10 = 0.05, dip::dfloat p01 = 0.05)

Adds noise to the binary input image.

The noise added to the binary image is described by the two probabilities p10 and p01. p10 is the probability that a foreground pixel transitions to background (probability of 1 → 0 transition), and p01 is the probability that a background pixel transitions to foreground (probability to 0 → 1 transition). Thus, p10 indicates the probability for each foreground pixel in the input image to be set to background, and p01 indicates the probability that a background pixel in the input image is set to foreground. It is possible to set either of these to 0, to limit the noise to only one of the phases: for example, BinaryNoise( in, random, 0.05, 0.0 ) limits the noise to the foreground components, and does not add noise to the background.

Note that the noise generated corresponds to a Poisson point process. The distances between changed pixels have a Poisson distribution. For example, the following bit of code yields a Poisson process with a density governed by D.

dip::Random random;
dip::dfloat D = 0.001;
dip::Image poissonPoint( { 256, 256 }, 1, dip::DT_BIN );
poissonPoint.Fill( 0 );
BinaryNoise( poissonPoint, poissonPoint, random, 0, D );

The binary noise added to an all-zero image as in the code snippet above is equivalent to thresholding uniformly-distributed noise at a fraction D of the noise range, from the max value:

dip::Image poissonPoint2( { 256, 256 }, 1, dip::DT_SFLOAT );
poissonPoint2.Fill( 0 );
UniformNoise( poissonPoint2, poissonPoint2, random, 0, 1 );
poissonPoint2 = poissonPoint2 >= ( 1 - D );

Using blue noise it is possible to create a point process with similar density, but more equally-distributed points:

dip::Image poissonPoint3( { 256, 256 }, 1, dip::DT_SFLOAT );
FillColoredNoise( poissonPoint3, random, 1, 1 );
dip::dfloat threshold = Percentile( poissonPoint3, {}, 100 * ( 1 - D )).As< dip::dfloat >();
poissonPoint3 = poissonPoint3 >= threshold;

random is used to generate the random values needed by the first thread. If the algorithm runs in multiple threads, portions of the image processed by additional threads take their random values from random.Split(), which is essentially a copy of random set to a different random stream. Given a dip::Random object in an identical state before calling this function, the output image will be different depending on the number of threads used.

void dip::SaltPepperNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat p0 = 0.05, dip::dfloat p1 = 0.05, dip::dfloat white = 1.0)

Adds salt-and-pepper noise to the input image.

The noise added to the image is described by the two probabilities p0 and p1. p0 is the probability that a pixel is set to 0 (black), and p01 is the probability that a pixel is set to white. It is possible to set either of these to 0, to limit the noise to only one of the phases: for example, SaltPepperNoise( in, random, 0.05, 0.0 ) adds only black pixels to the image, not white ones. p0+p1 must not be larger than 1.

Note that the noise generated corresponds to a Poisson point process. The distances between changed pixels have a Poisson distribution.

random is used to generate the random values needed by the first thread. If the algorithm runs in multiple threads, portions of the image processed by additional threads take their random values from random.Split(), which is essentially a copy of random set to a different random stream. Given a dip::Random object in an identical state before calling this function, the output image will be different depending on the number of threads used.

void dip::FillColoredNoise(dip::Image& out, dip::Random& random, dip::dfloat variance = 1.0, dip::dfloat color = -2.0)

Fills out with colored (Brownian, pink, blue, violet) noise.

Colored noise is correlated, as opposed to white nose, which is uncorrelated.

The output image will have a variance of variance. color indicates the color of the noise (and is equal to the power of the function used to modulate the frequency spectrum):

  • -2.0: Brownian noise (a.k.a. brown or red noise), with a frequency spectrum proportional to $1/f^2$.
  • -1.0: pink noise, with a frequency spectrum proportional to $1/f$.
  • 0.0: white noise, equal to dip::GaussianNoise (but much more expensive).
  • 1.0: blue noise, with a frequency spectrum proportional to $f$.
  • 2.0: violet noise, with a frequency spectrum proportional to $f^2$.

It is possible to specify any values in between these, to tune the color more precisely. Values larger than 2.0 and smaller than -2.0 are possible also, but the results become less interesting quickly as the magnitude increases.

With pink and Brownian noise, nearby pixels will be positively correlated. That is, the noise changes slowly across the image. This is because it has more power in the lower frequencies, which represent slow changes. These forms of noise can add texture to an image. The variance of the output image is given by variance, but the computed population variance will differ from it more strongly than with white noise. The differences are stronger for smaller images.

With blue and violet noise, nearby pixels will be negatively correlated. That is, large-scale changes across the image are weaker. The resulting noise looks more uniform than white noise. Because of this, the computed population variance in the output will be much closer to variance than with white noise.

void dip::ColoredNoise(dip::Image const& in, dip::Image& out, dip::Random& random, dip::dfloat variance = 1.0, dip::dfloat color = -2.0)

Adds colored (Brownian, pink, blue, violet) noise to in.

Equivalent to adding the output of dip::FillColoredNoise to in. See the reference for that function for information on the input parameters. out will have the data type of in.