dip::PixelTable class

Represents an arbitrarily-shaped neighborhood (filter support) in an arbitrary number of dimensions.

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:

  1. dip::PixelTable::Runs returns a std::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 filter dip::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.

  2. 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

struct PixelRun
The pixel table is formed of pixel runs, represented by this structure.
class iterator
An iterator that visits each of the neighborhood’s pixels in turn.

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 shapes 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.