Generic local filters
Most filters provided by the LocalFilters
package are implemented by the generic localfilter!
method.
The localfilter!
method
A local filtering operation can be performed by calling the localfilter!
method as follows:
localfilter!(dst, A, B, initial, update, final = identity) -> dst
where dst
is the destination, A
is the source, B
defines the neighborhood, initial
gives the initial value of the state variable, update
is a function to update the state variable for each entry of the neighborhood, and final
is a function to yield the local result of the filter given the final value of the state variable. The purposes of these parameters are explained by the following pseudo-code implementing the local filtering:
@inbounds for i ∈ indices(dst)
v = initial
for j ∈ indices(A) ∩ (indices(B) + i)
v = update(v, A[j], B[j-i])
end
dst[i] = final(v)
end
where indices(A)
denotes the set of indices of A
while indices(B) + i
denotes the set of indices j
such that j - i ∈ indices(B)
with indices(B)
the set of indices of B
. In other words, j ∈ indices(A) ∩ (indices(B) + i)
means all indices j
such that j ∈ indices(A)
and j - i ∈ indices(B)
, hence A[j]
and B[j-i]
are in-bounds. In LocalFilters
, indices i
and j
are multi-dimensional Cartesian indices, thus indices(A)
is the analogous of CartesianIndices(A)
in Julia.
The behavior of the filter is fully determined by the neighborhood B
(see Section Neighborhoods, structuring elements, and kernels), by the type and initial value of the state variable v
, and by the methods:
update(v, a, b)
which yields the updated state variablev
given the state variablev
,a = A[j]
, andb = B[j-i]
;final(v)
which yields the result of the filter given the state variablev
.
Examples
For example, implementing a local minimum filter (that is, an erosion), is as simple as:
localfilter!(dst, A, B, typemax(a),
(v,a,b) -> min(v,a),
(d,i,v) -> @inbounds(d[i] = v))
This is typically how mathematical morphology methods are implemented in LocalFilters
.
As another example, implementing a convolution by B
writes:
localfilter!(dst, A, B,
(a) -> zero(a),
(v,a,b) -> v + a*b)
Apart from specializations to account for the type of neighborhood defined by B
, it is essentially the way the convolve
and convolve!
methods (described in the Section Linear filters) are implemented in LocalFilters
.