module #include "diplib/generation.h"
Drawing Drawing in images
Classes
-
class dip::
FreeTypeTool - Class used to draw text using a specified font file (TTF, OTF, etc).
Functions
-
void dip::
SetBorder(dip::Image& out, dip::Image::Pixel const& value = {0}, dip::UnsignedArray const& sizes = {1}) - Sets the pixels at the border of
out
tovalue
. -
void dip::
ApplyWindow(dip::Image const& in, dip::Image& out, dip::String const& type = "Hamming", dip::dfloat parameter = 0.5) - Multiplies the image with a windowing function.
-
void dip::
DrawLine(dip::Image& out, dip::UnsignedArray const& start, dip::UnsignedArray const& end, dip::Image::Pixel const& value = {1}, dip::String const& blend = S::ASSIGN) - Draws a Bresenham line in an image.
-
void dip::
DrawLines(dip::Image& out, dip::CoordinateArray const& points, dip::Image::Pixel const& value = {1}, dip::String const& blend = S::ASSIGN) - Draws a series of Bresenham lines in an image.
-
void dip::
DrawPolygon2D(dip::Image& out, dip::Polygon const& polygon, dip::Image::Pixel const& value = {1}, dip::String const& mode = S::FILLED) - Draws a polygon in a 2D image.
-
void dip::
DrawEllipsoid(dip::Image& out, dip::FloatArray const& sizes, dip::FloatArray const& origin, dip::Image::Pixel const& value = {1}) - Draws a solid ellipsoid in an image.
-
void dip::
DrawDiamond(dip::Image& out, dip::FloatArray const& sizes, dip::FloatArray const& origin, dip::Image::Pixel const& value = {1}) - Draws a solid diamond in an image.
-
void dip::
DrawBox(dip::Image& out, dip::FloatArray const& sizes, dip::FloatArray const& origin, dip::Image::Pixel const& value = {1}) - Draws a solid box (rectangle) in an image.
-
void dip::
DrawBandlimitedPoint(dip::Image& out, dip::FloatArray origin, dip::Image::Pixel const& value = {1}, dip::FloatArray sigmas = {1.0}, dip::dfloat truncation = 3.0) - Draws an approximately bandlimited point in the image, in the form of a Gaussian blob.
-
void dip::
DrawBandlimitedLine(dip::Image& out, dip::FloatArray start, dip::FloatArray end, dip::Image::Pixel const& value = {1}, dip::dfloat sigma = 1.0, dip::dfloat truncation = 3.0) - Draws an approximately bandlimited line between two points in the image, using Gaussian profiles.
-
void dip::
DrawBandlimitedBall(dip::Image& out, dip::dfloat diameter, dip::FloatArray origin, dip::Image::Pixel const& value = {1}, dip::String const& mode = S::FILLED, dip::dfloat sigma = 1.0, dip::dfloat truncation = 3.0) - Draws an approximately bandlimited ball (disk) or an n-sphere (circle) in an image, using Gaussian profiles.
-
void dip::
DrawBandlimitedBox(dip::Image& out, dip::FloatArray sizes, dip::FloatArray origin, dip::Image::Pixel const& value = {1}, dip::String const& mode = S::FILLED, dip::dfloat sigma = 1.0, dip::dfloat truncation = 3.0) - Draws an approximately bandlimited box (rectangle) in an image, using Gaussian profiles.
-
void dip::
BlendBandlimitedMask(dip::Image& out, dip::Image const& mask, dip::Image const& value = dip::Image({255}), dip::IntegerArray pos = {}) - Blends
value
intoout
at positionpos
, according tomask
. -
void dip::
DrawText(dip::Image& out, dip::String const& text, dip::FloatArray origin, dip::Image::Pixel const& value = {1}, dip::dfloat orientation = 0, dip::String const& align = S::LEFT) - Draws text with the built-in, fixed-sized glyphs.
-
auto dip::
DrawText(dip::String const& text, dip::dfloat orientation = 0) -> dip::Image - Alternate version of the function above that returns a new image tightly cropped around the rendered text.
Function documentation
void
dip:: SetBorder(dip::Image& out,
dip::Image::Pixel const& value = {0},
dip::UnsignedArray const& sizes = {1})
Sets the pixels at the border of out
to value
.
sizes
must contain either a single value or one value per image dimension, and indicates how many pixels
in from the border are set.
out
must not be 0D.
void
dip:: ApplyWindow(dip::Image const& in,
dip::Image& out,
dip::String const& type = "Hamming",
dip::dfloat parameter = 0.5)
Multiplies the image with a windowing function.
type
can be one of the following windowing functions:
- “Hamming”: A cosine window. Set
parameter
to 0.5 to get a Hann window, and to 25.0/46.0 to get a Hamming window. With 0.53836, a small refinement to the Hamming optimum, yields the minimum peak side-lobe level. - “Gaussian”: A Gaussian window, this is the only one that is isotropic.
parameter
is the sigma, as a function of the image half-width. Choose a value smaller or equal to 0.5. At 0.5, 4 sigmas fit in the image width. - “Tukey”: A rectangular window convolved with a Hann window.
parameter
is the fraction of image width occupied by the cosine lobe. Ifparameter
is 1.0, it is a Hann window, if it is 0.0 it is a rectangular window. - “GaussianTukey”: A rectangular window convolved with a Gaussian window.
parameter
is the sigma in pixels, a value of the order of 10 is a good choice. The rectangular window is of the size of the image minus 3 sigma on each edge. This is the only window where the tapering is independent of the image width, and thus equal along each image dimension even if the image is not square. If the image size along one dimension is too small to accommodate the window shape, a Gaussian window is created instead.
In all these cases, the window is applied to each dimension independently, meaning that the multi-dimensional window is the outer product of the 1D windows.
void
dip:: DrawLine(dip::Image& out,
dip::UnsignedArray const& start,
dip::UnsignedArray const& end,
dip::Image::Pixel const& value = {1},
dip::String const& blend = S::ASSIGN)
Draws a Bresenham line in an image.
The line goes from start
to end
, both points included. These points must be within the image.
Pixels in out
on the line are set to value
, other pixels are not touched.
blend
can be one of the following strings:
"assign"
: The pixels are set tovalue
."add"
:value
is added to the pixels using saturated arithmetic.
void
dip:: DrawLines(dip::Image& out,
dip::CoordinateArray const& points,
dip::Image::Pixel const& value = {1},
dip::String const& blend = S::ASSIGN)
Draws a series of Bresenham lines in an image.
Lines are drawn from points[0]
to points[1]
, from points[1]
to points[2]
, etc, forming a continuous
curve composed of straight (Bresenham) line segments that hits each of the points in sequence.
To create a closed curve, repeat the first point at the end.
points
must have at least two points, and all points must be within the image.
Pixels in out
on the lines are set to value
, other pixels are not touched.
blend
can be one of the following strings:
"assign"
: The pixels are set tovalue
."add"
:value
is added to the pixels using saturated arithmetic.
out
must have at least two dimensions.
void
dip:: DrawPolygon2D(dip::Image& out,
dip::Polygon const& polygon,
dip::Image::Pixel const& value = {1},
dip::String const& mode = S::FILLED)
Draws a polygon in a 2D image.
Draws a polygon going through each of the points in polygon
. mode
can be one of the following strings:
"open"
: the start and end points are not connected."closed"
: the start and end points are connected."filled"
: the polygon is filled, that is, all pixels within the polygon are painted (default).
In the "filled"
mode, the polygon must be simple (which is guaranteed if it was obtained from a dip::ChainCode
).
In the "open"
or "closed"
mode, the polygon can self-intersect. In all cases, polygon vertices can be outside
the image. The two different algorithms (filled and not filled) do not necessarily produce the exact same polygon
outline, rounding errors can be different.
Pixels in out
on the polygon (and within the polygon for filled polygons) are set to value
, other pixels
are not touched.
The dip::Polygon
struct is defined in diplib/chain_code.h, which you’ll need to include to use this function.
out
must have two dimensions.
void
dip:: DrawEllipsoid(dip::Image& out,
dip::FloatArray const& sizes,
dip::FloatArray const& origin,
dip::Image::Pixel const& value = {1})
Draws a solid ellipsoid in an image.
The ellipsoid is centered around the coordinates given by origin
, and has a diameter sizes[ii]
along
dimension ii
. That is, the ellipsoid is composed of all pixels within a Euclidean distance of sizes/2
from the origin
.
The origin does not need to be within the image.
Pixels in out
within the ellipsoid are set to value
, other pixels are not touched.
out
must have at least one dimension.
void
dip:: DrawDiamond(dip::Image& out,
dip::FloatArray const& sizes,
dip::FloatArray const& origin,
dip::Image::Pixel const& value = {1})
Draws a solid diamond in an image.
The diamond is centered around the coordinates given by origin
, and has a width sizes[ii]
along
dimension ii
. That is, the diamond is composed of all pixels within a L-1 distance of sizes/2
from the origin
.
The origin does not need to be within the image.
Pixels in out
within the diamond are set to value
, other pixels are not touched.
out
must have at least one dimension.
void
dip:: DrawBox(dip::Image& out,
dip::FloatArray const& sizes,
dip::FloatArray const& origin,
dip::Image::Pixel const& value = {1})
Draws a solid box (rectangle) in an image.
The box is centered around the coordinates given by origin
, and has a width sizes[ii]
along
dimension ii
. That is, the box is composed of all pixels within a L-infinity distance of sizes/2
from the origin
.
The origin does not need to be within the image.
Pixels in out
within the box are set to value
, other pixels are not touched.
out
must have at least one dimension.
void
dip:: DrawBandlimitedPoint(dip::Image& out,
dip::FloatArray origin,
dip::Image::Pixel const& value = {1},
dip::FloatArray sigmas = {1.0},
dip::dfloat truncation = 3.0)
Draws an approximately bandlimited point in the image, in the form of a Gaussian blob.
The blob is centered around the coordinates given by origin
, and sigmas[ii]
is the parameter for the
Gaussian along dimension ii
. The Gaussian is scaled such that its integral is value
. The integral might
be off if sigmas
contains a small value.
The origin does not need to be within the image. sigmas * truncation
is the size of the box around origin
that is affected by the blob. Pixels in out
within that box have the values of the Gaussian added to them,
other pixels are not touched.
out
must not be binary, and have at least one dimension.
void
dip:: DrawBandlimitedLine(dip::Image& out,
dip::FloatArray start,
dip::FloatArray end,
dip::Image::Pixel const& value = {1},
dip::dfloat sigma = 1.0,
dip::dfloat truncation = 3.0)
Draws an approximately bandlimited line between two points in the image, using Gaussian profiles.
The two points do not need to be within the image domain.
sigma
determines the smoothness of the line. Values are calculated up to a distance of sigma * truncation
from the line, further away values are rounded to 0. value
is the linear integral perpendicular to the line.
That is, it is the weight of the Gaussian used to draw the line. The values are added to existing values in
the image out
.
out
must not be binary and have at least two dimensions.
If start
and end
are identical, calls dip::DrawBandlimitedPoint
.
void
dip:: DrawBandlimitedBall(dip::Image& out,
dip::dfloat diameter,
dip::FloatArray origin,
dip::Image::Pixel const& value = {1},
dip::String const& mode = S::FILLED,
dip::dfloat sigma = 1.0,
dip::dfloat truncation = 3.0)
Draws an approximately bandlimited ball (disk) or an n-sphere (circle) in an image, using Gaussian profiles.
The ball is centered around the coordinates given by origin
, and has a diameter diameter
along
all dimensions. The origin does not need to be within the image.
If mode
is "empty"
, a circle/sphere/n-sphere is drawn as a thin shell with a Gaussian profile.
If mode
is "filled"
, a disk/ball/hyperball is drawn as a solid shape with an error function transition
to background values. The former is the gradient magnitude of the latter.
In both cases, sigma
determines the smoothness of the shape, and truncation
determines how far out from the edge the smooth values are computed: at a distance of sigma * truncation
the values are rounded to 1 or 0. value
indicates the weight of the ball: it is the value of the
solid shape, and the value of the integral perpendicular to the edge for the empty shape.
The ball is added to the image out
. Pixels within sigma * truncation
of the ball’s edge have
their value increased, other pixels are not touched.
out
must not be binary, and have at least one dimension.
Note: diameter
is a scalar, unlike for similar functions, because a bandlimited ellipsoid would be very
expensive (and complicated) to compute in the spatial domain.
void
dip:: DrawBandlimitedBox(dip::Image& out,
dip::FloatArray sizes,
dip::FloatArray origin,
dip::Image::Pixel const& value = {1},
dip::String const& mode = S::FILLED,
dip::dfloat sigma = 1.0,
dip::dfloat truncation = 3.0)
Draws an approximately bandlimited box (rectangle) in an image, using Gaussian profiles.
The box is centered around the coordinates given by origin
, and has a width of sizes[ii]
along
dimension ii
. The origin does not need to be within the image.
If mode
is "empty"
, the edge of the rectangle or the surface of the box is drawn as a thin shell
with a Gaussian profile. If mode
is "filled"
, the rectangle/box is drawn as a solid shape with an
error function transition to background values. The former is the gradient magnitude of the latter.
In both cases, sigma
determines the smoothness of the shape, and truncation
determines how far out from the edge the smooth values are computed: at a distance of sigma * truncation
the values are rounded to 1 or 0. value
indicates the weight of the ball: it is the value of the
solid shape, and the value of the integral perpendicular to the edge for the empty shape.
The box is added to the image out
. Pixels within sigma * truncation
of the box’s edge have
their value increased, other pixels are not touched.
out
must not be binary, and have at least one dimension.
void
dip:: BlendBandlimitedMask(dip::Image& out,
dip::Image const& mask,
dip::Image const& value = dip::Image({255}),
dip::IntegerArray pos = {})
Blends value
into out
at position pos
, according to mask
.
Computes out = value * mask + out * (1 - mask)
, after shifting value
and mask
by pos
. If
mask is an integer type, it will be scaled to the 0-1 range first. That is, where mask
is maximal,
out
will be assigned value
. Where mask
is zero, out
will not be changed. Intermediate values
indicate how much of value
to mix into the existing color.
value
is cast to the data type of out
after blending.
out
is a forged image of any data type, dimensionality and number of tensor elements. mask
is a
scalar image of the same dimensionality. If it is a floating-point image, the values should be in
the range 0-1; if it is an integer image, the values should be between 0 and the maximum for the data type.
mask
can also be binary, but it cannot be a complex type.
value
is an image of the same sizes as mask
, or can be singleton-expanded to the same sizes. It has
either one tensor element or as many as out
(i.e. the tensor dimension can be singleton-expanded to
the tensor size of out
).
Note that value
can be a single pixel to paint mask
in a single color. Likewise, mask
can be a single
pixel to mix in value
at a constant level. mask
and value
will be singleton-expanded to the match
their sizes. This means that, if both are a single pixel, only a single pixel in out
will be modified.
pos
has one value for each dimension in out
, and indicates the position of the top-left corner of
mask
and value
in out
. That is, mask
and value
will be translated by this vector.
Note that mask
can fall partially outside of out
, it is perfectly fine to specify negative coordinates.
If pos
is an empty array, no translation is applied, mask
will coincide with the top-left corner
of out
.
If out
is binary, mask
will be thresholded at 50%.
void
dip:: DrawText(dip::Image& out,
dip::String const& text,
dip::FloatArray origin,
dip::Image::Pixel const& value = {1},
dip::dfloat orientation = 0,
dip::String const& align = S::LEFT)
Draws text with the built-in, fixed-sized glyphs.
Draws text in the image out
, at location origin
, with a color given by value
, and rotated according to
orientation
.
The font used is composed of glyph images rendered from the Open Sans font, at 14 px.
The lowercase letter ‘x’ is 8x8 pixels and uppercase letter ‘X’ is 9x10 pixels. The font uses anti-aliasing,
blending from the color value
to the existing image colors.
text
is any ASCII string; even if Unicode support was enabled when building DIPlib, the built-in font only
has glyphs for the ASCII characters 32-126. Other characters will be ignored. In particular, control characters
such as the newline and the backspace are ignored, to draw multiple lines of text, call this function for each
line in turn.
origin
is the pixel coordinates of a point on the base line. If align
is "left"
, origin
is a point
on the left edge of the rendered text; if align
is "right"
, it is a point on the right edge; and if it
is "center"
, it is the point halfway between the left and right edges.
orientation
is in radian, with 0 for horizontal text, and increasing clockwise.
out
must be a forged 2D image. If out
is binary, the anti-aliased glyphs will be thresholded.
value
must have the same number of tensor elements as out
. If value
is scalar, this value will be used
for all tensor elements.
dip::Image
dip:: DrawText(dip::String const& text,
dip::dfloat orientation = 0)
Alternate version of the function above that returns a new image tightly cropped around the rendered text.
The output image is a 2D scalar image of type dip::DT_UINT8
, with white text on a black background.
See dip::DrawText
for a description of the functionality and arguments.