Efficient separable filters for associative operations
Out-of-place version
The localfilter
method may be called as:
dst = localfilter([T=eltype(A),] A, dims, op, rngs [, w])
to apply the van Herk-Gil-Werman algorithm to filter array A
along dimension(s) dims
with (associative) binary operation op
and contiguous structuring element(s) defined by the interval(s) rngs
. Optional argument T
is the element type of the result dst
(by default T = eltype(A)
). Optional argument w
is a workspace array which is automatically allocated if not provided; otherwise, it must be a vector with the same element type as A
which is resized as needed (by calling the resize!
method).
Argument dims
specifies along which dimension(s) of A
the filter is to be applied, it can be a single integer, several integers or a colon :
to specify all dimensions. Dimensions are processed in the order given by dims
(the same dimension may appear several times) and there must be a matching interval in rngs
to specify the structuring element (except that if rngs
is a single interval, it is used for every dimension in dims
). An interval is either an integer or an integer valued unit range in the form kmin:kmax
(an interval specified as a single integer, say k
, is the same as specifying k:k
).
Assuming a mono-dimensional array A
, the single filtering pass:
localfilter!(dst, A, :, op, rng)
amounts to computing:
dst[j] = A[j-kmax] ⋄ A[j-kmax+1] ⋄ A[j-kmax+2] ⋄ ... ⋄ A[j-kmin]
for all j ∈ [first(axes(A,1)):last(axes(A,1))]
, with x ⋄ y = op(x, y)
, kmin = first(rng)
and kmax = last(rng)
. Note that if kmin = kmax = k
(which occurs if rng
is a simple integer), the result of the filter is to operate a simple shift by k
along the corresponding dimension and has no effects if k = 0
. This can be exploited to not filter some dimension(s).
In-place version
The localfilter!
method implement the in-place version of the van Herk-Gil-Werman algorithm:
localfilter!([dst = A,] A, dims, op, rngs [, w]) -> dst
overwrites the contents of dst
with the result of the filter and returns dst
. The destination array dst
must have the same indices as the source A
(that is, axes(dst) == axes(A)
). If dst
is not specified or if dst
is A
, the operation is performed in-place.
Examples
The in-place morphological erosion (local minimum) of the array A
on a centered structuring element of width 7 in every dimension can be applied by:
localfilter!(A, :, min, -3:3)
Index interval 0
may be specified to do nothing along the corresponding dimension. For instance, assuming A
is a three-dimensional array:
localfilter!(A, :, max, (-3:3, 0, -4:4))
overwrites A
by its morphological dilation (i.e. local maximum) in a centered local neighborhood of size 7×1×9
(nothing is done along the second dimension). The same result may be obtained with:
localfilter!(A, (1,3), max, (-3:3, -4:4))
where the second dimension is omitted from the list of dimensions.
The local average of the two-dimensional array A
on a centered moving window of size 11×11 can be computed as:
localfilter(A, :, +, (-5:5, -5:5))*(1/11)
Efficiency and restrictions
The van Herk-Gil-Werman algorithm is very fast for rectangular structuring elements. It takes at most 3 operations to filter an element along a given dimension whatever the width p
of the considered local neighborhood. For N
-dimensional arrays, the algorithm requires only 3N
operations per element instead of p^N - 1
operations for a naive implementation. This however requires to make a pass along each dimension so memory page faults may reduce the performances. This is somewhat attenuated by the fact that the algorithm can be applied in-place. For efficient multi-dimensional out-of-place filtering, it is recommended to make the first pass with a fresh destination array and then all other passes in-place on the destination array.
To apply the van Herk-Gil-Werman algorithm, the structuring element must be separable along the dimensions and its components must be contiguous. In other words, the algorithm is only applicable for N
-dimensional rectangular neighborhoods, so-called hyperrectangles. The structuring element may however be off-centered by arbitrary offsets along each dimension.
To take into account boundary conditions (for now, only nearest neighbor is implemented) and allow for in-place operation, the algorithm allocates a workspace array.
References
Marcel van Herk, "A fast algorithm for local minimum and maximum filters on rectangular and octagonal kernels" in Pattern Recognition Letters 13, 517-521 (1992).
Joseph Gil and Michael Werman, "Computing 2-D Min, Median, and Max Filters" in IEEE Transactions on Pattern Analysis and Machine Intelligence 15, 504-507 (1993).