Ядра
Поддерживаемые ядра
Поддерживаются следующие ядра:
-
sobel
-
prewitt
-
ando3
,ando4
иando5
-
scharr
-
bickley
-
gaussian
-
DoG
(разность гауссианов) -
LoG
(лапласиан гауссиана) -
Laplacian
-
gabor
-
moffat
KernelFactors
— это модуль, реализующий разделяемые ядра фильтрации, каждое из которых хранится в виде множителей. Поддерживаются следующие ядра:
-
box
-
sobel
-
prewitt
-
ando3
,ando4
иando5
(последнее только в двухмерном варианте) -
scharr
-
bickley
-
gaussian
-
IIRGaussian
(приближенная гауссова фильтрация, выполняющаяся быстро даже при большом σ)
В модулях Kernel
и KernelFactors
реализованы популярные ядра корреляции в «плотной» и «разложенной» формах соответственно. Введите ?Kernel
или ?KernelFactors
в REPL, чтобы узнать, какие ядра поддерживаются.
Корреляция вместо свертки
Пакет ImageFiltering вычисляет отфильтрованное изображение F
на основе входного изображения A
и ядра K
по следующей формуле:
Поэтому итоговое изображение представляет собой корреляцию, а не свертку входного изображения и ядра. Если требуется свертка, сначала вызовите функцию reflect
для ядра.
Индексы ядра
ImageFiltering использует имеющуюся в Julia возможность определения массивов с индексами, охватывающими произвольный диапазон:
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
Индексы этого массива охватывают диапазон -2:2
по каждой оси, а центр гауссиана находится в позиции [0,0]
. Поэтому данный фильтр «размывает», но не «смещает» изображение; если бы вместо этого центр находился, скажем, в позиции [3,3]
, отфильтрованное изображение было бы смещено на 3 пикселя вниз и вправо относительно исходного.
Функция centered
полезна для преобразования обычного массива в массив с центром в позиции с координатами [0,0,...]
:
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
Дополнительные сведения см. в документации по OffsetArrays.
Разложенные ядра
Ключевой особенностью гауссовых, а также многих других часто используемых ядер является их разделяемость, то есть K[j_1,j_2,...]
можно записать как K_2[j_2] \cdots]. Как следствие, следующую корреляцию:
можно записать так:
Если ядро имеет размер m×n
, то первый вариант требует mn
операций для каждой точки filtered
, в то время как второй вариант требует m+n
операций. Это может давать существенную экономию, особенно при больших значениях m
и n
.
Для эффективного вычисления разделяемых ядер imfilter
принимает кортеж ядер: изображение фильтруется по каждому из них по очереди. Вы можете предоставить m×1
и 1×n
фильтров напрямую или вызвать kernelfactors
для кортежа векторов (что будет немного эффективнее):
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
Если ядро представляет собой двухмерный массив, imfilter
попытается разложить его; в случае успеха будет использоваться разделяемый алгоритм. Чтобы избежать автоматического разложения, передайте ядро в виде кортежа, например (kernp,)
.