module #include "diplib/generation.h"
Noise generation Adding noise to an image
Contents
- Reference
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
.