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;
LocalFilters provides a number of linear and non-linear filters. All methods
have an in-place counterpart which can be called to avoid allocations.
LocalFilters provides the following linear filters:
-
localmean(A,B=3)performs a local averaging ofAin a neighborhood defined byB. -
correlate(A,B)performs a discrete correlation ofAby the kernelB. This is the most general linear filter. -
convolve(A,B)performs a discrete convolution ofAby the kernelB. This is the same as a discrete correlation ofAby the symmetrical ofB.
LocalFilters implements the following mathematical
morphology operations:
-
erode(A,B=3)performs an erosion (local minimum) ofAby the structuring elementB; -
dilate(A,B=3)performs a dilation (local maximum) ofAby the structuring elementB; -
localextrema(A,B=3)yields the erosion and the dilation ofAby the structuring elementB; -
opening(A,B=3)performs an erosion followed by a dilation ofAby the structuring elementB; -
closing(A,B=3)performs a dilation followed by an erosion ofAby the structuring elementB; -
top_hat(A,B=3[,S])performs a summit detection ofAby the structuring elementB(argumentSmay be optionally supplied to pre-smoothAbyS); -
bottom_hat(A,B=3[,S])performs a valley detection ofAby the structuring elementB(argumentSmay be optionally supplied to pre-smoothAbyS).
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.
LocalFilters provides an instance of the bilateral
filter:
bilateralfilter(A,F,G,B)performs a bilateral filtering of arrayAwithFthe range kernel for smoothing differences in values,Gthe spatial kernel for smoothing differences in coordinates, andBthe 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σrandσs.
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)
endwhere 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) -> dstAs 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
Ain a neighborhood defined by an arrayBof 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 ofAbyBcan be implemented with:localfilter!(dst, A, B, #= initial =# zero(T), #= update =# (v,a,b) -> v + a*b)
There are no needs to specify the
finalmethod here, as the defaultfinal = identity, does the job. -
Computing a local maximum (that is, a dilation in mathematical morphology terms) of array
Awith a kernelBwhose 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
finalmethod here. Note the use of a bitwise&instead of a&&in theupdatemethod to avoid branching.
To install the last official version, press the ] key to enter Julia's Pkg
REPL mode and type:
add LocalFiltersat the ... pkg> prompt.
The LocalFilters package is pure Julia code and nothing has to be build.