# Generation » Test image generation module#include "diplib/generation.h"

Generating images with test objects or functions

• Reference

## Classes

struct dip::TestObjectParams
Describes the parameters for a test object, used by dip::TestObject.

## Functions

dip::Image const& in, dip::Image& out, Image::Pixel const& value = {1}, dip::dfloat sigma = 1.0, dip::dfloat truncation = 3.0)
Maps input values through an error function, can be used to generate arbitrary band-limited objects.
dip::Image const& in, dip::Image& out, Image::Pixel const& value = {1}, dip::dfloat sigma = 1.0, dip::dfloat truncation = 3.0)
Maps input values through a Gaussian function, can be used to generate arbitrary band-limited lines.
void dip::FillDelta(dip::Image& out, dip::String const& origin = "")
Fills an image with a delta function.
void dip::CreateDelta(dip::Image& out, dip::UnsignedArray const& sizes, dip::String const& origin = "")
Creates a delta function image.
auto dip::CreateDelta(dip::UnsignedArray const& sizes, dip::String const& origin = "") -> dip::Image
Overload for the function above, which takes image sizes instead of an image.
void dip::CreateGauss(dip::Image& out, dip::FloatArray const& sigmas, dip::UnsignedArray derivativeOrder = {0}, dip::dfloat truncation = 3.0, dip::UnsignedArray exponents = {0})
Creates a Gaussian kernel.
auto dip::CreateGauss(dip::FloatArray const& sigmas, dip::UnsignedArray const& order = {0}, dip::dfloat truncation = 3.0, dip::UnsignedArray const& exponents = {0}) -> dip::Image
Overload for the function above, which takes image sizes instead of an image.
void dip::CreateGabor(dip::Image& out, dip::FloatArray const& sigmas, dip::FloatArray const& frequencies, dip::dfloat truncation = 3.0)
Creates a Gabor kernel.
void dip::FTEllipsoid(dip::Image& out, dip::FloatArray radius = {1}, dip::dfloat amplitude = 1)
Generates the Fourier transform of an ellipsoid.
auto dip::FTEllipsoid(dip::UnsignedArray const& sizes, dip::FloatArray const& radius = {1}, dip::dfloat amplitude = 1) -> dip::Image
Overload for the function above, which takes image sizes instead of an image.
void dip::FTBox(dip::Image& out, dip::FloatArray length = {1}, dip::dfloat amplitude = 1)
Generates the Fourier transform of a box.
auto dip::FTBox(dip::UnsignedArray const& sizes, dip::FloatArray const& length = {1}, dip::dfloat amplitude = 1) -> dip::Image
Overload for the function above, which takes image sizes instead of an image.
void dip::FTCross(dip::Image& out, dip::FloatArray length = {1}, dip::dfloat amplitude = 1)
Generates the Fourier transform of a cross.
auto dip::FTCross(dip::UnsignedArray const& sizes, dip::FloatArray const& length = {1}, dip::dfloat amplitude = 1) -> dip::Image
Overload for the function above, which takes image sizes instead of an image.
void dip::FTGaussian(dip::Image& out, dip::FloatArray sigma, dip::dfloat amplitude = 1, dip::dfloat truncation = 3)
Generates the Fourier transform of a Gaussian.
auto dip::FTGaussian(dip::UnsignedArray const& sizes, dip::FloatArray const& sigma, dip::dfloat amplitude = 1, dip::dfloat truncation = 3) -> dip::Image
Overload for the function above, which takes image sizes instead of an image.
void dip::TestObject(dip::Image& out, dip::TestObjectParams const& params, dip::Random& random)
Generates a test object according to params.
auto dip::TestObject(dip::UnsignedArray const& sizes, dip::TestObjectParams const& params, dip::Random& random) -> dip::Image
Overload for the function above, which takes image sizes instead of an image.
void dip::TestObject(dip::Image& out, dip::TestObjectParams const& params = {})
Calls the main dip::TestObject function with a default-initialized dip::Random object.
auto dip::TestObject(dip::UnsignedArray const& sizes = {256,256}, dip::TestObjectParams const& params = {}) -> dip::Image
Overload for the function above, which takes image sizes instead of an image.
dip::Image& out, dip::Random& random, dip::dfloat density = 0.01)
Fills the binary image out with a Poisson point process of density.
dip::Image& out, dip::UnsignedArray const& sizes, dip::Random& random, dip::dfloat density = 0.01)
Creates a binary image with a Poisson point process of density.
void dip::FillRandomGrid(dip::Image& out, dip::Random& random, dip::dfloat density = 0.01, dip::String const& type = S::RECTANGULAR, dip::String const& mode = S::TRANSLATION)
Fills the binary image out with a grid that is randomly placed over the image.
dip::Image& out, dip::UnsignedArray const& sizes, dip::Random& random, dip::dfloat density = 0.01, dip::String const& type = S::RECTANGULAR, dip::String const& mode = S::TRANSLATION)
Creates a binary image with a random grid.

