Kernels
Supported kernels
The following kernels are supported:
-
sobel
-
prewitt
-
ando3
,ando4
, andando5
-
scharr
-
bickley
-
gaussian
-
DoG
(Difference-of-Gaussian) -
LoG
(Laplacian-of-Gaussian) -
Laplacian
-
gabor
-
moffat
KernelFactors
is a module implementing separable filtering kernels, each stored in terms of their factors. The following kernels are supported:
-
box
-
sobel
-
prewitt
-
ando3
,ando4
, andando5
(the latter in 2d only) -
scharr
-
bickley
-
gaussian
-
IIRGaussian
(approximate gaussian filtering, fast even for large σ)
The two modules Kernel
and KernelFactors
implement popular correlation kernels in "dense" and "factored" forms, respectively. Type ?Kernel
or ?KernelFactors
at the REPL to see which kernels are supported.
Correlation, not convolution
The ImageFiltering package uses the following formula to calculate the filtered image F
from an input image A
and kernel K
:
Consequently, the resulting image is the correlation, not convolution, of the input and the kernel. If you want the convolution, first call reflect
on the kernel.
Kernel indices
ImageFiltering exploits Julia’s ability to define arrays whose indices span an arbitrary range:
julia> Kernel.gaussian(1)
OffsetArray{Float64,2,Array{Float64,2}} with indices -2:2×-2:2:
0.00296902 0.0133062 0.0219382 0.0133062 0.00296902
0.0133062 0.0596343 0.0983203 0.0596343 0.0133062
0.0219382 0.0983203 0.162103 0.0983203 0.0219382
0.0133062 0.0596343 0.0983203 0.0596343 0.0133062
0.00296902 0.0133062 0.0219382 0.0133062 0.00296902
The indices of this array span the range -2:2
along each axis, and the center of the gaussian is at position [0,0]
. As a consequence, this filter "blurs" but does not "shift" the image; were the center instead at, say, [3,3]
, the filtered image would be shifted by 3 pixels downward and to the right compared to the original.
The centered
function is a handy utility for converting an ordinary array to one that has coordinates [0,0,...]
at its center position:
julia> centered([1 0 1; 0 1 0; 1 0 1])
OffsetArray{Int64,2,Array{Int64,2}} with indices -1:1×-1:1:
1 0 1
0 1 0
1 0 1
See OffsetArrays for more information.
Factored kernels
A key feature of Gaussian kernels---along with many other commonly-used kernels---is that they are separable, meaning that K[j_1,j_2,...]
can be written as K_2[j_2] \cdots]. As a consequence, the correlation:
can be written:
If the kernel is of size m×n
, then the upper version line requires mn
operations for each point of filtered
, whereas the lower version requires m+n
operations. Especially when m
and n
are larger, this can result in a substantial savings.
To enable efficient computation for separable kernels, imfilter
accepts a tuple of kernels, filtering the image by each sequentially. You can either supply m×1
and 1×n
filters directly, or (somewhat more efficiently) call kernelfactors
on a tuple-of-vectors:
julia> kern1 = centered([1/3, 1/3, 1/3])
OffsetArray{Float64,1,Array{Float64,1}} with indices -1:1:
0.333333
0.333333
0.333333
julia> kernf = kernelfactors((kern1, kern1))
(ImageFiltering.KernelFactors.ReshapedOneD{Float64,2,0,OffsetArray{Float64,1,Array{Float64,1}}}([0.333333,0.333333,0.333333]),ImageFiltering.KernelFactors.ReshapedOneD{Float64,2,1,OffsetArray{Float64,1,Array{Float64,1}}}([0.333333,0.333333,0.333333]))
julia> kernp = broadcast(*, kernf...)
OffsetArray{Float64,2,Array{Float64,2}} with indices -1:1×-1:1:
0.111111 0.111111 0.111111
0.111111 0.111111 0.111111
0.111111 0.111111 0.111111
julia> imfilter(img, kernf) ≈ imfilter(img, kernp)
true
If the kernel is a two dimensional array, imfilter
will attempt to factor it; if successful, it will use the separable algorithm. You can prevent this automatic factorization by passing the kernel as a tuple, e.g., as (kernp,)
.