Mathematical morphology over n-dimensional matrices with a random
n-dimensional structuring element (shape), represented by Pattern class.
It is supposed that the type of matrix elements is one of primitive Java types
(boolean, char, byte, short, int,
long, float, double) and, so, represents an integer or a real number,
according to comments to PFixedArray.getLong(long) and PArray.getDouble(long) methods.
In 2-dimensional case, these operations can be used for processing grayscale digital images.
Please see Wikipedia
about the "Mathematical morphology" concept.
Basic operations, defined by this interface, are dilation
and erosion. Other operations are combinations
of the basic ones and, probably, some arithmetic elementwise operations.
This package provides the following basic methods for creating objects, implementing this interface:
Returns an immutable view of the passed source matrix,
such that any reading data from it calculates and returns the dilation
of the source matrix by the specified pattern.
Returns an immutable view of the passed source matrix,
such that any reading data from it calculates and returns the erosion
of the source matrix by the specified pattern.
Returns a new updatable matrix, containing the Beucher gradient
of the source matrix by the specified pattern, that means
the elementwise difference between dilation
and erosion of the source matrix with the same pattern.
Switches the context: returns an instance, identical to this one excepting
that it uses the specified newContext for all operations.
The returned instance is usually a clone of this one, but there is no guarantees
that it is a deep clone.
Usually, the returned instance is used only for performing a
subtask of the full task.
More precisely, it means that when the value in some element of the processed matrix,
returned by a method of this class, depends on elements of the source matrix, lying outside its bounds,
then it is supposed that the values outside the source matrix are calculated as described in
Matrix.ContinuationMode.PSEUDO_CYCLIC. Exactly such behaviour is specified in
the comments to the basic dilation(Matrix, Pattern) and erosion(Matrix, Pattern)
methods as the default definition of dilation and erosion.
Returns an immutable view of the passed source matrix,
such that any reading data from it calculates and returns the dilation
of the source matrix by the specified pattern.
See dilation(Matrix, Pattern) method about the "dilation" term.
The element type
of the created matrix is the same as the element type of the source one.
The result is usually "lazy", that means that this method finishes immediately and all
actual calculations are performed while getting elements of the returned matrix.
It is true for all implementations provided by this package.
However, some implementations may not support lazy dilation;
then this method will be equivalent to dilation(Matrix, Pattern).
Please note: this method does not require time (if the result is "lazy"),
but the resulting matrix can work slowly!
For example, reading all its content than work much slower than dilation(Matrix, Pattern)
method for complex patterns.
Usually you should use it only for very little patterns, or if you know that the implementation
of this interface does not provide better algorithm for non-"lazy"
dilation(Matrix, Pattern) method.
Parameters:
src - the source matrix.
pattern - the pattern.
Returns:
the "lazy" matrix containing the dilation of the source matrix by the given pattern.
Returns an immutable view of the passed source matrix,
such that any reading data from it calculates and returns the erosion
of the source matrix by the specified pattern.
See erosion(Matrix, Pattern) method about the "erosion" term.
The element type
of the created matrix is the same as the element type of the source one.
The result is usually "lazy", that means that this method finishes immediately and all
actual calculations are performed while getting elements of the returned matrix.
It is true for all implementations provided by this package.
However, some implementations may not support lazy erosion;
then this method will be equivalent to erosion(Matrix, Pattern).
Please note: this method does not require time (if the result is "lazy"),
but the resulting matrix can work slowly!
For example, reading all its content than work much slower than dilation(Matrix, Pattern)
method for complex patterns.
Usually you should use it only for very little patterns, or if you know that the implementation
of this interface does not provide better algorithm for non-"lazy"
erosion(Matrix, Pattern) method.
Parameters:
src - the source matrix.
pattern - the pattern.
Returns:
the "lazy" matrix containing the erosion of the source matrix by the given pattern.
Returns a new updatable matrix, containing the dilation
of the source matrix by the specified pattern.
Usually dilation means the elementwise maximum from the set of matrices,
obtained by pseudo-cyclic shifting the source matrix by the vectors,
equal to all pattern points.
More precisely, let mi=Matrices.asShifted(src,ip.coordinates()),
where ip is the point #i from all points contained in the pattern.
Then the every element of the returned matrix is the maximum from all corresponding elements
of all mi matrices. The element type
of the created matrix is the same as the element type of the source one.
The byte and short elements are considered to be unsigned.
In a case of bit elements, the maximum is equivalent to logical OR.
The basic morphology implementation BasicMorphology strictly complies with this definition.
However, other implementations of this interface may use alternate definitions of the dilation term.
For example, some percentile (90% or 80%) may be used instead of strict maximum
(as in objects, returned by BasicRankMorphology.getInstance(ArrayContext, double, CustomRankPrecision)
method),
or elements outside the matrix may be supposed to be filled according some non-trivial rules
instead of pseudo-cyclic continuation
(as in ContinuedMorphology objects),
or only some region of the matrix may be processed, etc.
Please see
Wikipedia
to know more about the dilation.
Parameters:
src - the source matrix.
pattern - the pattern.
Returns:
the result of dilation of the source matrix by the given pattern.
Returns a new updatable matrix, containing the erosion
of the source matrix by the specified pattern.
Usually erosion means the elementwise minimum from the set of matrices,
obtained by pseudo-cyclic shifting the source matrix by the vectors,
symmetric to all pattern points relatively the origin of coordinates.
More precisely, let mi=Matrices.asShifted(src,ip.symmetric().coordinates()),
where ip is the point #i from all points contained in the pattern.
Then the every element of the returned matrix is the minimum from all corresponding elements
of all mi matrices. The element type
of the created matrix is the same as the element type of the source one.
The byte and short elements are considered to be unsigned.
In a case of bit elements, the minimum is equivalent to logical AND.
The basic morphology implementation BasicMorphology strictly complies with this definition.
However, other implementations of this interface may use alternate definitions of the erosion term.
For example, some percentile (10% or 20%) may be used instead of strict minimum
(as in objects, returned by BasicRankMorphology.getInstance(ArrayContext, double, CustomRankPrecision)
method),
or elements outside the matrix may be supposed to be filled according some non-trivial rules
instead of pseudo-cyclic continuation
(as in ContinuedMorphology objects),
or only some region of the matrix may be processed, etc.
Please see
Wikipedia
to know more about the erosion.
Parameters:
src - the source matrix.
pattern - the pattern.
Returns:
the result of erosion of the source matrix by the given pattern.
Equivalent to dilation(Matrix, Pattern) method, but the result matrix
will be placed in the dest argument.
It allows to avoid extra memory allocation if you need to perform dilation many times
from one matrix to another.
Moreover, if disableMemoryAllocation argument is true, this method
guarantees that no any additional memory will be allocated, even if it can optimize the algorithm speed.
In this case, this method is always executed in one pass:
it is equivalent to creating new lazy matrix by asDilation(Matrix src, Pattern pattern) method
and further copying it into dest by Matrices.copy(ArrayContext, Matrix, Matrix) method.
It can be useful if you are sure that the pattern is small enough (usually 2-10 points),
and allocation additional work matrices can slow down the algorithm to greater extent
than using the simple one-pass algorithm.
If the element type of the dest matrix is not the same as the source element type
(dest.elementType()!=src.elementType()),
the elements are automatically cast to the necessary type. More precisely, in this case
the dest matrix, before all further calculations, is replaced with
We do not recommend to pass matrices with different element types: it can slow down calculations.
Parameters:
dest - the target matrix.
src - the source matrix.
pattern - the pattern.
disableMemoryAllocation - if false, this method may allocate additional temporary matrices
for optimizing the algorithm speed;
if true, no any work memory will be allocated.
Equivalent to erosion(Matrix, Pattern) method, but the result matrix
will be placed in the dest argument.
It allows to avoid extra memory allocation if you need to perform erosion many times
from one matrix to another.
Moreover, if disableMemoryAllocation argument is true, this method
guarantees that no any additional memory will be allocated, even if it can optimize the algorithm speed.
In this case, this method is always executed in one pass:
it is equivalent to creating new lazy matrix by asDilation(Matrix src, Pattern pattern) method
and further copying it into dest by Matrices.copy(ArrayContext, Matrix, Matrix) method.
It can be useful if you are sure that the pattern is small enough (usually 2-10 points),
and allocation additional work matrices can slow down the algorithm to greater extent
than using the simple one-pass algorithm.
If the element type of the dest matrix is not the same as the source element type
(dest.elementType()!=src.elementType()),
the elements are automatically cast to the necessary type. More precisely, in this case
the dest matrix, before all further calculations, is replaced with
We do not recommend to pass matrices with different element types: it can slow down calculations.
Parameters:
dest - the target matrix.
src - the source matrix.
pattern - the pattern.
disableMemoryAllocation - if false, this method may allocate additional temporary matrices
for optimizing the algorithm speed;
if true, no any work memory will be allocated.
If subtractionMode is not Morphology.SubtractionMode.NONE,
the behaviour is little other: this method returns the difference between
the result of these two operation and the src matrix, according the specified mode.
When both patterns are equal, the result is the closing of the matrix.
Parameters:
src - the source matrix.
dilationPattern - the pattern for dilation.
erosionPattern - the pattern for erosion.
subtractionMode - whether the difference with the source matrix should be returned.
Returns:
the result of sequential dilation and erosion of the source matrix by the given patterns
or the difference of such result and the source matrix.
If subtractionMode is not Morphology.SubtractionMode.NONE,
the behaviour is little other: this method returns the difference between
the result of these two operation and the src matrix, according the specified mode.
When both patterns are equal, the result is the opening of the matrix.
Parameters:
src - the source matrix.
erosionPattern - the pattern for erosion.
dilationPattern - the pattern for dilation.
subtractionMode - whether the difference with the source matrix should be returned.
Returns:
the result of sequential erosion and dilation of the source matrix by the given patterns
or the difference of such result and the source matrix.
Returns a new updatable matrix, containing the closing
of the source matrix by the specified pattern.
Closing means the result of sequential performing
dilation and erosion of the source matrix
with the same pattern.
If subtractionMode is not Morphology.SubtractionMode.NONE,
the behaviour is little other: this method returns the difference between
the closing and the src matrix, according the specified mode.
For example, Morphology.SubtractionMode.SUBTRACT_SRC_FROM_RESULT argument
with this method allows to remove "light" background from a gray-scale image,
represented by src matrix.
Returns a new updatable matrix, containing the opening
of the source matrix by the specified pattern.
Opening means the result of sequential performing
erosion and dilation of the source matrix
with the same pattern.
If subtractionMode is not Morphology.SubtractionMode.NONE,
the behaviour is little other: this method returns the difference between
the opening and the src matrix, according the specified mode.
For example, Morphology.SubtractionMode.SUBTRACT_RESULT_FROM_SRC argument
with this method allows to remove "dark" background from a gray-scale image,
represented by src matrix.
Returns a new updatable matrix, containing the weak dilation
of the source matrix by the specified pattern.
Weak dilation of the matrix A is defined as an elementwise difference
B=dilation(A)-(closing(A)-A).
It is obvious that, for any elements, A<=B<=dilation(A)
(because both differences
dilation(A)-closing(A)
and closing(A)-A are non-negative).
Returns a new updatable matrix, containing the weak erosion
of the source matrix by the specified pattern.
Weak erosion of the matrix A is defined as an elementwise sum
B=erosion(A)+(A-opening(A)).
It is obvious that, for any elements, A>=B>=erosion(A)
(because both differences
opening(A)-erosion(A)
and A-opening(A) are non-negative).
Let B is the result of this method, A is the source matrix,
Q is dilationPattern, P is erosionPattern: B=min(A,erosion(dilation(A,Q),P)) for any elements.
It is obvious that (for any elements) A>=B>=erosion(A,P).
But if Q is a some "boundary" or "carcass" of the erosion pattern P,
then a stronger condition is true:
A>=B>=opening(A,P).
More precisely, there is the following theorem.
If Q is a subset of P and the Minkowski sum P⊕Q is equal to
P⊕P (see Pattern.carcass() method),
then B>=opening(A,P).
Below is the proof for the binary case.
(For other element types, it's enough to consider the system of binary matrices
A>=threshold for all possible real values threshold.)
Let some point x∈opening(A,P).
It means: there is such p1∈P,
that for all p∈P we have x+p1-p∈A
(the statement A).
We already know, that x∈A (the case p=p1),
and we also need to prove, that x∈erosion(dilation(A,Q),P).
Let's suppose that it is not true. It means: there is such p2∈P,
that for all q∈Q we have x+p2-q∉A
(the statement B)
Let x will be the origin of coordinates: x=0. Then, let
P1=-P+p1={p1-p,
p∈P}. Note: the origin 0∈P1
(the case p=p1). We have P1⊂A
(statement A), so,
for all q∈Q we have p2-q∉P1
(because p2-q∉A, statement B).
In other words, p2∉P1⊕Q (dilation of P by Q,
or Minkowski sum of P and Q).
On the other hand, it's obvious that p2∈P1⊕P,
because 0∈P1 and, so,
P⊂P⊕P1=P1⊕P.
There is a contradiction: according to the condition, there must be
P1⊕P=P1⊕Q. The theorem is proved.
This fact allows to interpret this method, if dilationPattern
is a "boundary" of erosionPattern (usually UniformGridPattern.surface()
or a similar point set), as a "weak" analog of opening.
For binary images, it helps to remove small isolated objects, but (unlike usual opening)
to preserve thin structures.
Parameters:
src - the source matrix.
dilationPattern - the pattern for dilation.
erosionPattern - the pattern for erosion.
Returns:
the elementwise minimum between the source matrix and
its sequential dilation and erosion by the given patterns.
Returns a new updatable matrix, containing the Beucher gradient
of the source matrix by the specified pattern, that means
the elementwise difference between dilation
and erosion of the source matrix with the same pattern.
More precisely, the Beucher gradient of the matrix A is defined
as an elementwise positive difference
B=max(0,dilation(A)-erosion(A)).
The element type
of the created matrix is the same as the element type of the source one.
The byte and short elements are considered to be unsigned.
Parameters:
src - the source matrix.
pattern - the pattern.
Returns:
the Beucher gradient of the source matrix by the given pattern.