## Class documentation

### struct dip::TestObjectParams

Describes the parameters for a test object, used by dip::TestObject.

Variables
dip::String objectShape Can be "ellipsoid", "ellipsoid shell", "box", "box shell", or "custom".
dip::FloatArray objectSizes Sizes of the object along each dimension.
dip::dfloat objectAmplitude Brightness of object pixels.
bool randomShift If true, add a random sub-pixel shift in the range [-0.5,0.5].
dip::String generationMethod Can be "gaussian" (spatial domain method) or "fourier" (frequency domain method).
dip::dfloat modulationDepth Strength of modulation, if 0 no modulation is applied.
dip::FloatArray modulationFrequency Frequency of a sine modulation added to the object, units are periods/pixel.
dip::String pointSpreadFunction PSF, can be "gaussian", "incoherent", or "none".
dip::dfloat oversampling Determines size of PSF (Gaussian PSF has sigma = 0.9*oversampling).
dip::dfloat backgroundValue Background intensity, must be non-negative.
dip::dfloat signalNoiseRatio SNR = average object energy divided by average noise power. If SNR > 0, adds a mixture of Gaussian and Poisson noise.
dip::dfloat gaussianNoise Relative amount of Gaussian noise.
dip::dfloat poissonNoise Relative amount of Poisson noise.

## Function documentation

### void dip::GaussianEdgeClip(dip::Image const& in, dip::Image& out, Image::Pixel const& value = {1}, dip::dfloat sigma = 1.0, dip::dfloat truncation = 3.0)

Maps input values through an error function, can be used to generate arbitrary band-limited objects.

in is a scalar, real-valued function whose zero level set represents the edges of an object. The function indicates the Euclidean distance to these edges, with positive values inside the object. out will have a value of value inside the object, zero outside the object, and a Gaussian profile in the transition. If sigma is larger or equal to about 0.8, and the input image is well formed, the output will be approximately bandlimited.

The error function mapping is computed in band around the zero crossings where the input image has values smaller than sigma * truncation.

If value has more than one element, the output will be a tensor image with the same number of elements.

The following example draws a band-limited cross, where the horizontal and vertical bars both have 20.5 pixels width, and different sub-pixel shifts. The foreground has a value of 255, and the background of 0.

dip::UnsignedArray outSize{ 256, 256 };
dip::Image xx = 20.5 - dip::Abs( dip::CreateXCoordinate( outSize ) + 21.3 );
dip::Image yy = 20.5 - dip::Abs( dip::CreateYCoordinate( outSize ) - 7.8 );
dip::Image cross = dip::GaussianEdgeClip( dip::Supremum( xx, yy ), { 255 } );


### void dip::GaussianLineClip(dip::Image const& in, dip::Image& out, Image::Pixel const& value = {1}, dip::dfloat sigma = 1.0, dip::dfloat truncation = 3.0)

Maps input values through a Gaussian function, can be used to generate arbitrary band-limited lines.

in is a scalar, real-valued function whose zero level set represents the lines to be drawn. The function indicates the Euclidean distance to these edges. out will have lines with a Gaussian profile and a weight of value (the integral perpendicular to the line is value), and a value of zero away from the lines. If sigma is larger or equal to about 0.8, and the input image is well formed, the output will be approximately bandlimited.

The Gaussian function mapping is computed in band around the zero crossings where the input image has values smaller than sigma * truncation.

If value has more than one element, the output will be a tensor image with the same number of elements.

The following example draws a band-limited cross outline, where the horizontal and vertical bars both have 20.5 pixels width, and different sub-pixel shifts. The lines have a weight of 1500, and the background has a value of 0.

dip::UnsignedArray outSize{ 256, 256 };
dip::Image xx = 20.5 - dip::Abs( dip::CreateXCoordinate( outSize ) + 21.3 );
dip::Image yy = 20.5 - dip::Abs( dip::CreateYCoordinate( outSize ) - 7.8 );
dip::Image cross = dip::GaussianLineClip( dip::Supremum( xx, yy ), { 1500 } );


