LocalFilters.jl
Julia package LocalFilters
implements
multidimensional local filters such as discrete convolution, local mean,
mathematical morphology, etc., and provides support to build custom local
filters.
This page summarizes the principles and the features of LocalFilters
, the
Reference Manual provides more exhaustive documentation. 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 nonlinear filters. All methods
have an inplace 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 presmoothA
byS
); 
bottom_hat(A,B=3[,S])
performs a valley detection ofA
by the structuring elementB
(argumentS
may be optionally supplied to presmoothA
byS
).
In mathematical morphology, the structuring element B
defines the local
neighborhood of each index in the source array. It can be a sliding
hyperrectangular 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 nonlinear 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 pseudocode:
for i ∈ indices(dst)
v = initial
for j ∈ indices(A) ∩ (indices(B) + i)
v = update(v, A[j], B[ji])
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[ji]
are inbounds. In LocalFilters
, indices i
and j
are multidimensional Cartesian indices, thus indices(A)
is the analogous of
CartesianIndices(A)
in Julia.
The behavior of the filter is completely determined by the neighborhood or
kernel B
, by the type of the state variable v
, its initial
value 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 nonlinear local filters:

Implementing a local average of
A
in a neighborhood defined by an arrayB
of booleans is done with:localfilter!(dst, A, B, (zero(a), 0), # initial, state = (sum_of_values, count_of_values) (v,a,b) > ifelse(b, (v[1] + a, v[2] + 1), v), # update (v) > v[1]/v[2]) # final

Assuming
T = eltype(dst)
is a suitable element type for the result, a discrete convolution ofA
byB
can be implemented with:localfilter!(dst, A, B, zero(T), # initial (v,a,b) > v + a*b) # update
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, typemin(a), # initial (v,a,b) > ((b & (v < a)) ? a : v)) # update
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:
using Pkg
pkg"add LocalFilters"
To use the last development version, install with Pkg, the Julia package manager, as an unregistered Julia package (press the ] key to enter the Pkg REPL mode):
using Pkg
pkg"add https://github.com/emmt/LocalFilters.jl"
The LocalFilters
package is pure Julia code and nothing has to be build.