-
In
localfilter!
, argumentinitial
may be a function to compute the state variable from the value of the source array at the current destination index. This imposes that the source and destination arrays have the same axes. This fixes issue#3. -
localmean
andlocalmean!
accept anull
keyword to specify the value of the result when the sum of weights in a neighborhood is zero. -
The algorithm to infer the result type is now based on Julia's arithmetic rules and can cope with arguments that have units.
-
To represent hyper-rectangular neighborhoods, instances of non-exported
LocalFilters.Box
have been replaced by fast uniform arrays with offset axes from theStructuredArrays
package.LocalFilters.Box{N}
is now an alias toFastUniformArray{Boll,N,true}
. -
Exported method
reverse_kernel
yields a reversed kernel such that correlation byreverse_kernel(B)
is identical to convolution byB
. -
Constants for filter ordering follow more general naming rules:
FORWARD_FILTER
andREVERSE_FILTER
instead ofForwardFilter
andReverseFilter
.
Version 2 of LocalFilters
better integrates in the Julia ecosystem as fewer
custom types are introduced:
-
To represent hyper-rectangular Cartesian sliding windows, former type
RectangularBox
has been replaced byCartesianIndices
. -
Kernels with values or neighborhoods with more complex shape than hyper-rectangular Cartesian sliding windows are all represented by abstract arrays (with boolean entries to define a neighborhood). The former type
LocalFilters.Kernel
is no longer provided. To account for offsets in the indexing, it is recommended to use theOffsetArrays
package. The methodLocalFilters.centered(B)
can be called to yield a kernel or a neighborhood whose index ranges are approximately centered. This method is not exported to avoid conflicts (for instance, it has a slightly different semantic inOffsetArrays
).
Version 2 of LocalFilters
provides more general, more consistent, and better
optimized methods:
-
Most filtering operations take an optional ordering argument
ord
right before the argument, sayB
, specifying the kernel or the neighborhood. Iford
isForwardFilter
,B
is indexed as in discrete correlations; otherwise, iford
isReverseFilter
,B
is indexed as in discrete convolutions. The default ordering isForwardFilter
as this is the most natural for many filters (except discrete convolutions of course) and as it yields faster code. For symmetric kernels and neighborhoods, the ordering has no incidence on the result. InLocalFilters
version 1, indexing as in discrete convolutions was the only rule. -
The API of
localfilters!
have changed a bit, the syntax islocalfilters!(dst,A,ord=ForwardFilter,B,initial,update,final=identity)
withdst
the destination,A
the source,ord
the direction of the filter,B
the kernel or neighborhood of the filter,initial
the value of the initial state variable,update
a method to update the state variable, andfinal
a method to yield the result to store in the destinationdst
given the value of the state variable at the end of visiting the neighborhood. -
Constructor
LocalFilters.Indices
and helper methodLocalFilters.localindices
may be used as an alternative tolocalfilters!
to build custom filters. -
In all filters, a simple neighborhood that is a hyper-rectangular Cartesian sliding window can be specified in many different ways. Such a neighborhood is represented by an instance of
CartesianIndices
with unit step ranges. MethodLocalFilters.kernel(Dims{N},args...)
can be called to build such aN
-dimensional neighborhood from argument(s)args...
. -
Non-exported
LocalFilters.ball
method is now type stable. CallLocalFilters.ball(Dims{N},r)
instead ofLocalFilters.ball(N,r)
. -
The
strel
method uses uniform arrays from packageStructuredArrays
to represent structuring elements with the same value for all valid indices. -
In out-of-place filters, the destination array needs not be of the same size as the source array. The local filtering operation is applied for all indices of the destination, using boundary conditions to extract the corresponding value in the source array. Currently only flat boundary conditions are implemented but this may change in the future.
If the high level API was used, there should be almost no changes, except for
non-symmetric kernels or neighborhoods for which ReverseFilter
ordering must
be specified to mimic the former behavior.
At a lower level, the following changes should be done:
-
Non-exported union
LocalFilters.IndexInterval
has been replaced byLocalFilters.Axis
to represent the type of any argument that can be used to define a sliding window axis: an integer length or an integer-valued index range. -
Non-exported method
LocalFilters.ismmbox
has been replaced byLocalFilters.is_morpho_math_box
. -
Non-exported method
LocalFilters.cartesian_region
has been replaced by the more general and better designed exported methodkernel
. -
Replace
Neighborhood{N}(args...)
bykernel(Dims{N}, args...)
andNeighborhood{N}
orRectangularBox{N}
byLocalFilters.Box{N}
. -
Replace
LocalFilters.Kernel
byOffsetArrays.OffsetArray
. -
Update the arguments of
localfilters!
:initial
is no longer a method but the initial state value,update
has the same semantics, andfinal
just yields the result of the local filter given the last state value. By default,final
isidentity
. -
Replace
LocalFilters.ball(N,r)
byLocalFilters.ball(Dims{N},r)
which is type-stable.
-
Fix an important performance bug related to anonymous functions. Methods
localmean!
andconvolve!
are about 60 times faster! -
The documentation has been largely revised and on-line documentation is generated by
Documenter.jl
and hosted on https://emmt.github.io/LocalFilters.jl/.
- A default window of width
2*round(Int,3σ)+1
for the spatial filter in the bilateral filter if a Gaussian spatial filter of standard deviationσ
is chosen.
-
Scalar and array element type restrictions have been relaxed for most filter methods. This is to let users apply these methods to non-standard types.
-
Some optimizations.
-
Syntax
Kernel(T,G,B)
has been deprecated in favor ofKernel{T}(G,B)
. -
Rename unexported methods
initialindex
,finalindex
,defaultstart
,cartesianregion
,convertcoefs
, andstrictfloor
respectively asfirst_cartesian_index
andlast_cartesian_index
,default_start
,cartesianregion
,convert_coefs
, andstrictfloor
.
- Drop compatibility with Julia versions < 1.0;
Compat
only needed to run tests.
-
Compatibility with Julia 0.6 to 1.1
-
Add fast separable filters with the van Herk-Gil-Werman algorithm. This algorithm is applied whenever possible (for
RectangularBox
, or flatKernel
whose elements are all valid). -
New
strel
function to build structuring elements. -
The type of the result of operations like local mean and convolution is more consistent (e.g., local mean yields a floating-point type result). Rounding to the nearest integer is automatically used when the floating-point result of an operation is stored into a array of integers.
-
Constructors for
Kernel
basically takes two arguments: the array of coefficients, sayA
, and the initialCartesianIndex
for indexing the kernel. This simplify the interface, notably when the array of coefficientsA
has not 1-based indexing. -
Compatibility with Julia versions 0.6, 0.7 and 1.0 without loss of performances. This has been achieved thanks to the new
cartesianregion()
method (see below). -
The method
cartesianregion()
is provided to return either aCartesianIndices{N}
or aCartesianRange{CartesianIndex{N}}
(whichever is the most efficient depending on Julia version) to loop over theN
-dimensional indices of anything whose type belongs toCartesianRegion{N}
. TypeCartesianRegion{N}
is an union of the types of anything suitable to define a Cartesian region of indices. -
Methods
initialindex
andfinalindex
are provided to retrieve the first and lastCartesianIndex
for indexing their argument. -
Types
CartesianBox
andCenteredBox
have been merged in a single type namedRectangularBox
(to avoid conflicts with the CartesianBoxes package). Hence,Neighborhood
has two concrete subtypes:RectangularBox
andKernel
. -
Method
anchor
has been removed because its result depends on the indexing of the embedded array of kernel coefficients. -
Add bilateral filter.