### void dip::FillDelta(dip::Image& out, dip::String const& origin = "")

Fills an image with a delta function.

All pixels will be zero except at the origin, where it will be 1. out must be forged, and scalar.

origin specifies where the origin lies:

• "right": The origin is on the pixel right of the center (at integer division result of size/2). This is the default.
• "left": The origin is on the pixel left of the center (at integer division result of (size-1)/2).
• "corner": The origin is on the first pixel. This is the default if no other option is given.

### void dip::CreateDelta(dip::Image& out, dip::UnsignedArray const& sizes, dip::String const& origin = "")

Creates a delta function image.

All pixels will be zero except at the origin, where it will be 1. out will be of size sizes, scalar, and of type dip::DT_SFLOAT. See dip::FillDelta for the meaning of origin.

### void dip::CreateGauss(dip::Image& out, dip::FloatArray const& sigmas, dip::UnsignedArray derivativeOrder = {0}, dip::dfloat truncation = 3.0, dip::UnsignedArray exponents = {0})

Creates a Gaussian kernel.

out is reforged to the required size to hold the kernel. These sizes are always odd. sigmas determines the number of dimensions. order and exponents will be adjusted if necessary to match.

derivativeOrder is the derivative order, and can be a value between 0 and 3 for each dimension.

If derivativeOrder is 0, the size of the kernel is given by 2 * std::ceil( truncation * sigma ) + 1. The default value for truncation is 3, which assures a good approximation of the Gaussian kernel without unnecessary expense. For derivatives, the value of truncation is increased by 0.5 * derivativeOrder.

By setting exponents to a positive value for each dimension, the created kernel will be multiplied by the coordinates to the power of exponents.

### void dip::CreateGabor(dip::Image& out, dip::FloatArray const& sigmas, dip::FloatArray const& frequencies, dip::dfloat truncation = 3.0)

Creates a Gabor kernel.

out is reforged to the required size to hold the kernel. These sizes are always odd. sigmas determines the number of dimensions. frequencies must have the same number of elements as sigmas.

Frequencies are in the range [0, 0.5), with 0.5 being the frequency corresponding to a period of the size of the image.

The size of the kernel is given by 2 * std::ceil( truncation * sigma ) + 1. The default value for truncation is 3, which assures a good approximation of the kernel without unnecessary expense.

### void dip::FTEllipsoid(dip::Image& out, dip::FloatArray radius = {1}, dip::dfloat amplitude = 1)

Generates the Fourier transform of an ellipsoid.

The length of the axes of the ellipsoid are specified through radius, which indicates the half-length of the axes along each dimension. amplitude specifies the brightness of the ellipsoid.

The function is defined for images between 1 and 3 dimensions. out must be forged, scalar, and of a floating-point type.

### void dip::FTBox(dip::Image& out, dip::FloatArray length = {1}, dip::dfloat amplitude = 1)

Generates the Fourier transform of a box.

The length of the sides of the box are specified through length, which indicates the half-length of the sides along each dimension. amplitude specifies the brightness of the box.

out must be forged, scalar, and of a floating-point type.

### void dip::FTCross(dip::Image& out, dip::FloatArray length = {1}, dip::dfloat amplitude = 1)

Generates the Fourier transform of a cross.

The length of the sides of the cross are specified through length, which indicates the half-length of the sides along each dimension. amplitude specifies the brightness of the cross.

out must be forged, scalar, and of a floating-point type.

### void dip::FTGaussian(dip::Image& out, dip::FloatArray sigma, dip::dfloat amplitude = 1, dip::dfloat truncation = 3)

Generates the Fourier transform of a Gaussian.

The size of the Gaussian is specified with sigma (note that the Fourier transform of a Gaussian is also a Gaussian). volume is the integral of the Gaussian in the spatial domain.

out must be forged, scalar, and of a floating-point type.

### void dip::TestObject(dip::Image& out, dip::TestObjectParams const& params, dip::Random& random)

Generates a test object according to params.

Generates a test object in the center of out, which must be forged, scalar and of a floating-point type. The test object can optionally be modulated using a sine function, blurred, and have noise added.

params describes how the object is generated:

