Morphological filtering module #include "diplib/morphology.h"
Morphological filters for smoothing, sharpening, detection and more.
Classes
-
class dip::
StructuringElement - Represents the shape and size of a structuring element. more...
Functions
-
void dip::
AlternatingSequentialFilter(dip::Image const& in, dip::Image& out, dip::Range const& sizes = {3,7,2}, dip::String const& shape = S::ELLIPTIC, dip::String const& mode = S::STRUCTURAL, dip::String const& polarity = S::OPENCLOSE, dip::StringArray const& boundaryCondition = {}) - Alternating sequential filters for smoothing more...
-
void dip::
AreaClosing(dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::uint filterSize, dip::uint connectivity = 0) - Computes the area closing, calling
dip::AreaOpeningwithpolarity="closing". -
void dip::
AreaOpening(dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::uint filterSize, dip::uint connectivity = 0, dip::String const& polarity = S::OPENING) - Computes the area opening or closing. This is a parametric opening. more...
-
void dip::
Closing(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {}) - Applies the closing with a standard or custom structuring element. more...
-
void dip::
ClosingByReconstruction(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::uint connectivity = 0, dip::StringArray const& boundaryCondition = {}) - Closing by reconstruction more...
-
void dip::
Dilation(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {}) - Applies the dilation with a standard or custom structuring element. more...
-
void dip::
DirectedPathOpening(dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::IntegerArray filterParam, dip::String const& polarity = S::OPENING, dip::StringSet const& mode = {}) - Applies a path opening or closing in a specific direction. more...
-
void dip::
Erosion(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {}) - Applies the erosion with a standard or custom structuring element. more...
-
void dip::
HitAndMiss(dip::Image const& in, dip::Image& out, dip::StructuringElement const& hit, dip::StructuringElement const& miss, dip::String const& mode = S::UNCONSTRAINED, dip::StringArray const& boundaryCondition = {}) - The Hit-and-Miss transform, uses two structuring elements,
hitmust be within the structures,missmust be without. more... -
void dip::
HitAndMiss(dip::Image const& in, dip::Image& out, dip::Image const& se, dip::String const& mode = S::UNCONSTRAINED, dip::StringArray const& boundaryCondition = {}) - The Hit-and-Miss transform, uses a single structuring element in the form of a small image that has “hit”, “miss” and “don’t care” values. more...
-
void dip::
HMaxima(dip::Image const& in, dip::Image& out, dip::dfloat h, dip::uint connectivity = 0) - Computes the H-Maxima filtered image more...
-
void dip::
HMinima(dip::Image const& in, dip::Image& out, dip::dfloat h, dip::uint connectivity = 0) - Computes the H-Minima filtered image more...
-
void dip::
ImposeMinima(dip::Image const& in, dip::Image const& marker, dip::Image& out, dip::uint connectivity = 0) - Impose minima. more...
-
void dip::
Lee(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::String const& sign = S::UNSIGNED, dip::StringArray const& boundaryCondition = {}) - A morphological edge detector more...
-
void dip::
Leveling(dip::Image const& in, dip::Image const& marker, dip::Image& out, dip::uint connectivity = 0) - The leveling of
inimposed bymarker. more... -
void dip::
LimitedMorphologicalReconstruction(dip::Image const& marker, dip::Image const& in, dip::Image& out, dip::dfloat maxDistance = 20, dip::uint connectivity = 0, dip::String const& direction = S::DILATION) - Reconstruction by dilation or erosion, but with a limited reach. more...
-
void dip::
MorphologicalGist(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::StringArray const& boundaryCondition = {}) - Morphological gist operator and its variants more...
-
void dip::
MorphologicalGradientMagnitude(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {}) - The morphological version of the gradient magnitude more...
-
void dip::
MorphologicalLaplace(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {}) - The morphological version of the Laplace operator more...
-
void dip::
MorphologicalRange(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::StringArray const& boundaryCondition = {}) - A morphological edge detector more...
-
void dip::
MorphologicalReconstruction(dip::Image const& marker, dip::Image const& in, dip::Image& out, dip::uint connectivity = 0, dip::String const& direction = S::DILATION) - Reconstruction by dilation or erosion, also known as inf-reconstruction and sup-reconstruction more...
-
void dip::
MorphologicalSharpening(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {}) - A morphological sharpening filter more...
-
void dip::
MorphologicalSmoothing(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& polarity = S::AVERAGE, dip::StringArray const& boundaryCondition = {}) - A morphological smoothing filter more...
-
void dip::
MorphologicalThreshold(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::StringArray const& boundaryCondition = {}) - A morphological smoothing filter more...
-
void dip::
MultiScaleMorphologicalGradient(dip::Image const& in, dip::Image& out, dip::uint upperSize = 9, dip::uint lowerSize = 3, dip::String const& filterShape = S::ELLIPTIC, dip::StringArray const& boundaryCondition = {}) - A morphological edge detector more...
-
void dip::
Opening(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {}) - Applies the opening with a standard or custom structuring element. more...
-
void dip::
OpeningByReconstruction(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::uint connectivity = 0, dip::StringArray const& boundaryCondition = {}) - Opening by reconstruction more...
-
void dip::
PathOpening(dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::uint length = 7, dip::String const& polarity = S::OPENING, dip::StringSet const& mode = {}) - Applies a path opening or closing in all possible directions more...
-
void dip::
RankFilter(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::uint rank = 2, dip::String const& order = S::INCREASING, dip::StringArray const& boundaryCondition = {}) - Applies the rank-order filter. more...
-
void dip::
RankMaxOpening(dip::Image const& in, dip::Image& out, dip::StructuringElement se = {}, dip::uint rank = 2, dip::StringArray const& boundaryCondition = {}) - Applies the rank-max opening, an opening that is somewhat robust to noise. more...
-
void dip::
RankMinClosing(dip::Image const& in, dip::Image& out, dip::StructuringElement se = {}, dip::uint rank = 2, dip::StringArray const& boundaryCondition = {}) - Applies the rank-min closing, a closing that is somewhat robust to noise. more...
-
void dip::
Tophat(dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::String const& polarity = S::WHITE, dip::StringArray const& boundaryCondition = {}) - The Top-hat operator and its variants more...
-
void dip::
UpperSkeleton2D(dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::String const& endPixelCondition = S::NATURAL) - Grey-value skeleton (2D only). more...
-
void dip::
VolumeClosing(dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::dfloat filterSize, dip::uint connectivity = 0) - Computes the area closing, calling
dip::VolumeOpeningwithpolarity="closing". -
void dip::
VolumeOpening(dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::dfloat filterSize, dip::uint connectivity = 0, dip::String const& polarity = S::OPENING) - Computes the volume opening or closing. This is a parametric opening. more...
Function documentation
void
dip:: Dilation(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {})
Applies the dilation with a standard or custom structuring element.
If the structuring element is a set (i.e. a binary image, or a footprint), the dilation of image is defined as (the supremum or maximum over the pixels covered by the structuring element). For gray-scale structuring elements, it is defined as .
se defines the structuring element, see dip::StructuringElement for options and details.
boundaryCondition determines the boundary conditions. See dip::BoundaryCondition.
The default value, and most meaningful one, is "add min", but any value can be used.
For the rectangular, diamond, fast line and periodic line structuring elements, no boundary condition
causes the filter to not read outside the image bounds. This is equivalent to "add min".
in must be a scalar image, and not complex-valued. In particular, in can be binary; this function
is more efficient than dip::BinaryDilation.
void
dip:: Erosion(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {})
Applies the erosion with a standard or custom structuring element.
If the structuring element is a set (i.e. a binary image, or a footprint), the erosion of image is defined as (the infimum or minimum over the pixels covered by the structuring element). For gray-scale structuring elements, it is defined as .
se defines the structuring element, see dip::StructuringElement for options and details.
boundaryCondition determines the boundary conditions. See dip::BoundaryCondition.
The default value, and most meaningful one, is "add max", but any value can be used.
For the rectangular, diamond, fast line and periodic line structuring elements, no boundary condition
causes the filter to not read outside the image bounds. This is equivalent to "add max".
in must be a scalar image, and not complex-valued. In particular, in can be binary; this function
is more efficient than dip::BinaryErosion.
void
dip:: Closing(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {})
Applies the closing with a standard or custom structuring element.
The closing is defined as a dilation followed by its complementary erosion (i.e. with the mirrored structuring element).
se defines the structuring element, see dip::StructuringElement for options and details.
boundaryCondition determines the boundary conditions. See dip::BoundaryCondition.
Meaningful values for the closing are "add max" and "add min", but any value can
be used. The default empty array causes the function to use "add min" with the dilation
and "add max" with the erosion, equivalent to ignoring what’s outside the image.
For the rectangular, diamond, fast line and periodic line structuring elements, no boundary condition
causes the filter to not read outside the image bounds.
in must be a scalar image, and not complex-valued. In particular, in can be binary; this function
is more efficient than dip::BinaryClosing.
void
dip:: Opening(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {})
Applies the opening with a standard or custom structuring element.
The opening is defined as a erosion followed by its complementary dilation (i.e. with the mirrored structuring element).
se defines the structuring element, see dip::StructuringElement for options and details.
boundaryCondition determines the boundary conditions. See dip::BoundaryCondition.
Meaningful values for the opening are "add max" and "add min", but any value can
be used. The default empty array causes the function to use "add min" with the dilation
and "add max" with the erosion, equivalent to ignoring what’s outside the image.
For the rectangular, diamond, fast line and periodic line structuring elements, no boundary condition
causes the filter to not read outside the image bounds.
in must be a scalar image, and not complex-valued. In particular, in can be binary; this function
is more efficient than dip::BinaryOpening.
void
dip:: Tophat(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::String const& polarity = S::WHITE, dip::StringArray const& boundaryCondition = {})
The Top-hat operator and its variants
The top-hat is the difference between a morphological operation and the original image,
comparable to a high-pass filter. The flags edgeType and polarity define which
operation is applied.
edgeType can be one of:
"texture": response is limited to edges in texture (i.e. scales smaller than the structuring element)."object": response is limited to object edges (i.e. scales larger than the structuring element)."both"or"dynamic": all edges produce equal response.
polarity can be either "white" to indicate objects are brighter than the background, or "black" to
indicate objects are darker than the background.
The standard top-hat is defined as the Opening( in ) - in. This is the operation obtained
with the default values.
se defines the structuring element, and boundaryCondition the boundary conditions.
See dip::Dilation for a description of these parameters.
void
dip:: MorphologicalThreshold(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::StringArray const& boundaryCondition = {})
A morphological smoothing filter
Implements a morphological smoothing based on the average of two complementary morphological operations.
These can be chosen through the edgeType parameter.
edgeType can be one of:
"texture": response is limited to edges in texture (i.e. scales smaller than the structuring element)."object": response is limited to object edges (i.e. scales larger than the structuring element)."both"or"dynamic": all edges produce equal response.
se defines the structuring element, and boundaryCondition the boundary conditions.
See dip::Dilation for a description of these parameters.
void
dip:: MorphologicalGist(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::StringArray const& boundaryCondition = {})
Morphological gist operator and its variants
Similar to the top-hat operator, it computes the difference between the average of two complementary morphological operators and the original image.
The flags edgeType defines which operation is applied:
"texture": response is limited to edges in texture (i.e. scales smaller than the structuring element)."object": response is limited to object edges (i.e. scales larger than the structuring element)."both"or"dynamic": all edges produce equal response.
se defines the structuring element, and boundaryCondition the boundary conditions.
See dip::Dilation for a description of these parameters.
void
dip:: MorphologicalRange(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::StringArray const& boundaryCondition = {})
A morphological edge detector
Implements a morphological edge detector based on the difference of two complementary morphological
operations. These can be chosen through the edgeType parameter.
edgeType can be one of:
"texture": response is limited to edges in texture (i.e. scales smaller than the structuring element)."object": response is limited to object edges (i.e. scales larger than the structuring element)."both"or"dynamic": all edges produce equal response.
se defines the structuring element, and boundaryCondition the boundary conditions.
See dip::Dilation for a description of these parameters.
void
dip:: MorphologicalGradientMagnitude(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {})
The morphological version of the gradient magnitude
The morphological gradient magnitude is defined as Dilation( in ) - Erosion( in ).
This function is implemented by a call to dip::MorphologicalRange with edgeType set to "both".
void
dip:: Lee(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& edgeType = S::TEXTURE, dip::String const& sign = S::UNSIGNED, dip::StringArray const& boundaryCondition = {})
A morphological edge detector
Implements a morphological edge detector based on the minimum of two complementary morphological
operations. These can be chosen through the edgeType parameter.
edgeType can be one of:
"texture": response is limited to edges in texture (i.e. scales smaller than the structuring element)."object": response is limited to object edges (i.e. scales larger than the structuring element)."both"or"dynamic": all edges produce equal response.
If sign is "unsigned", Lee computes the absolute edge strength. sign can also be "signed"
to compute the signed edge strength.
se defines the structuring element, and boundaryCondition the boundary conditions.
See dip::Dilation for a description of these parameters.
void
dip:: MorphologicalSmoothing(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::String const& polarity = S::AVERAGE, dip::StringArray const& boundaryCondition = {})
A morphological smoothing filter
Implements a morphological smoothing based on the sequence of an opening and a closing. Their order
can be chosen through the polarity parameter.
polarity can be one of:
"open-close": applies the opening first, then the closing."close-open": applies the closing first, then the opening."average": computes the average of the result of the first two modes.
se defines the structuring element, and boundaryCondition the boundary conditions.
See dip::Dilation for a description of these parameters.
void
dip:: MorphologicalSharpening(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {})
A morphological sharpening filter
Implements a morphological sharpening based on selecting per pixel the result of the dilation or erosion, whichever is closest to the input image.
se defines the structuring element, and boundaryCondition the boundary conditions.
See dip::Dilation for a description of these parameters.
void
dip:: MultiScaleMorphologicalGradient(
dip::Image const& in, dip::Image& out, dip::uint upperSize = 9, dip::uint lowerSize = 3, dip::String const& filterShape = S::ELLIPTIC, dip::StringArray const& boundaryCondition = {})
A morphological edge detector
This function computes the average morphological gradient over a range of scales bounded by upperSize
and lowerSize. The morphological gradient is computed as the difference of the dilation and erosion
of the input image at a particular scale, eroded by an erosion of one size smaller. At the lowest scale,
the diameter of the structuring element is 2 * lowerSize + 1.
filterShape can be either "rectangular", "elliptic", and "diamond", as described in
dip::StructuringElement.
boundaryCondition determines the boundary conditions. See dip::BoundaryCondition.
The default empty array causes the function to use "add min" with the dilation
and "add max" with the erosion, equivalent to ignoring what’s outside the image.
void
dip:: MorphologicalLaplace(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::StringArray const& boundaryCondition = {})
The morphological version of the Laplace operator
This function computes:
out = ( Dilation( in ) + Erosion( in ) ) / 2 - in;
se defines the structuring element, and boundaryCondition the boundary conditions.
See dip::Dilation for a description of these parameters.
void
dip:: RankFilter(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::uint rank = 2, dip::String const& order = S::INCREASING, dip::StringArray const& boundaryCondition = {})
Applies the rank-order filter.
se defines the structuring element. rank determines which of the sorted values within
the SE should be written to the output. A rank of 1 leads to an erosion, and a rank equal
to the number of pixels within the SE leads to a dilation. If order is "decreasing" (instead
of the default "increasing"), then rank is interpreted in the opposite direction, it
counts elements starting at the largest value. In this case, a rank of 1 is equal to a dilation.
Thus, a small non-zero rank with increasing order leads to an approximation to the dilation that is less sensitive to noise, and a small non-zero rank with decreasing order leads to an approximation of the erosion.
See also dip::PercentileFilter, which does the same thing but uses a percentile instead of
a rank as input argument.
boundary determines the boundary conditions. See dip::BoundaryCondition.
The default value is the most meaningful one, but any value can be used. By default it is
"add max" if rank is lower than half of the pixels in the SE, or "add min" otherwise.
void
dip:: RankMinClosing(
dip::Image const& in, dip::Image& out, dip::StructuringElement se = {}, dip::uint rank = 2, dip::StringArray const& boundaryCondition = {})
Applies the rank-min closing, a closing that is somewhat robust to noise.
se defines the structuring element. rank determines how many pixels in the SE
are ignored. That is, if the SE has n pixels, then a rank filter with rank equal
to n - rank is applied instead of a dilation.
This function uses the definition of Soille:
which is identical to
boundary determines the boundary conditions. See dip::BoundaryCondition.
The default empty array causes the function to use "add min" with the rank filter,
and "add max" with the erosion, equivalent to ignoring what’s outside the image.
void
dip:: RankMaxOpening(
dip::Image const& in, dip::Image& out, dip::StructuringElement se = {}, dip::uint rank = 2, dip::StringArray const& boundaryCondition = {})
Applies the rank-max opening, an opening that is somewhat robust to noise.
se defines the structuring element. rank determines how many pixels in the SE
are ignored. That is, a rank filter with rank equal rank + 1 is applied instead of an
erosion.
This function uses the definition of Soille (ref!):
which is identical to
boundary determines the boundary conditions. See dip::BoundaryCondition.
The default empty array causes the function to use "add min" with the dilation,
and "add max" with the rank filter, equivalent to ignoring what’s outside the image.
void
dip:: UpperSkeleton2D(
dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::String const& endPixelCondition = S::NATURAL)
Grey-value skeleton (2D only).
This algorithm finds ridges in the image by, starting at the lowest values, setting values to the minimum possible value for the given data type if that doesn’t change the topology of the higher-valued pixels. It uses Hilditch conditions to preserve topology. The unmodified pixels are the grey-value equivalent to a binary skeleton. Note that the minimum possible value is minus infinity for floating-point types.
The mask image optionally restricts the region of the image processed. Pixels not selected by the mask will
retain their original value.
The endPixelCondition parameter determines what is considered an “end pixel” in the skeleton, and thus affects
how many branches are generated. It is one of the following strings:
"natural": “natural” end pixel condition of this algorithm."one neighbor": Keep endpoint if it has one neighbor."two neighbors": Keep endpoint if it has two neighbors."three neighbors": Keep endpoint if it has three neighbors.
To generate skeletons without end pixels (the equivalent of "loose ends away" in dip::EuclideanSkeleton),
use dip::Watershed instead.
in must be a real-valued, scalar image. out will have the same type.
void
dip:: MorphologicalReconstruction(
dip::Image const& marker, dip::Image const& in, dip::Image& out, dip::uint connectivity = 0, dip::String const& direction = S::DILATION)
Reconstruction by dilation or erosion, also known as inf-reconstruction and sup-reconstruction
This function has the same effect as iteratively dilating (eroding) the image marker such that it remains lower
(higher) than in everywhere, until stability. However, this is implemented with a much more efficiently.
direction indicates which of the two operations to apply ("dilation" or "erosion").
out will have the data type of in, and marker will be cast to that same type (with clamping to the target
range, see dip::Convert).
See Connectivity for information on the connectivity parameter.
The algorithm implemented is a hybrid between the method proposed by Vincent (a forward raster scan, followed by a backward raster scan, followed by a LIFO queue propagation method), and that proposed by Robinson and Whelan (a priority queue method). We implement the forward and backward scan, and follow it by a priority queue propagation. The priority queue method has the advantage of visiting each pixels exactly once.
For binary images, this function calls dip::BinaryPropagation, which uses the same algorithm but is specialized
for the binary case (e.g. using a stack instead of a priority queue).
This functions is used by dip::LimitedMorphologicalReconstruction, dip::HMinima, dip::HMaxima,
dip::Leveling, dip::OpeningByReconstruction, dip::ClosingByReconstruction
void
dip:: LimitedMorphologicalReconstruction(
dip::Image const& marker, dip::Image const& in, dip::Image& out, dip::dfloat maxDistance = 20, dip::uint connectivity = 0, dip::String const& direction = S::DILATION)
Reconstruction by dilation or erosion, but with a limited reach.
Performs the same function as dip::MorphologicalReconstruction, but limiting the
reach of the operation to maxDistance pixels. This is an Euclidean distance, and
determines the zone of influence of each value in marker. The limited reach is
accomplished by updating in, rather than counting propagation steps.
See dip::MorphologicalReconstruction for the meaning of the rest of the parameters,
and more information about the algorithm.
void
dip:: HMinima(
dip::Image const& in, dip::Image& out, dip::dfloat h, dip::uint connectivity = 0)
Computes the H-Minima filtered image
The H-Minima filtered image has all local minima with a depth less than h removed:
HMinima = dip::MorphologicalReconstruction( in + h, in, connectivity, "erosion" );
void
dip:: HMaxima(
dip::Image const& in, dip::Image& out, dip::dfloat h, dip::uint connectivity = 0)
Computes the H-Maxima filtered image
The H-Maxima filtered image has all local maxima with a height less than h removed:
HMaxima = dip::MorphologicalReconstruction( in - h, in, connectivity, "dilation" );
void
dip:: ImposeMinima(
dip::Image const& in, dip::Image const& marker, dip::Image& out, dip::uint connectivity = 0)
Impose minima.
Regions in marker will be the only local minima in in: dip::Minima( dip::ImposeMinima( a, b )) == b, for any a.
The image in will be modified such that the regions marked by marker obtain the lowest possible value for the
given data type, and any other local minima in in are filled in to become plateaus. Minimum imposition is typically
applied in conjunction with the watershed to reduce the number of regions created. The function dip::SeededWatershed
has a similar result, but obtained in a different way, to applying dip::Watershed to the output of ImposeMinima.
void
dip:: Leveling(
dip::Image const& in, dip::Image const& marker, dip::Image& out, dip::uint connectivity = 0)
The leveling of in imposed by marker.
The leveling introduces flat zones in the image, in such a way that, if , then and , with the leveling of , and , any two locations within the image. That is, for any edge remaining in , there exists an edge of equal or larger magnitude in .
The leveling can be obtained by initializing to the marker image and iteratively applying
until idempotence ( doesn’t change any further). However, here it is implemented more efficiently
using dip::MorphologicalReconstruction.
The marker image can be a smoothed version of in, then the leveling yields a similar simplification as
the smoothing, but preserving sharp edges.
void
dip:: AreaOpening(
dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::uint filterSize, dip::uint connectivity = 0, dip::String const& polarity = S::OPENING)
Computes the area opening or closing. This is a parametric opening.
The area opening removes all local maxima that have an area smaller than the given parameter filterSize,
and is equivalent to the supremum of openings with all possible connected flat structuring elements of that area.
The output has all maxima being connected components with a size of at least filterSize. The area closing is the
dual operation.
Note that we refer to “area” here as the number of pixels, which readily extends to any number of dimensions.
in must be scalar and real-valued or binary.
mask restricts the image regions used for the operation.
connectivity determines what a connected component is. See Connectivity for information on the
connectivity parameter.
polarity can be "opening" (the default) or "closing", to compute the area opening or area closing, respectively.
We use a union-find implementation similar to that described my Meijster and Wilkinson (2002), and is based on
the algorithm for our fast watershed ("fast" mode to dip::Watershed). For binary images, this function calls
dip::BinaryAreaOpening or dip::BinaryAreaClosing.
void
dip:: AreaClosing(
dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::uint filterSize, dip::uint connectivity = 0)
Computes the area closing, calling dip::AreaOpening with polarity="closing".
void
dip:: VolumeOpening(
dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::dfloat filterSize, dip::uint connectivity = 0, dip::String const& polarity = S::OPENING)
Computes the volume opening or closing. This is a parametric opening.
The volume opening removes all local maxima that have a volume smaller than the given parameter filterSize. The
“volume” is the integral over the pixel values, offset by the graylevel at which the maximum is cut.
The volume closing is the dual operation.
Comparing to the area opening, which removes peaks by the area of their support, this function removes peaks by
the volume being removed. The difference of the opening with the input image, in the case of the area opening,
is a series of peaks, each of which less than filterSize pixels, surrounded by zero-valued pixels.
In the case of the volume opening, these peaks all have an integral (sum of pixel values) of less than filterSize.
in must be scalar and real-valued. Binary images are not allowed.
mask restricts the image regions used for the operation.
connectivity determines what a connected component is. See Connectivity for information on the
connectivity parameter.
polarity can be "opening" (the default) or "closing", to compute the area opening or area closing, respectively.
We use a union-find implementation similar to that described my Meijster and Wilkinson (2002), and is based on
the algorithm for our fast watershed ("fast" mode to dip::Watershed).
void
dip:: VolumeClosing(
dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::dfloat filterSize, dip::uint connectivity = 0)
Computes the area closing, calling dip::VolumeOpening with polarity="closing".
void
dip:: PathOpening(
dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::uint length = 7, dip::String const& polarity = S::OPENING, dip::StringSet const& mode = {})
Applies a path opening or closing in all possible directions
length is the length of the path. All filterParam arguments to dip::DirectedPathOpening that yield a
length of length pixels and represent unique directions are generated, and the directed path opening or closing
is computed for each of them. The supremum (when polarity is "opening") or infimum (when it is "closing") is
computed over all results. See dip::DirectedPathOpening for a description of the algorithm and the parameters.
void
dip:: DirectedPathOpening(
dip::Image const& in, dip::Image const& mask, dip::Image& out, dip::IntegerArray filterParam, dip::String const& polarity = S::OPENING, dip::StringSet const& mode = {})
Applies a path opening or closing in a specific direction.
The path opening is an opening over all possible paths of a specific length and general direction. A path direction represents a 90 degree cone within which paths are generated. The paths are formed by single pixel steps in one of three directions (in 2D): the main direction, or 45 degrees to the left or right. That is, if the main direction is [1,0] (to the right), then [1,-1] and [1,1] (diagonal up or down) are also possible steps. This leads to a number of different paths that is exponential in its lengths. However, the opening over all these paths can be computed in time, with the path length.
The direction description above can be generalized to any number of dimensions by realizing that the main direction can be specified by any of the neighbors of a central pixel, and then the other allowed steps are the neighbor pixels that are also neighbor to the pixel that represents the main direction. In 3D, this leads to 6 or 8 alternate steps.
There are 4 possible path directions in 2D, and 13 in 3D. Both length and direction are specified through
the filterParam argument, see below. Note that the path length is given by the number of pixels in the path,
not the Euclidean length of the path.
The polarity parameter can be "opening" (the default) or "closing", to compute the path opening and path
closing, respectively.
When mode contains "constrained", the path construction described above is modified such that, after every alternate
step, a step in the main direction must be taken. This constraint avoids a zig-zag line that causes the path
opening to yield much shorter lines for the diagonal directions if the lines in the image are thicker than one pixel.
See the paper by Luengo referenced below. It also reduces the cone size from 90 degrees to 45 degrees, making the
algorithm more directionally-selective. The constrained mode increases computation time a little, but is highly
recommended when using the path opening in a granulometry. The alternate flag is "unconstrained", which is the
default and does not need to be given.
Path openings can be sensitive to noise. If mode contains "robust", a robust path opening or closing is
obtained. A robust path opening is computed by dilating the image with a 2x2 rectangular structuring element,
applying the path opening, then taking the infimum of the result and the input (Merveille, 2018). For a path
closing, the erosion and the supremum are used instead.
void
dip:: OpeningByReconstruction(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::uint connectivity = 0, dip::StringArray const& boundaryCondition = {})
Opening by reconstruction
Applies a structural erosion followed by a reconstruction by dilation.
See dip::Erosion and dip::MorphologicalReconstruction for a description of the parameters.
void
dip:: ClosingByReconstruction(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& se = {}, dip::uint connectivity = 0, dip::StringArray const& boundaryCondition = {})
Closing by reconstruction
Applies a structural dilation followed by a reconstruction by erosion.
See dip::Dilation and dip::MorphologicalReconstruction for a description of the parameters.
void
dip:: AlternatingSequentialFilter(
dip::Image const& in, dip::Image& out, dip::Range const& sizes = {3,7,2}, dip::String const& shape = S::ELLIPTIC, dip::String const& mode = S::STRUCTURAL, dip::String const& polarity = S::OPENCLOSE, dip::StringArray const& boundaryCondition = {})
Alternating sequential filters for smoothing
Applies alternating sequential filters to in, using structuring element sizes given by the range sizes.
Alternating sequential filters are two morphological filters opening and closing, applied in sequence, from
a small size to a larger size. This provides an effective smoothing that is less biased than applying an
opening and closing of a single size (as in dip::MorphologicalSmoothing).
polarity can be "open-close" or "close-open", and determines which of the operations is applied first.
For example, if sizes is {3,7,2} and polarity is "open-close", the following operations are applied:
dip::Opening( in, out, { 3, shape } ); dip::Closing( out, out, { 3, shape } ); dip::Opening( out, out, { 5, shape } ); dip::Closing( out, out, { 5, shape } ); dip::Opening( out, out, { 7, shape } ); dip::Closing( out, out, { 7, shape } );
mode is one of:
"structural": uses structural openings and closings (seedip::Opening)."reconstruction": uses openings and closings by reconstruction (seedip::OpeningByReconstruction)."area": uses area openings and closings (seedip::AreaOpening) –shapeis ignored.
void
dip:: HitAndMiss(
dip::Image const& in, dip::Image& out, dip::StructuringElement const& hit, dip::StructuringElement const& miss, dip::String const& mode = S::UNCONSTRAINED, dip::StringArray const& boundaryCondition = {})
The Hit-and-Miss transform, uses two structuring elements, hit must be within the structures,
miss must be without.
For a binary image, the result is the intersection of the erosion of the image with hit and the erosion of the
inverted image with miss.
For a grey-value image, there are two definitions of the operator. If mode is "unconstrained", the output is
the difference of the erosion with hit and the dilation with miss, with any negative values clipped to 0.
If mode is "constrained", a more restrictive definition is applied (conditions evaluated pixel-wise):
- If
in == erosion(in,hit) && dilation(in,miss) < in:out = in - dilation(in,miss). - If
in == dilation(in,miss) && erosion(in,hit) > in:out = erosion(in,hit) - in. - Otherwise:
out = 0.
Note that the two structuring elements must be disjoint. If one pixel is set in both structuring elements, the output will be all zeros.
See also dip::SupGenerating for a function specific to binary images.
void
dip:: HitAndMiss(
dip::Image const& in, dip::Image& out, dip::Image const& se, dip::String const& mode = S::UNCONSTRAINED, dip::StringArray const& boundaryCondition = {})
The Hit-and-Miss transform, uses a single structuring element in the form of a small image that has “hit”, “miss” and “don’t care” values.
The hit SE is se == 1, the miss SE is se == 0. “Don’t care” values are any other value.
See the description for the other dip::HitAndMiss function for a description of the other parameters.