Ядра
Поддерживаемые ядра
Поддерживаются следующие ядра:
-
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,).