PixelTable class
Represents an arbitrarily-shaped neighborhood (filter support) in an arbitrary number of dimensions.
Contents
The PixelTable
is an array of pixel runs, where each run is encoded by start coordinates
and a length (number of pixels). The runs all go along the same dimension, given by
dip::PixelTable::ProcessingDimension
.
It is simple to create a pixel table for unit circles (spheres) in different norms, and for straight lines. And any other shape can be created through a binary image.
The processing dimension defines the dimension along which the pixel runs are taken. By default it is dimension 0, but it could be beneficial to set it to the dimension in which there would be fewer runs.
Two ways can be used to walk through the pixel table:
-
dip::PixelTable::Runs
returns astd::vector
with all the runs, which are encoded by the coordinates of the first pixel and a run length. Visiting each run is an efficient way to process the whole neighborhood. For example, the filterdip::Uniform
, which computes the average over all pixels within the neighborhood, only needs to subtract the pixels on the start of each run, shift the neighborhood by one pixel, then add the pixels on the end of each run. See the example in the section Applying an arbitrary neighborhood filter. -
dip::PixelTable::begin
returns an iterator to the first pixel in the table, incrementing the iterator successively visits each of the pixels in the run. Dereferencing this iterator yields the offset to a neighbor pixel. This makes for a simple way to visit every single pixel within the neighborhood.
The pixel table can optionally contain a weight for each pixel. These can be accessed
only by retrieving the array containing all weights. This array is meant to be used
by taking its begin
iterator, and using that iterator in conjunction with the pixel
table’s iterator. Taken together, they provide both the location and the weight of each
pixel in the neighborhood. For example, modified from from the function dip::GeneralConvolution
:
sfloat* in = ... // pointer to the current pixel in the input image sfloat* out = ... // pointer to the current pixel in the output image sfloat sum = 0; auto ito = pixelTable.begin(); // pixelTable is our neighborhood auto itw = pixelTable.Weights().begin(); while( !ito.IsAtEnd() ) { sum += in[ *ito ] * static_cast< sfloat >( *itw ); ++ito; ++itw; } *out = sum;
Constructors, destructors, assignment and conversion operators
- PixelTable() defaulted
- A default-constructed pixel table is kinda useless.
- PixelTable(dip::String const& shape, dip::FloatArray size, dip::uint procDim = 0)
- Construct a pixel table for default filter shapes.
- PixelTable(dip::Image const& mask, dip::IntegerArray const& origin = {}, dip::uint procDim = 0)
- Construct a pixel table for an arbitrary shape defined by a binary image.
Classes
Functions
- auto Runs() const -> std::vector<PixelRun> const&
- Returns the vector of runs.
- auto Dimensionality() const -> dip::uint
- Returns the dimensionality of the neighborhood.
- auto Sizes() const -> dip::UnsignedArray const&
- Returns the size of the bounding box of the neighborhood.
- auto Origin() const -> dip::IntegerArray const&
- Returns the coordinates of the top-left corner of the bounding box w.r.t. the origin.
- auto Boundary() const -> dip::UnsignedArray
- Returns the size of the boundary extension along each dimension that is necessary to accommodate the neighborhood on the edge pixels of the image.
- void ShiftOrigin(dip::IntegerArray const& shift)
- Shifts the origin of the neighborhood by the given amount.
- void MirrorOrigin()
- Shifts the origin of neighborhood by one pixel to the left for even-sized dimensions. This is useful for neighborhoods with their origin in the default location, that have been mirrored.
- void Mirror()
- Mirrors the neighborhood.
- auto NumberOfPixels() const -> dip::uint
- Returns the number of pixels in the neighborhood.
- auto ProcessingDimension() const -> dip::uint
- Returns the processing dimension, the dimension along which pixel runs are laid out.
- auto begin() const -> dip::PixelTable::iterator
- A const iterator to the first pixel in the neighborhood.
- auto end() const -> dip::PixelTable::iterator
- A const iterator to one past the last pixel in the neighborhood.
- auto AsImage() const -> dip::Image
- Creates a binary image representing the neighborhood, or a
dfloat
one if there are weights associated. - void AsImage(dip::Image& out) const
- Same as previous overload, but writing into the given image.
- auto Prepare(dip::Image const& image) const -> dip::PixelTableOffsets
- Prepare the pixel table to be applied to a specific image.
- void AddWeights(dip::Image const& image)
- Add weights to each pixel in the neighborhood, taken from an image. The image must be of the same
sizes as the
PixelTable
’s bounding box (i.e. the image used to construct the pixel table), scalar, and not binary (i.e. integer, float or complex). - void AddDistanceToOriginAsWeights()
- Add weights to each pixel in the neighborhood, using the Euclidean distance to the origin as the weight. This is useful for algorithms that need to, for example, sort the pixels in the neighborhood by distance to the origin.
- auto HasWeights() const -> bool
- Tests if there are weights associated to each pixel in the neighborhood.
- auto WeightsAreComplex() const -> bool
- Tests if the weights associated to each pixel, if any, are complex-valued.
- auto Weights() const -> std::vector<dfloat> const&
- Returns a const reference to the weights array.
Class documentation
struct PixelRun
The pixel table is formed of pixel runs, represented by this structure.
Variables | |
---|---|
dip::IntegerArray coordinates | The coordinates of the first pixel in a run, w.r.t. the origin. |
dip::uint length | The length of the run, expected to always be larger than 0. |
Function documentation
PixelTable(dip::String const& shape, dip::FloatArray size, dip::uint procDim = 0)
Construct a pixel table for default filter shapes.
The known default shape
s are "rectangular"
, "elliptic"
, and "diamond"
,
which correspond to a unit circle in the L∞, L2 and L1 norms; and
"line"
, which is a single-pixel thick line.
The size
array determines the size and dimensionality. For unit circles, it gives the diameter of the
neighborhood (not the radius!); the neighborhood contains all pixels at a distance equal or smaller than
half the diameter from the origin. This means that non-integer sizes can be meaningful.
The exception is for the "rectangular"
shape, where the sizes are rounded down to the nearest integer,
yielding rectangle sides that are either even or odd in length. For even sizes, one can imagine that the
origin is shifted by half a pixel to accommodate the requested size (though the origin is set to the pixel
that is right of the center). For the "diamond"
and "elliptic"
shapes, the bounding box always has odd
sizes, and the origin is always centered on one pixel. To accomplish the same for the “rectangular” shape,
simply round the sizes array to an odd integer:
size[ ii ] = std::floor( size[ ii ] / 2 ) * 2 + 1
For the line, the size
array gives the size of the bounding box (rounded to the nearest integer), as
well as the direction of the line. A negative value for one dimension means that the line runs from
high to low along that dimension. The line will always run from one corner of the bounding box to the
opposite corner, and run through the origin.
procDim
indicates the processing dimension.
PixelTable(dip::Image const& mask, dip::IntegerArray const& origin = {}, dip::uint procDim = 0)
Construct a pixel table for an arbitrary shape defined by a binary image.
Set pixels in mask
indicate pixels that belong to the neighborhood.
origin
gives the coordinates of the pixel in the image that will be placed at the origin
(i.e. have coordinates {0,0,0}. If origin
is an empty array, the origin is set to the middle
pixel, as given by mask.Sizes() / 2
. That is, for odd-sized dimensions, the origin is the
exact middle pixel, and for even-sized dimensions the origin is the pixel to the right of the
exact middle.
procDim
indicates the processing dimension.
dip::PixelTableOffsets Prepare(dip::Image const& image) const
Prepare the pixel table to be applied to a specific image.
The resulting object is identical to this
,
but has knowledge of the image’s strides and thus directly gives offsets rather than coordinates to
the neighbors.
std::vector<dfloat> const& Weights() const
Returns a const reference to the weights array.
If dip::PixelTable::HasWeights
, then the array returned is not empty. If dip::PixelTable::WeightsAreComplex
is false, there
will be dip::PixelTable::NumberOfPixels
weights, one for each pixel in the neighborhood, stored in the same order
that the dip::PixelTable::iterator
visits these pixels.
If dip::PixelTable::WeightsAreComplex
is true, there will be two times dip::PixelTable::NumberOfPixels
weights. Each pair of
weights represents one complex value. The pointer to the weights array data can be cast to dip::dcomplex
.