• params.generationMethod can be one of:
• "gaussian": creates the shape directly in the spatial domain, the shape will have Gaussian edges with a sigma of 0.9.
• "fourier": creates the shape in the frequency domain, the shape will be truly bandlimited.
• params.objectShape can be one of:
• "ellipsoid" or "ellipsoid shell": the shape is drawn with dip::DrawBandlimitedBall or dip::FTEllipsoid, depending on the generation method. In the case of "gaussian" (spatial-domain generation), the shape must be isotropic (have same sizes in all dimensions). In the case of "fourier", the image cannot have more than three dimensions.
• "box" or "box shell": the shape is drawn with dip::DrawBandlimitedBox or dip::FTBox, depending on the generation method.
• "custom": out already contains a shape, which is used as-is. In the case that params.generationMethod is "gaussian", out is taken to be in the spatial domain, and in the case of "fourier", in the frequency domain.
• params.objectSizes determines the extent of the object along each dimension. Must have either one element or as many elements as image dimensions in out.
• params.objectAmplitude determines the brightness of the object.
• params.randomShift, if true, shifts the object with a random sub-pixel shift in the range [-0.5,0.5]. This sub-pixel shift can be used to avoid bias due to digitization error over a sequence of generated objects.

params also describes what effects are applied to the image:

Modulation is an additive sine wave along each dimension, and is controlled by:

• params.modulationDepth controls the strength of the modulation. If this value is zero, no modulation is applied.
• params.modulationFrequency controls the frequency along each image axis. The units are number of periods per pixel, and hence values below 0.5 should be given to prevent aliasing.

Blurring is controlled by:

• params.pointSpreadFunction determines the point spread function (PSF) used. It can be "gaussian" for Gaussian blurring, "incoherent" for a 2D, in-focus, diffraction limited incoherent PSF (applied through Fourier domain filtering), or "none" for no blurring.
• params.oversampling determines the size of the PSF. In the case of "gaussian", the sigma used for blurring is 0.9 * params.oversampling. In the case of "incoherent", this is the oversampling parameter passed to dip::IncoherentOTF.

Noise is controlled by:

• params.backgroundValue determines the background intensity added to the image. This is relevant for the Poisson noise.
• params.signalNoiseRatio determines the signal to noise ratio (SNR), which we define as the average object energy divided by average noise power (i.e. not in dB). If the SNR is larger than 0, a mixture of Gaussian and Poisson noise is added to the whole image.
• params.gaussianNoise determines the relative amount of Gaussian noise used.
• params.poissonNoise determines the relative amount of Poisson noise used. The magnitude of these two quantities is not relevant, only their relative values are. If they are equal, the requested SNR is divided equally between the Gaussian and the Poisson noise.

random is the random number generator used for both the sub-pixel shift and the noise added to the image.

### void dip::FillPoissonPointProcess(dip::Image& out, dip::Random& random, dip::dfloat density = 0.01)

Fills the binary image out with a Poisson point process of density.

out must be forged, binary and scalar. On average, one of every 1/density pixels will be set.

### void dip::CreatePoissonPointProcess(dip::Image& out, dip::UnsignedArray const& sizes, dip::Random& random, dip::dfloat density = 0.01)

Creates a binary image with a Poisson point process of density.

out will be of size sizes, binary and scalar.

### void dip::FillRandomGrid(dip::Image& out, dip::Random& random, dip::dfloat density = 0.01, dip::String const& type = S::RECTANGULAR, dip::String const& mode = S::TRANSLATION)

Fills the binary image out with a grid that is randomly placed over the image.

This grid can be useful for random systematic sampling.

type determines the grid type. It can be "rectangular" in any number of dimensions, this is the default grid. For 2D images it can be "hexagonal". In 3D it can be "fcc" or "bcc" for face-centered cubic and body-centered cubic, respectively.

density determines the grid density. On average, one of every 1/density pixels will be set. The grid is sampled equally densely along all dimensions. If the density doesn’t lead to an integer grid spacing, the grid locations will be rounded, leading to an uneven spacing. density must be such that the grid spacing is at least 2. Therefore, density must be smaller than , with the image dimensionality, in the rectangular case. In the hexagonal case, this is .

mode determines how the random grid location is determined. It can be either "translation" or "rotation". In the first case, only a random translation is applied to the grid, it will be aligned with the image axes. In the second case, the grid will also be randomly rotated. This option is used only for 2D and 3D grids.

out must be forged, binary and scalar.

### void dip::CreateRandomGrid(dip::Image& out, dip::UnsignedArray const& sizes, dip::Random& random, dip::dfloat density = 0.01, dip::String const& type = S::RECTANGULAR, dip::String const& mode = S::TRANSLATION)

Creates a binary image with a random grid.

out will be of size sizes, binary and scalar.

See dip::FillRandomGrid for the meaning of the remainder of the parameters, which define the grid.