Awesome
LocalFilters.jl
Julia package LocalFilters
implements
multi-dimensional local filters such as discrete convolution or correlation,
local mean, mathematical morphology, etc., and provides support to build custom
local filters.
The Reference Manual provides more exhaustive documentation.
This page summarizes the principles and the features of LocalFilters
. This
document is structured as follows:
-
Available filters lists ready to use filters.
-
Neighborhoods describes the concept of neighborhoods, also known as sliding windows in image processing or structuring element in mathematical morphology.
-
Build your own filters explains how to implement custom local filters.
-
Installation gives instructions to install the package.
Packages with overlapping functionalities:
-
ImageFiltering for local filters on multidimensional arrays (not just images), also implement various boundary conditions;
-
ImageMorphology for fast morphological operations with separable structuring elements;
Available filters
LocalFilters
provides a number of linear and non-linear filters. All methods
have an in-place counterpart which can be called to avoid allocations.
Linear filters
LocalFilters
provides the following linear filters:
-
localmean(A,B=3)
performs a local averaging ofA
in a neighborhood defined byB
. -
correlate(A,B)
performs a discrete correlation ofA
by the kernelB
. This is the most general linear filter. -
convolve(A,B)
performs a discrete convolution ofA
by the kernelB
. This is the same as a discrete correlation ofA
by the symmetrical ofB
.
Mathematical morphology
LocalFilters
implements the following mathematical
morphology operations:
-
erode(A,B=3)
performs an erosion (local minimum) ofA
by the structuring elementB
; -
dilate(A,B=3)
performs a dilation (local maximum) ofA
by the structuring elementB
; -
localextrema(A,B=3)
yields the erosion and the dilation ofA
by the structuring elementB
; -
opening(A,B=3)
performs an erosion followed by a dilation ofA
by the structuring elementB
; -
closing(A,B=3)
performs a dilation followed by an erosion ofA
by the structuring elementB
; -
top_hat(A,B=3[,S])
performs a summit detection ofA
by the structuring elementB
(argumentS
may be optionally supplied to pre-smoothA
byS
); -
bottom_hat(A,B=3[,S])
performs a valley detection ofA
by the structuring elementB
(argumentS
may be optionally supplied to pre-smoothA
byS
).
In mathematical morphology, the structuring element B
defines the local
neighborhood of each index in the source array. It can be a sliding
hyper-rectangular Cartesian window or an array of Booleans to define a more
complex neighborhood shape. If B
is a single odd integer (as it is by
default), the structuring element is assumed to be a sliding window of size B
along every dimension of A
.
Other non-linear filters
LocalFilters
provides an instance of the bilateral
filter:
bilateralfilter(A,F,G,B)
performs a bilateral filtering of arrayA
withF
the range kernel for smoothing differences in values,G
the spatial kernel for smoothing differences in coordinates, andB
the neighborhood. Alternatively one can specify the range and spatial parametersbilateralfilter(A,σr,σs,B=2*round(Int,3σs)+1)
for using Gaussian kernels with standard deviationsσr
andσs
.
Build your own filters
In LocalFilters
, a local filtering operation, say dst = filter(A, B)
with
A
the source of the operation and B
the neighborhood or the kernel
associated with the filter, is implemented by the following pseudo-code:
for i ∈ indices(dst)
v = initial isa Function ? initial(A[i]) : 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 Cartesian indices for multi-dimensional arrays, thus indices(A)
is the
analogous of CartesianIndices(A)
in Julia in that case. For vectors, indices
i
and j
are linear indices.
The behavior of the filter is completely determined by the neighborhood or
kernel B
, by the type of the state variable v
initialized by initial
for
each entry of the destination, and by the methods update
and final
.
Such a filter can be applied by calling localfilter!
as:
localfilter!(dst, A, B, initial, update, final = identity) -> dst
As shown by the following examples, this simple scheme allows the implementation of a variety of linear and non-linear local filters:
-
Implementing a local average of
A
in a neighborhood defined by an arrayB
of Booleans is done with:localfilter!(dst, A, B, #= initial =# (; num = zero(a), den = 0), #= update =# (v,a,b) -> ifelse(b, (; num = v.num + a, den = v.den + 1), v), #= final =# (v) -> v.num / v.den)
-
Assuming
T = eltype(dst)
is a suitable element type for the result, a discrete correlation ofA
byB
can be implemented with:localfilter!(dst, A, B, #= initial =# zero(T), #= update =# (v,a,b) -> v + a*b)
There are no needs to specify the
final
method here, as the defaultfinal = identity
, does the job. -
Computing a local maximum (that is, a dilation in mathematical morphology terms) of array
A
with a kernelB
whose entries are Booleans can be done with:localfilter!(dst, A, B, #= initial =# typemin(a), #= update =# (v,a,b) -> ((b & (v < a)) ? a : v))
As in the above example, there are no needs to specify the
final
method here. Note the use of a bitwise&
instead of a&&
in theupdate
method to avoid branching.
Installation
To install the last official version, press the ]
key to enter Julia's Pkg
REPL mode and type:
add LocalFilters
at the ... pkg>
prompt.
The LocalFilters
package is pure Julia code and nothing has to be build.