Сводка и справка по функциям
Ниже квадратные скобки []
в списке аргументов означают необязательный аргумент.
Загрузка и сохранение изображений
FileIO.jl — это интерфейс ввода-вывода, который предоставляет функции save
и load
для легкой загрузки изображений. В настоящее время для файлов изображений доступны следующие бэкенды.
-
ImageMagick.jl охватывает большинство форматов изображений и имеет дополнительные возможности. Его можно выбрать первым, если у вас нет особых предпочтений.
-
QuartzImageIO.jl делает доступными собственные функции ввода-вывода изображений macOS в Julia. В некоторых случаях он быстрее, чем ImageMagick, но может удовлетворять не все потребности.
-
ImageIO.jl — это новый бэкенд ввода-вывода изображений (требуется Julia версии не ниже 1.3), который обеспечивает повышенную производительность для файлов PNG. Результат тестов производительности см. здесь.
-
OMETIFF.jl поддерживает файлы OME-TIFF. Если вы не знаете, что это такое, то, скорее всего, этот пакет вам не нужен.
Стандартные тестовые изображения доступны в пакете TestImages.jl
#
FileIO.load
— Function
-
load(filename)
загружает содержимое форматированного файла, пытаясь вывести формат изfilename
и (или) магических байтов в файле (см. описание функцииquery
). -
load(strm)
загружает данные изIOStream
или аналогичного объекта. В данном случае расширения имени файла нет, поэтому формат распознается на основе магических байтов. -
load(File{format"PNG"}(filename))
задает формат напрямую; формат изquery
игнорируется. -
load(Stream{format"PNG"}(io))
задает формат напрямую; формат изquery
игнорируется. -
load(f; options...)
передает именованные аргументы в метод загрузки.
#
FileIO.save
— Function
-
save(filename, data...)
сохраняет содержимое форматированного файла, пытаясь вывести формат изfilename
. -
save(Stream{format"PNG"}(io), data...)
задает формат напрямую; формат изquery
игнорируется. -
save(File{format"PNG"}(filename), data...)
задает формат напрямую; формат изquery
игнорируется. -
save(f, data...; options...)
передает именованные аргументы в метод сохранения.
#
TestImages.testimage
— Function
img = testimage(filename; download_only=false, [ops...])
Загружает тестовое изображение, которое частично совпадает с filename
; если совпадений несколько, используется первое из них.
При download_only=true
возвращается полный путь к файлу. Остальные именованные аргументы ops
передаются в бэкенд ввода-вывода изображений посредством FileIO.load
.
Пример
julia> using TestImages
julia> img = testimage("cameraman.tif"); # полное имя
julia> img = testimage("cameraman"); # без расширения работает
julia> img = testimage("c"); # с частью имени тоже работает
Расширенная справка
Ниже приведен полный список тестовых изображений. Он также доступен на странице https://testimages.juliaimages.org/.
-
"airplaneF16"
-
"autumn_leaves"
-
"barbara_color"
-
"barbara_gray_512"
-
"bark_512"
-
"bark_he_512"
-
"beach_sand_512"
-
"beach_sand_he_512"
-
"blobs"
-
"brick_wall_512"
-
"brick_wall_he_512"
-
"calf_leather_512"
-
"calf_leather_he_512"
-
"cameraman"
-
"chelsea"
-
"coffee"
-
"earth_apollo17"
-
"fabio_color_256"
-
"fabio_color_512"
-
"fabio_gray_256"
-
"fabio_gray_512"
-
"grass_512"
-
"grass_he_512"
-
"hela-cells"
-
"herringbone_weave_512"
-
"herringbone_weave_he_512"
-
"house"
-
"jetplane"
-
"lake_color"
-
"lake_gray"
-
"lena_color_256"
-
"lena_color_512"
-
"lena_gray_16bit"
-
"lena_gray_256"
-
"lena_gray_512"
-
"lighthouse"
-
"lilly"
-
"livingroom"
-
"m51"
-
"mandril_color"
-
"mandril_gray"
-
"mandrill"
-
"monarch_color"
-
"monarch_color_256"
-
"moonsurface"
-
"morphology_test_512"
-
"mountainstream"
-
"mri-stack"
-
"multi-channel-time-series.ome"
-
"peppers_color"
-
"peppers_gray"
-
"pigskin_512"
-
"pigskin_he_512"
-
"pirate"
-
"plastic_bubbles_512"
-
"plastic_bubbles_he_512"
-
"raffia_512"
-
"raffia_he_512"
-
"resolution_test_1920"
-
"resolution_test_512"
-
"simple_3d_ball"
-
"simple_3d_psf"
-
"straw_512"
-
"straw_he_512"
-
"sudoku"
-
"toucan"
-
"walkbridge"
-
"water_512"
-
"water_he_512"
-
"woman_blonde"
-
"woman_darkhair"
-
"wood_grain_512"
-
"wood_grain_he_512"
-
"woolen_cloth_512"
-
"woolen_cloth_he_512"
#
Images.shepp_logan
— Function
phantom = shepp_logan(N,[M]; highContrast=true)
output the NxM Shepp-Logan phantom, which is a standard test image usually used for comparing image reconstruction algorithms in the field of computed tomography (CT) and magnetic resonance imaging (MRI). If the argument M is omitted, the phantom is of size NxN. When setting the keyword argument highConstrast
to false, the CT version of the phantom is created. Otherwise, the high contrast MRI version is calculated.
Создание, преобразование и представления изображений
Любой массив можно рассматривать как изображение. В графических средах только массивы с типами элементов Colorant
(Gray
, RGB
, ARGB
и т. д.) автоматически отображаются как изображения.
#
ImageCore.colorview
— Function
colorview(C, A)
Возвращает представление числового массива A
, интерпретируя последовательные элементы A
как каналы цвета C
.
Для таких типов, как RGB и BGR, элементы A
интерпретируются в порядке следования аргументов конструктора, а не в порядке размещения в памяти (если требуется порядок размещения в памяти, см. reinterpretc
).
Пример
A = rand(3, 10, 10)
img = colorview(RGB, A)
См. также описание channelview
.
colorview(C, gray1, gray2, ...) -> imgC
Объединяет числовые изображения или изображения в оттенках серого gray1
, gray2
и т. д. в отдельные цветовые каналы массива imgC
с типом элементов C<:Colorant
.
Для удобства есть константа zeroarray
, которая заполняет массив соответствующего размера нулями.
Пример
imgC = colorview(RGB, r, zeroarray, b)
Создает изображение с r
в красном канале и b
в синем канале; зеленый канал не заполняется.
См. также описание типа StackedView
.
colorview(C)
Создает функцию, эквивалентную (As...) -> colorview(C, Ax...)
.
Примеры
julia> ones(Float32, 2, 2) |> colorview(Gray)
2×2 reinterpret(reshape, Gray{Float32}, ::Matrix{Float32}) with eltype Gray{Float32}:
Gray{Float32}(1.0) Gray{Float32}(1.0)
Gray{Float32}(1.0) Gray{Float32}(1.0)
Это может быть довольно удобно, если нужно преобразовать пакет данных каналов, например:
julia> Rs, Gs, Bs = ntuple( i -> [randn(2, 2) for _ in 1:4], 3)
julia> map(colorview(RGB), Rs, Gs, Bs)
#
ImageCore.channelview
— Function
channelview(A)
Возвращает представление массива A
, разделяя (при необходимости) цветовые каналы A
и помещая их в новое первое измерение.
Для таких типов, как RGB и BGR, каналы возвращаемого массива следуют в порядке аргументов конструктора, а не в порядке размещения в памяти (если требуется порядок размещения в памяти, см. reinterpretc
).
Пример
img = rand(RGB{N0f8}, 10, 10)
A = channelview(img) # массив 3×10×10
См. также описание colorview
.
#
ImageCore.normedview
— Function
normedview([T], img::AbstractArray{Unsigned})
Возвращает «представление» изображения img
, интерпретируя значения как числовые типы Normed
. Например, если img
— это Array{UInt8}
, представление будет работать как Array{N0f8}
. Если тип элементов img
— UInt16
, укажите в T
нужный тип результата: N6f10
, N4f12
, N2f14
или N0f16
.
См. также описание rawview
.
#
ImageCore.rawview
— Function
rawview(img::AbstractArray{FixedPoint})
Возвращает «представление» изображения img
, интерпретируя значения как базовый тип хранения. Например, если img
— это Array{N0f8}
, представление будет работать как Array{UInt8}
.
См. также описание normedview
.
#
ImageCore.StackedView
— Type
StackedView(B, C, ...) -> A
Представляет массивы B
, C
и т. д. как отдельные каналы по первому измерению A
. В частности,
B == A[1,:,:...] C == A[2,:,:...]
и т. д. В сочетании с colorview
позволяет объединять два или более изображений в оттенках серого в одно цветное.
См. также описание функции colorview
.
#
PaddedViews.PaddedView
— Type
datapadded = PaddedView(fillvalue, data, padded_axes)
datapadded = PaddedView(fillvalue, data, padded_axes, data_axes)
datapadded = PaddedView(fillvalue, data, sz)
datapadded = PaddedView(fillvalue, data, sz, first_datum)
datapadded = PaddedView{T}(args...)
Создает дополненную версию массива data
, где все элементы в пределах padded_axes
, которым не присвоено значение в data
, будут иметь значение fillvalue
.
В data_axes
можно указать другой набор осей для data
, таким образом переместив data
в другой набор индексов. Это краткая форма записи для
offsetdata = OffsetArray(data, data_axes) datapadded = PaddedView(fillvalue, offsetdata, padded_axes)
с использованием пакета OffsetArrays.
Можно также указать размер дополненного массива sz
; в этом случае индексирование datapadded
начинается с 1. При желании можно указать позицию элемента [1, 1, ...]
в data
с помощью first_datum
. В частности, datapadded[first_datum...]
соответствует data[1, 1, ...]
. По умолчанию все значения first_datum
равны 1.
Тип элементов T
представления необязателен. Если он не указан, то в большинстве случаев T
выводится как eltype(data)
. В случаях, когда fillvalue
невозможно преобразовать в eltype(data)
, T
продвигается до типа, поддерживающего такое преобразование. Например, при fillvalue == nothing
и eltype(data) == Float32
тип элементов T
выводится как Union{Nothing, Float32}
.
Пример
julia> using PaddedViews
julia> a = collect(reshape(1:9, 3, 3))
3×3 Matrix{Int64}:
1 4 7
2 5 8
3 6 9
julia> PaddedView(-1, a, (4, 5))
4×5 PaddedView(-1, ::Matrix{Int64}, (Base.OneTo(4), Base.OneTo(5))) with eltype Int64:
1 4 7 -1 -1
2 5 8 -1 -1
3 6 9 -1 -1
-1 -1 -1 -1 -1
julia> PaddedView(-1, a, (1:5,1:5), (2:4,2:4))
5×5 PaddedView(-1, OffsetArray(::Matrix{Int64}, 2:4, 2:4), (1:5, 1:5)) with eltype Int64 with indices 1:5×1:5:
-1 -1 -1 -1 -1
-1 1 4 7 -1
-1 2 5 8 -1
-1 3 6 9 -1
-1 -1 -1 -1 -1
julia> PaddedView(-1, a, (0:4, 0:4))
5×5 PaddedView(-1, ::Matrix{Int64}, (0:4, 0:4)) with eltype Int64 with indices 0:4×0:4:
-1 -1 -1 -1 -1
-1 1 4 7 -1
-1 2 5 8 -1
-1 3 6 9 -1
-1 -1 -1 -1 -1
julia> PaddedView(-1, a, (5,5), (2,2))
5×5 PaddedView(-1, OffsetArray(::Matrix{Int64}, 2:4, 2:4), (Base.OneTo(5), Base.OneTo(5))) with eltype Int64:
-1 -1 -1 -1 -1
-1 1 4 7 -1
-1 2 5 8 -1
-1 3 6 9 -1
-1 -1 -1 -1 -1
#
PaddedViews.paddedviews
— Function
Aspad = paddedviews(fillvalue, A1, A2, ...; [dims])
Дополняет массивы A1
, A2
и т. д. до общего размера или набора осей, выбранных в качестве диапазона осей, охватывающих все входные массивы.
Дополнение применяется в одном направлении в измерениях dims
. Например, в двухмерном случае значения заполняются в направлении правого нижнего угла нового массива. Если дополнение должно производиться в обоих направлениях, используйте sym_paddedviews
.
Оси исходного массива A
сохраняются в дополненном результате Ap
, следовательно, верно равенство Ap[CartesianIndices(A)] == A
.
Пример:
julia> using PaddedViews
julia> a1 = reshape([1, 2, 3], 3, 1)
3×1 Matrix{Int64}:
1
2
3
julia> a2 = [4 5 6]
1×3 Matrix{Int64}:
4 5 6
julia> a1p, a2p = paddedviews(-1, a1, a2);
julia> a1p
3×3 PaddedView(-1, ::Matrix{Int64}, (Base.OneTo(3), Base.OneTo(3))) with eltype Int64:
1 -1 -1
2 -1 -1
3 -1 -1
julia> a2p
3×3 PaddedView(-1, ::Matrix{Int64}, (Base.OneTo(3), Base.OneTo(3))) with eltype Int64:
4 5 6
-1 -1 -1
-1 -1 -1
julia> a1p[CartesianIndices(a1)]
3×1 Matrix{Int64}:
1
2
3
Именованный аргумент dims
позволяет дополнять только указанные измерения.
julia> a1 = reshape(collect(1:9), 3, 3)
3×3 Matrix{Int64}:
1 4 7
2 5 8
3 6 9
julia> a2 = [4 5;6 7]
2×2 Matrix{Int64}:
4 5
6 7
julia> a1f, a2f = paddedviews(-1, a1, a2; dims=1);
julia> a2f
3×2 PaddedView(-1, ::Matrix{Int64}, (Base.OneTo(3), Base.OneTo(2))) with eltype Int64:
4 5
6 7
-1 -1
julia> a1f, a2f = paddedviews(-1, a1, a2; dims=(1,2));
julia> a2f
3×3 PaddedView(-1, ::Matrix{Int64}, (Base.OneTo(3), Base.OneTo(3))) with eltype Int64:
4 5 -1
6 7 -1
-1 -1 -1
#
PaddedViews.sym_paddedviews
— Function
Aspad = sym_paddedviews(fillvalue, A1, A2, ...; [dims])
Дополняет массивы A1
, A2
и т. д. до общего размера или набора осей, выбранных в качестве диапазона осей, охватывающих все входные массивы.
Дополнение применяется в обоих направлениях в измерениях dims
, то есть исходный массив будет находиться в центре дополненного результата. Если дополнение должно производиться только в одном направлении, используйте paddedviews
.
Оси исходного массива A
сохраняются в дополненном результате Ap
, следовательно, верно равенство Ap[CartesianIndices(A)] == A
.
julia> using PaddedViews
julia> a1 = reshape([1, 2, 3], 3, 1)
3×1 Matrix{Int64}:
1
2
3
julia> a2 = [4 5 6]
1×3 Matrix{Int64}:
4 5 6
julia> a1p, a2p = sym_paddedviews(-1, a1, a2);
julia> a1p
3×3 PaddedView(-1, ::Matrix{Int64}, (1:3, 0:2)) with eltype Int64 with indices 1:3×0:2:
-1 1 -1
-1 2 -1
-1 3 -1
julia> a2p
3×3 PaddedView(-1, ::Matrix{Int64}, (0:2, 1:3)) with eltype Int64 with indices 0:2×1:3:
-1 -1 -1
4 5 6
-1 -1 -1
julia> a1p[CartesianIndices(a1)]
3×1 Matrix{Int64}:
1
2
3
Именованный аргумент dims
позволяет дополнять только указанные измерения.
julia> a1 = reshape(collect(1:9), 3, 3)
3×3 Matrix{Int64}:
1 4 7
2 5 8
3 6 9
julia> a2 = reshape([5, 6], 2, 1)
2×1 Matrix{Int64}:
5
6
julia> a1f, a2f = sym_paddedviews(-1, a1, a2; dims=1);
julia> a2f
3×1 PaddedView(-1, ::Matrix{Int64}, (1:3, 1:1)) with eltype Int64 with indices 1:3×1:1:
5
6
-1
julia> a1f, a2f = sym_paddedviews(-1, a1, a2; dims=(1,2));
julia> a2f
3×3 PaddedView(-1, ::Matrix{Int64}, (1:3, 0:2)) with eltype Int64 with indices 1:3×0:2:
-1 5 -1
-1 6 -1
-1 -1 -1
#
MosaicViews.MosaicView
— Type
MosaicView(A::AbstractArray)
Создает двухмерное «представление» трех- или четырехмерного массива A
. В итоговом представлении MosaicView
данные из A
отображаются так, словно эмулируется использование vcat
для всех элементов в третьем измерении A
и hcat
для всех элементов в четвертом измерении A
.
Например, если размер size(A)
равен (2,3,4)
, то итоговое представление MosaicView
будет иметь размер (2*4,3)
, то есть (8,3)
. Если же размер size(A)
равен (2,3,4,5)
, то итоговое представление будет иметь размер (2*4,3*5)
, то есть (8,15)
.
Это можно представить иначе так: MosaicView
создает мозаику из отдельных матриц, перечисленных в третьем (и, возможно, четвертом) измерении заданного трех- или четырехмерного массива A
. Это может быть особенно полезно для создания единого составного изображения из набора изображений одинакового размера.
julia> using MosaicViews
julia> A = [(k+1)*l-1 for i in 1:2, j in 1:3, k in 1:2, l in 1:2]
2×3×2×2 Array{Int64,4}:
[:, :, 1, 1] =
1 1 1
1 1 1
[:, :, 2, 1] =
2 2 2
2 2 2
[:, :, 1, 2] =
3 3 3
3 3 3
[:, :, 2, 2] =
5 5 5
5 5 5
julia> MosaicView(A)
4×6 MosaicViews.MosaicView{Int64,4,Array{Int64,4}}:
1 1 1 3 3 3
1 1 1 3 3 3
2 2 2 5 5 5
2 2 2 5 5 5
#
MosaicViews.mosaicview
— Function
mosaicview(A::AbstractArray;
[fillvalue=<zero unit>], [npad=0],
[nrow], [ncol], [rowmajor=false]) -> MosaicView
mosaicview(As::AbstractArray...; kwargs...)
mosaicview(As::Union{Tuple, AbstractVector}; kwargs...)
Создает двухмерное «представление» массива A
.
В итоговом представлении MosaicView
все срезы матриц первых двух измерений A
будут организованы в виде одной большой мозаики (в виде матрицы).
Аргументы
В отличие от использования конструктора MosaicView
напрямую, функция mosaicview
имеет несколько удобных именованных аргументов. Типичным применением является создание мозаики изображений из набора входных изображений.
-
Параметр
fillvalue
определяет значение, которое следует использовать для пустого пространства. Это может быть дополнение посредствомnpad
или пустые плитки мозаики в случае, если количество срезов матриц вA
меньшеnrow*ncol
. -
Параметр
npad
определяет пустое пространство дополнения между соседними плитками мозаики. Он может быть особенно полезен, если отдельные плитки (то есть срезы матриц вA
) представляют собой изображения, которые должны быть визуально разделены линиями сетки. -
С помощью параметров
nrow
иncol
можно выбрать количество плиток в ряду и (или) столбце для построения мозаики. Обратите внимание, что достаточно указать один из этих двух параметров, так как второй может быть выведен из него. Если не указан ни один из них, по умолчаниюnrow = size(A,3)
. -
Если
rowmajor
имеет значениеtrue
, то срезы будут размещаться слева направо сверху вниз, а не сверху вниз слева направо (по умолчанию). Схема размещения будет другой только в особых случаях, то есть когдаnrow != 1
иncol != 1
.
Эта функция не является устойчивой по типу, поэтому ее следует использовать только в том случае, если производительность не имеет первостепенного значения. Для оптимальной производительности объекты |
Примеры
Простейший вариант использования — применение cat
к двум массивам одинаковой размерности.
julia> A1 = fill(1, 3, 1)
3×1 Array{Int64,2}:
1
1
1
julia> A2 = fill(2, 1, 3)
1×3 Array{Int64,2}:
2 2 2
julia> mosaicview(A1, A2)
6×3 MosaicView{Int64,4, ...}:
0 1 0
0 1 0
0 1 0
0 0 0
2 2 2
0 0 0
julia> mosaicview(A1, A2; center=false)
6×3 MosaicView{Int64,4, ...}:
1 0 0
1 0 0
1 0 0
2 2 2
0 0 0
0 0 0
Для получения нужных результатов могут быть полезны и другие именованные аргументы.
julia> using MosaicViews
julia> A = [k for i in 1:2, j in 1:3, k in 1:5]
2×3×5 Array{Int64,3}:
[:, :, 1] =
1 1 1
1 1 1
[:, :, 2] =
2 2 2
2 2 2
[:, :, 3] =
3 3 3
3 3 3
[:, :, 4] =
4 4 4
4 4 4
[:, :, 5] =
5 5 5
5 5 5
julia> mosaicview(A, ncol=2)
6×6 MosaicViews.MosaicView{Int64,4,...}:
1 1 1 4 4 4
1 1 1 4 4 4
2 2 2 5 5 5
2 2 2 5 5 5
3 3 3 0 0 0
3 3 3 0 0 0
julia> mosaicview(A, nrow=2)
4×9 MosaicViews.MosaicView{Int64,4,...}:
1 1 1 3 3 3 5 5 5
1 1 1 3 3 3 5 5 5
2 2 2 4 4 4 0 0 0
2 2 2 4 4 4 0 0 0
julia> mosaicview(A, nrow=2, rowmajor=true)
4×9 MosaicViews.MosaicView{Int64,4,...}:
1 1 1 2 2 2 3 3 3
1 1 1 2 2 2 3 3 3
4 4 4 5 5 5 0 0 0
4 4 4 5 5 5 0 0 0
julia> mosaicview(A, nrow=2, npad=1, rowmajor=true)
5×11 MosaicViews.MosaicView{Int64,4,...}:
1 1 1 0 2 2 2 0 3 3 3
1 1 1 0 2 2 2 0 3 3 3
0 0 0 0 0 0 0 0 0 0 0
4 4 4 0 5 5 5 0 0 0 0
4 4 4 0 5 5 5 0 0 0 0
julia> mosaicview(A, fillvalue=-1, nrow=2, npad=1, rowmajor=true)
5×11 MosaicViews.MosaicView{Int64,4,...}:
1 1 1 -1 2 2 2 -1 3 3 3
1 1 1 -1 2 2 2 -1 3 3 3
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
4 4 4 -1 5 5 5 -1 -1 -1 -1
4 4 4 -1 5 5 5 -1 -1 -1 -1
#
ImageAxes.StreamingContainer
— Type
A = StreamingContainer{T}(f!, parent, streamingaxes::Axis...)
Объект наподобие массива с одной или несколькими осями, для которого изменение «срезов» может быть ограничено или связано с затратами. Каноническим примером может служить поток AVI, в котором обращение к пикселям в пределах одного кадра происходит быстро, но переход между кадрами может быть медленным.
Вот простой пример деления каждого среза изображения на среднее значение перед возвратом значений.
A = AxisArrays.AxisArray(reshape(1:36, 3, 3, 4)) function f!(buffer, slice) meanslice = mean(slice) buffer .= slice./meanslice end B = StreamingContainer{Float64}(f!, A, AxisArrays.axes(A)[3]) julia> A[:,:,1] 3×3 AxisArray{Int64,2,Array{Int64,2},Tuple{Axis{:row,Base.OneTo{Int64}},Axis{:col,Base.OneTo{Int64}}}}: 1 4 7 2 5 8 3 6 9 julia> B[:,:,1] 3×3 Array{Float64,2}: 0.2 0.8 1.4 0.4 1.0 1.6 0.6 1.2 1.8
Предоставленная пользователем функция f!
должна принимать аргументы:
f!(buffer, slice)
Здесь buffer
— это пустой массив, вмещающий срез ряда, а slice
содержит текущий входной срез.
Стоит отметить, что StreamingContainer
не является подтипом AbstractArray
, но поддерживается большая часть интерфейса массива (eltype
, ndims
, axes
, size
, getindex
и IndexStyle
). Объект StreamingContainer A
можно создать как из AxisArray, так и из других «родительских» объектов, даже не являющихся массивами, при условии что они поддерживают те же функции. В любом случае родительский объект также должен поддерживать стандартные функции AxisArray axes
, axisnames
, axisvalues
и axisdim
; эта поддержка будет распространяться на StreamingContainer
.
Кроме того, объект StreamingContainer A
поддерживает вызов
getindex!(dest, A, axt::Axis{:time}, ...)
для получения срезов по передаваемым осям (здесь предполагается, что :time
— это передаваемая ось A
). Вы можете реализовать это напрямую (путем диспетчеризации по параметрам A
) либо (если родительский элемент — это AbstractArray
) использовать резервное определение
A.getindex!(dest, view(parent, axs...))
где A.getindex! = f!
передается как аргумент при создании. dest
должно иметь размерность ndims(parent)-length(streamingaxes)
.
При необходимости определите StreamIndexStyle(typeof(parent),typeof(f!))
.
Изображения с определенной геометрией и значением осей можно построить с помощью пакета AxisArrays
:
using AxisArrays
img = AxisArray(A, (:y, :x, :time), (0.25μm, 0.25μm, 0.125s)) # единицы см. в Unitful.jl
Пользовательские метаданные можно добавить следующим образом.
img = ImageMeta(A, date=now(), patientID=12345)
Любые из этих операций можно комбинировать, например, если имеется массив m×n×3 UInt8
, его можно преобразовать в канонический формат RGB и добавить метаданные:
img = ImageMeta(colorview(RGB, normedview(PermutedDimsArray(A, (3,1,2)))), sample="control")
Типажи
Эти функции являются предпочтительным способом доступа к определенным типам «внутренних» данных об изображении. Иногда они могут быть полезны для написания универсального кода.
#
ImageCore.pixelspacing
— Function
pixelspacing(img) -> (sx, sy, ...)
Возвращает кортеж, представляющий расстояние между соседними пикселями по каждой оси изображения. По умолчанию (1,1,…). Используйте ImagesAxes для изображений с анизотропными интервалами или для кодирования интервала с использованием физических единиц.
#
ImageCore.spacedirections
— Function
spacedirections(img) -> (axis1, axis2, ...)
Возвращает кортеж кортежей, где каждый элемент axis[i]
представляет вектор смещения между соседними пикселями по пространственной оси i
массива изображения относительно некоторой внешней системы координат («физических»).
По умолчанию вычисляется на основе pixelspacing
, но можно задать и вручную с помощью ImagesMeta.
spacedirections(img)
При использовании ImageMetadata это свойство можно задать вручную. Например, указать, что фотография была сделана камерой, наклоненной на 30 градусов относительно вертикали, можно так:
img["spacedirections"] = ((0.866025,-0.5),(0.5,0.866025))
Если значение не указано, оно рассчитывается на основе pixelspacing(img)
, причем интервал задается по «диагонали». При необходимости можно задать это свойство в физических единицах, причем у каждой оси они могут быть своими.
#
ImageCore.sdims
— Function
sdims(img)
Возвращает количество пространственных измерений на изображении. По умолчанию результат тот же, что и у ndims
, но при использовании ImagesAxes можно указать, что некоторые оси соответствуют другим величинам (например, времени) и поэтому не учитываются sdims
.
#
ImageCore.coords_spatial
— Function
coords_spatial(img)
Возвращает кортеж с пространственными измерениями img
.
Обратите внимание, что более эффективной стратегией может быть использование ImagesAxes и создание срезов по оси времени.
#
ImageCore.size_spatial
— Function
size_spatial(img)
Возвращает кортеж с размерами пространственных измерений изображения. По умолчанию результат тот же, что и у size
, но при использовании ImagesAxes можно пометить некоторые оси как непространственные.
#
ImageCore.indices_spatial
— Function
indices_spatial(img)
Возвращает кортеж с индексами пространственных измерений изображения. По умолчанию результат тот же, что и у indices
, но при использовании ImagesAxes можно пометить некоторые оси как непространственные.
#
ImageCore.nimages
— Function
nimages(img)
Возвращает количество временных точек в массиве изображения. По умолчанию
-
Если требуется явное измерение времени, используйте ImagesAxes.
#
ImageAxes.timeaxis
— Function
timeaxis(A)
Возвращает ось времени массива A
, если она есть, или nothing
в противном случае.
#
ImageAxes.timedim
— Function
timedim(img) -> d::Int
Возвращает измерение массива, используемое для кодирования времени, или 0, если для этой цели ось не используется.
Обратите внимание: для восстановления информации об оси времени обычно лучше использовать timeaxis
.
#
ImageCore.assert_timedim_last
— Function
assert_timedim_last(img)
Выдает ошибку, если у изображения есть измерение времени и оно не последнее.
#
ImageAxes.StreamIndexStyle
— Type
style = StreamIndexStyle(A)
Типаж, указывающий степень поддержки индексирования потоковых осей A
. Возможные варианты: IndexAny()
и IndexIncremental()
(для массивов, которые допускают продвижение только по оси времени, например видеопотока с веб-камеры). Значение по умолчанию — IndexAny()
.
Специализация должна производиться для типа, а не для экземпляра. Для объекта StreamingContainer S
этот типаж можно определить следующим образом:
StreamIndexStyle(::Type{P}, ::typeof(f!)) = IndexIncremental()
где P = typeof(parent(S))
.
#
ImageAxes.IndexAny
— Type
IndexAny()
Указывает, что ось поддерживает полное индексирование с произвольным доступом.
#
ImageAxes.IndexIncremental
— Type
IndexIncremental()
Указывает, что ось поддерживает только инкрементное индексирование, то есть от i
к i+1
. Обычно используется для временной оси в потоках мультимедиа.
Преобразование элементов и масштабирование интенсивности
#
ImageCore.clamp01
— Function
clamp01(x) -> y
Выдает значение y
в диапазоне от 0 до 1, которое равно x
, если x
уже находится в этом диапазоне. Эквивалентно clamp(x, 0, 1)
для числовых значений. В случае с цветами эта функция применяется к каждому цветовому каналу отдельно.
См. также описание функций clamp01!
, clamp01nan
.
#
ImageCore.clamp01nan
— Function
clamp01nan(x) -> y
То же, что и clamp01
, но все значения NaN
изменяются на 0.
См. также описание функций clamp01nan!
, clamp01
.
#
ImageCore.clamp01nan!
— Function
clamp01nan!(array::AbstractArray)
То же, что и clamp01!
, но все значения NaN
изменяются на 0.
См. также описание функций clamp01!
, clamp01nan
.
#
ImageCore.scaleminmax
— Function
scaleminmax(min, max) -> f
scaleminmax(T, min, max) -> f
Возвращает функцию f
, которая сопоставляет значения, меньшие или равные min
, с 0, значения, большие или равные max
, с 1, и использует линейную шкалу между этими границами. Значения min
и max
должны быть вещественными.
При необходимости можно указать возвращаемый тип T
. Если T
— это цветовая модель (например, RGB), масштабирование применяется к каждому цветовому каналу.
Примеры
Пример 1
julia> f = scaleminmax(-10, 10)
(::#9) (универсальная функция с 1 методом)
julia> f(10)
1.0
julia> f(-10)
0.0
julia> f(5)
0.75
Пример 2
julia> c = RGB(255.0,128.0,0.0)
RGB{Float64}(255.0,128.0,0.0)
julia> f = scaleminmax(RGB, 0, 255)
(::#13) (универсальная функция с 1 методом)
julia> f(c)
RGB{Float64}(1.0,0.5019607843137255,0.0)
См. также описание функции takemap
.
#
ImageCore.scalesigned
— Function
scalesigned(maxabs) -> f
Возвращает функцию f
, которая масштабирует значения в диапазоне [-maxabs, maxabs]
(ограничивая значения за его пределами) до диапазона [-1, 1]
.
См. также описание функции colorsigned
.
scalesigned(min, center, max) -> f
Возвращает функцию f
, которая масштабирует значения в диапазоне [min, center]
до [-1,0]
, а значения в диапазоне [center,max]
— до [0,1]
. Значения меньше min
и max
ограничиваются до min
и max
соответственно.
См. также описание функции colorsigned
.
#
ImageCore.colorsigned
— Function
colorsigned()
colorsigned(colorneg, colorpos) -> f
colorsigned(colorneg, colorcenter, colorpos) -> f
Определяет функцию, которая сопоставляет отрицательные значения (в диапазоне [-1,0]) с линейной цветовой картой от colorneg
до colorcenter
, а положительные значения (в диапазоне [0,1]) — с линейной цветовой картой от colorcenter
до colorpos
.
Цвета по умолчанию:
-
colorcenter
: белый -
colorneg
: зеленый 1 -
colorpos
: пурпурный
См. также описание функции scalesigned
.
#
ImageCore.takemap
— Function
takemap(f, A) -> fnew
takemap(f, T, A) -> fnew
Для заданной функции сопоставления значений f
и массива A
возвращает «конкретную» функцию сопоставления fnew
. При применении к элементам A
функция fnew
должна возвращать допустимые значения для хранения или отображения, например, в диапазоне от 0 до 1 (для оттенков серого), или допустимые цвета. Функция fnew
может быть адаптирована к фактическим значениям в A
и может не выдавать допустимых значений для других входных значений, которых нет в A
.
При необходимости можно указать тип вывода T
для функции fnew
.
Пример:
julia> A = [0, 1, 1000];
julia> f = takemap(scaleminmax, A)
(::#7) (универсальная функция с 1 методом)
julia> f.(A)
3-element Array{Float64,1}:
0.0
0.001
1.0
Преобразование типа хранения
#
ImageCore.float32
— Function
float32.(img)
Преобразует базовый тип хранения img
в Float32
, не изменяя цветовое пространство.
#
ImageCore.float64
— Function
float64.(img)
Преобразует базовый тип хранения img
в Float64
, не изменяя цветовое пространство.
#
ImageCore.n0f8
— Function
n0f8.(img)
Преобразует базовый тип хранения img
в N0f8
, не изменяя цветовое пространство.
#
ImageCore.n6f10
— Function
n6f10.(img)
Преобразует базовый тип хранения img
в N6f10
, не изменяя цветовое пространство.
#
ImageCore.n4f12
— Function
n4f12.(img)
Преобразует базовый тип хранения img
в N4f12
, не изменяя цветовое пространство.
#
ImageCore.n2f14
— Function
n2f14.(img)
Преобразует базовый тип хранения img
в N2f14
, не изменяя цветовое пространство.
#
ImageCore.n0f16
— Function
n0f16.(img)
Преобразует базовый тип хранения img
в N0f16
, не изменяя цветовое пространство.
Цветовые каналы
Вы можете извлечь числовые значения определенных цветовых каналов:
#
ColorTypes.gray
— Function
gray(c)
возвращает серый компонент непрозрачного или прозрачного цвета изображения в оттенках серого.
#
ColorTypes.red
— Function
red(c)
возвращает красный компонент непрозрачного или прозрачного цвета изображения AbstractRGB
.
#
ColorTypes.green
— Function
green(c)
возвращает зеленый компонент непрозрачного или прозрачного цвета изображения AbstractRGB
.
#
ColorTypes.blue
— Function
blue(c)
возвращает синий компонент непрозрачного или прозрачного цвета изображения AbstractRGB
.
#
ColorTypes.alpha
— Function
alpha(p)
извлекает альфа-компонент цвета. Для цвета без альфа-канала всегда возвращает 1.
Можно также выполнять операции с каналами:
#
ColorTypes.mapc
— Function
mapc(f, rgb) -> rgbf
mapc(f, rgb1, rgb2) -> rgbf
mapc(f, rgb1, rgb2, rgb3) -> rgbf
mapc
применяет функцию f
к каждому цветовому каналу входных цветов, возвращая выходной цвет в том же цветовом пространстве.
Примеры:
julia> mapc(x->clamp(x,0,1), RGB(-0.2,0.3,1.2)) RGB{Float64}(0.0,0.3,1.0) julia> mapc(clamp, RGB(-0.2,0.3,1.2), RGB(0, 0.4, 0.5), RGB(1, 0.8, 0.7)) RGB{Float64}(0.0,0.4,0.7) julia> mapc(max, RGB(0.1,0.8,0.3), RGB(0.5,0.5,0.5)) RGB{Float64}(0.5,0.8,0.5) julia> mapc(+, RGB(0.1,0.8,0.3), RGB(0.5,0.5,0.5)) RGB{Float64}(0.6,1.3,0.8)
#
ColorTypes.reducec
— Function
reducec(op, v0, c)
Выполняет редукцию по цветовым каналам c
с помощью бинарного оператора op
. v0
— нейтральный элемент, используемый для инициации редукции. Для оттенков серого:
reducec(op, v0, c::Gray) = op(v0, comp1(c))
В то время как для RGB:
reducec(op, v0, c::RGB) = op(comp3(c), op(comp2(c), op(v0, comp1(c))))
Если у c
есть альфа-канал, он всегда подлежит редукции последним.
#
ColorTypes.mapreducec
— Function
mapreducec(f, op, v0, c)
Выполняет редукцию по цветовым каналам c
с помощью бинарного оператора op
, сначала применяя f
к каждому каналу. v0
— нейтральный элемент, используемый для инициации редукции. Для оттенков серого:
mapreducec(f, op, v0, c::Gray) = op(v0, f(comp1(c)))
В то время как для RGB:
mapreducec(f, op, v0, c::RGB) = op(f(comp3(c)), op(f(comp2(c)), op(v0, f(comp1(c)))))
Если у c
есть альфа-канал, он всегда подлежит редукции последним.
Преобразование цветов
imgg = Gray.(img)
Вычисляет представление цветного изображения в оттенках серого с использованием стандарта Rec 601.
imghsv = HSV.(img)
Преобразует цветовую информацию в формат HSV.
Пакет ColorTypes содержит обширный набор типажей, которые позволяют выполнять общие операции с цветовыми типами. Дополнительные сведения см. в файле README.
Алгоритмы обработки изображений
Линейная фильтрация
#
ImageFiltering.imfilter
— Function
imfilter([T], img, kernel, [border="replicate"], [alg]) --> imgfilt
imfilter([r], img, kernel, [border="replicate"], [alg]) --> imgfilt
imfilter(r, T, img, kernel, [border="replicate"], [alg]) --> imgfilt
Фильтрует одно-, двух- или многомерный массив img
с ядром kernel
, вычисляя их корреляцию.
Расширенная справка
Варианты для r
При необходимости можно производить диспетчеризацию в различные реализации, передавая ресурс r
согласно определению в пакете ComputationalResources.
Например:
imfilter(ArrayFireLibs(), img, kernel)
Этот вызов запрашивает выполнение вычислений на GPU с использованием библиотек ArrayFire.
Варианты для T
При необходимости можно контролировать тип элементов выходного изображения, передавая тип T
первым аргументом.
Варианты для img
Изображение можно передать в виде одно-, двух- или многомерного массива.
Варианты для kernel
Параметр kernel[0, 0,..]
соответствует началу (нулевому смещению) ядра. С помощью centered
можно установить начало в центре массива. Можно также воспользоваться пакетом OffsetArrays для задания индексов kernel
вручную. Например, отфильтровать случайное отцентрированное ядро размером 3x3 можно одним из следующих способов.
kernel = centered(rand(3,3))
kernel = OffsetArray(rand(3,3), -1:1, -1:1)
Параметр kernel
можно задать в виде массива или «разложенного ядра», то есть кортежа (filt1, filt2, ...)
фильтров, которые будут применены по каждой оси изображения. Если известно, что ядро является разделяющимся, такой формат может ускорить обработку. Каждый фильтр должен быть той же размерности, что и само изображение, и иметь форму, указывающую на ось фильтрации, например фильтр 3x1 для фильтрации первого измерения или фильтр 1x3 для фильтрации второго измерения. В случае с двумя измерениями любое ядро, передаваемое в виде одиночной матрицы, проверяется на разделяемость; чтобы эта проверка не проводилась, передайте ядро в виде одноэлементного кортежа: (kernel,)
.
Варианты для border
С помощью аргумента border
указывается способ дополнения для экстраполяции изображения за пределами его исходных границ.
"replicate"
(по умолчанию)
Пиксели границы продолжаются за границами изображения.
╭────┏━━━━━━┓────╮
│aaaa┃abcdef┃ffff│
╰────┗━━━━━━┛────╯
"circular"
Пиксели границы переносятся в противоположную сторону. Например, при обращении по индексам за пределами левой границы возвращаются значения начиная с правой границы.
╭────┏━━━━━━┓────╮
│cdef┃abcdef┃abcd│
╰────┗━━━━━━┛────╯
"reflect"
Пиксели границы отражаются относительно позиции между пикселями. Пиксель границы при этом опускается.
╭────┏━━━━━━┓────╮
│dcba┃abcdef┃fedc│
╰────┗━━━━━━┛────╯
"symmetric"
Пиксели границы отражаются относительно края изображения.
╭────┏━━━━━━┓────╮
│edcb┃abcdef┃edcb│
╰────┗━━━━━━┛────╯
Fill(m)
Пиксели границы заполняются указанным значением .
╭────┏━━━━━━┓────╮
│mmmm┃abcdef┃mmmm│
╰────┗━━━━━━┛────╯
Inner()
Указывает, что края при фильтрации должны отбрасываться: возвращается только внутренняя часть результата.
NA()
Выбор фильтрации с использованием граничных условий NA (недоступно). Лучше всего подходит для фильтров только с положительными весами, например фильтров размытия.
Варианты для alg
Параметр alg
позволяет выбрать алгоритм: Algorithm.FIR()
(конечная импульсная характеристика, то есть традиционная цифровая фильтрация) или Algorithm.FFT()
(фильтрация методом Фурье). Если алгоритм не указан, он выбирается с учетом размера изображения и ядра так, чтобы обеспечивалась высокая производительность. Помимо этого, можно использовать фильтр пользовательского типа, например KernelFactors.IIRGaussian
.
#
ImageFiltering.imfilter!
— Function
imfilter!(imgfilt, img, kernel, [border="replicate"], [alg])
imfilter!(r, imgfilt, img, kernel, border::Pad)
imfilter!(r, imgfilt, img, kernel, border::NoPad, [inds=axes(imgfilt)])
Фильтрует массив img
с ядром kernel
, вычисляя их корреляцию, и сохраняет результат в imgfilt
.
Индексы imgfilt
определяют область, в которой вычисляется отфильтрованное изображение. Это позволяет выбрать определенную область интереса, однако имейте в виду, что входной массив img
все равно может дополняться. Можно также явным образом задать индексы inds
объекта imgfilt
, которые нужно вычислить, и использовать граничные условия NoPad
. В этом случае вы отвечаете за правильную настройку дополнения: массив img
должен быть индексируемым во всех позициях, которые требуются для вычисления результата. Этот синтаксис лучше всего поддерживается при использовании КИХ-фильтрации, в частности по той причине, что БИХ-фильтрация может давать несогласованные результаты при применении ко всему массиву.
См. также описание функции imfilter
.
#
ImageFiltering.imgradients
— Function
imgradients(img, kernelfun=KernelFactors.ando3, border="replicate") -> gimg1, gimg2, …
Оценивает градиент изображения img
в направлении первого и второго измерений во всех точках изображения с использованием ядра, указанного в kernelfun
.
Возвращает кортеж массивов (gimg1, gimg2, ...)
, по одному массиву для каждого измерения во входном массиве: gimg1
соответствует производной относительно первого измерения, gimg2
— второго и т. д.
Пример
using Images, ImageFiltering, TestImages
img = testimage("mandrill")
imgr = imgradients(img, KernelFactors.sobel, "reflect")
mosaicview(imgr...)
Ядро
#
ImageFiltering.Kernel.sobel
— Function
diff1, diff2 = sobel()
Возвращает ядра корреляции для вычисления двухмерного градиента с помощью оператора Собеля. Ядро diff1
вычисляет градиент по оси y (первое измерение), а ядро diff2
— градиент по оси x (второе измерение). diff1 == rotr90(diff2)
(diff,) = sobel(extended::NTuple{N,Bool}, d)
Возвращает N-мерное ядро корреляции (кортеж) для вычисления градиента по измерению d
с помощью оператора Собеля. Если extended[dim]
имеет значение false, diff
имеет размер 1 по соответствующему измерению.
Цитирование
P.-E. Danielsson and O. Seger, Generalized and separable sobel operators, in Machine Vision for Three-Dimensional Scenes, H. Freeman, Ed. Academic Press, 1990, pp. 347—379. doi:10.1016/b978-0-12-266722-0.50016-6
См. также описание функций KernelFactors.sobel
, Kernel.prewitt
, Kernel.ando3
, Kernel.scharr
, Kernel.bickley
и imgradients
.
#
ImageFiltering.Kernel.prewitt
— Function
diff1, diff2 = prewitt()
Возвращает ядра корреляции для вычисления двухмерного градиента с помощью оператора Прюитта. Ядро diff1
вычисляет градиент по оси y (первое измерение), а ядро diff2
— градиент по оси x (второе измерение). diff1 == rotr90(diff2)
(diff,) = prewitt(extended::NTuple{N,Bool}, d)
Возвращает N-мерное ядро корреляции (кортеж) для вычисления градиента по измерению d
с помощью оператора Прюитта. Если extended[dim]
имеет значение false, diff
имеет размер 1 по соответствующему измерению.
Цитирование
J.M. Prewitt, Object enhancement and extraction, Picture processing and Psychopictorics, vol. 10, no. 1, pp. 15—19, 1970.
См. также описание функций KernelFactors.prewitt
, Kernel.sobel
, Kernel.ando3
, Kernel.scharr
,Kernel.bickley
и ImageFiltering.imgradients
.
#
ImageFiltering.Kernel.ando3
— Function
diff1, diff2 = ando3()
Возвращает ядра корреляции для вычисления двухмерного градиента с помощью «оптимальных» фильтров Андо. Ядро diff1
вычисляет градиент по оси y (первое измерение), а ядро diff2
— градиент по оси x (второе измерение). diff1 == rotr90(diff2)
(diff,) = ando3(extended::NTuple{N,Bool}, d)
Возвращает N-мерное ядро корреляции (кортеж) для вычисления градиента по измерению d
с помощью «оптимальных» фильтров Андо размера 3. Если extended[dim]
имеет значение false, diff
имеет размер 1 по соответствующему измерению.
Цитирование
S.Ando, Consistent gradient operators, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 22, no.3, pp. 252—265, 2000. doi:10.1109/34.841757
См. также описание функций KernelFactors.ando3
, Kernel.ando4
, Kernel.ando5
и ImageFiltering.imgradients
.
#
ImageFiltering.Kernel.ando4
— Function
diff1, diff2 = ando4()
Возвращает ядра корреляции для вычисления двухмерного градиента с помощью «оптимальных» фильтров Андо. Ядро diff1
вычисляет градиент по оси y (первое измерение), а ядро diff2
— градиент по оси x (второе измерение). diff1 == rotr90(diff2)
(diff,) = ando4(extended::NTuple{N,Bool}, d)
Возвращает N-мерное ядро корреляции (кортеж) для вычисления градиента по измерению d
с помощью «оптимальных» фильтров Андо размера 4. Если extended[dim]
имеет значение false, diff
имеет размер 1 по соответствующему измерению.
Цитирование
S.Ando, Consistent gradient operators, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 22, no.3, pp. 252—265, 2000. doi:10.1109/34.841757
См. также описание функций KernelFactors.ando4
, Kernel.ando3
, Kernel.ando5
и ImageFiltering.imgradients
.
#
ImageFiltering.Kernel.ando5
— Function
diff1, diff2 = ando5()
Возвращает ядра корреляции для вычисления двухмерного градиента с помощью «оптимальных» фильтров Андо. Ядро diff1
вычисляет градиент по оси y (первое измерение), а ядро diff2
— градиент по оси x (второе измерение). diff1 == rotr90(diff2)
(diff,) = ando5(extended::NTuple{N,Bool}, d)
Возвращает N-мерное ядро корреляции (кортеж) для вычисления градиента по измерению d
с помощью «оптимальных» фильтров Андо размера 5. Если extended[dim]
имеет значение false, diff
имеет размер 1 по соответствующему измерению.
Цитирование
S.Ando, Consistent gradient operators, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 22, no.3, pp. 252—265, 2000. doi:10.1109/34.841757
См. также описание функций KernelFactors.ando5
, Kernel.ando3
, Kernel.ando4
и ImageFiltering.imgradients
.
#
ImageFiltering.Kernel.gaussian
— Function
gaussian((σ1, σ2, ...), [(l1, l2, ...)]) -> g
gaussian(σ) -> g
Создает многомерный фильтр Гаусса со среднеквадратичным отклонением σd
по измерению d
. Можно также указать длину ядра l
в виде кортежа той же длины.
Если значение σ
задано в виде одного числа, возвращается симметричное двухмерное ядро.
См. также описание функции KernelFactors.gaussian
.
#
ImageFiltering.Kernel.DoG
— Function
DoG((σp1, σp2, ...), (σm1, σm2, ...), [l1, l2, ...]) -> k
DoG((σ1, σ2, ...)) -> k
DoG(σ::Real) -> k
Создает многомерное ядро на основе разницы гауссианов k
, равное gaussian(σp, l)-gaussian(σm, l)
. Если предоставлено только одно значение σ
, по умолчанию выбирается σp = σ, σm = √2 σ
. Можно также указать длину ядра l
; по умолчанию ядро простирается на два max(σp,σm)
в каждом направлении от центра. Значение l
должно быть нечетным.
Если значение σ
задано в виде одного числа, возвращается симметричное двухмерное ядро на основе разницы гауссианов.
См. также описание функции KernelFactors.IIRGaussian
.
#
ImageFiltering.Kernel.LoG
— Function
LoG((σ1, σ2, ...)) -> k
LoG(σ) -> k
Создает ядро на основе лапласиана гауссиана k
. σd
— это ширина гауссиана по измерению d
. Если значение σ
задано в виде одного числа, возвращается симметричное двухмерное ядро.
См. также описание функций KernelFactors.IIRGaussian
и Kernel.Laplacian
.
#
ImageFiltering.Kernel.gabor
— Function
gabor(size_x,size_y,σ,θ,λ,γ,ψ) -> (k_real,k_complex)
Возвращает двухмерное комплексное ядро Габора, содержащееся в кортеже:
-
size_x
,size_y
означают размер ядра; -
σ
означает среднеквадратичное отклонение от огибающей Гаусса; -
θ
представляет ориентацию нормали относительно параллельных полос функции Габора; -
λ
представляет длину волны периодической составляющей; -
γ
— пространственное характеристическое отношение, определяющее эллиптичность носителя функции Габора; -
ψ
— сдвиг фаз.
#Citation N. Petkov and P. Kruizinga, Computational models of visual neurons specialised in the detection of periodic and aperiodic oriented visual stimuli: bar and grating cells, Biological Cybernetics, vol. 76, no. 2, pp. 83—96, Feb. 1997. doi.org/10.1007/s004220050323
#
ImageFiltering.Kernel.Laplacian
— Type
Laplacian((true,true,false,...))
Laplacian(dims, N)
Laplacian()
Ядро на основе лапласиана в N
измерениях, принимающее производные в направлениях, помеченных как true
в переданном кортеже. В аргументе dims
можно также передать список измерений для дифференцирования. (Однако такой вариант не является выводимым.)
Laplacian()
— это двухмерный лапласиан, эквивалентный Laplaciantrue,true
.
Ядро представлено как непрозрачный тип, но с помощью функции convert(AbstractArray, L)
его можно преобразовать в формат массива.
#
ImageFiltering.Kernel.bickley
— Function
diff1, diff2 = bickley()
Возвращает ядра корреляции для вычисления двухмерного градиента с помощью оператора Бикли. Ядро diff1
вычисляет градиент по оси y (первое измерение), а ядро diff2
— градиент по оси x (второе измерение). diff1 == rotr90(diff2)
(diff,) = bickley(extended::NTuple{N,Bool}, d)
Возвращает N-мерное ядро корреляции (кортеж) для вычисления градиента по измерению d
с помощью оператора Бикли. Если extended[dim]
имеет значение false, diff
имеет размер 1 по соответствующему измерению.
Цитирование
W.G. Bickley, Finite difference formulae for the square lattice, The Quarterly Journal of Mechanics and Applied Mathematics, vol. 1, no. 1, pp. 35—42, 1948. doi:10.1093/qjmam/1.1.35
См. также описание функций KernelFactors.bickley
, Kernel.prewitt
, Kernel.ando3
, Kernel.scharr
и ImageFiltering.imgradients
.
#
ImageFiltering.Kernel.scharr
— Function
diff1, diff2 = scharr()
Возвращает ядра корреляции для вычисления двухмерного градиента с помощью оператора Шарра. Ядро diff1
вычисляет градиент по оси y (первое измерение), а ядро diff2
— градиент по оси x (второе измерение). diff1 == rotr90(diff2)
(diff,) = scharr(extended::NTuple{N,Bool}, d)
Возвращает N-мерное ядро корреляции (кортеж) для вычисления градиента по измерению d
с помощью оператора Шарра. Если extended[dim]
имеет значение false, diff
имеет размер 1 по соответствующему измерению.
Цитирование
H.Scharr and J. Weickert, An anisotropic diffusion algorithm with optimized rotation invariance, Mustererkennung 2000, pp. 460—467, 2000. doi:10.1007/978-3-642-59802-9_58
См. также описание функций KernelFactors.scharr
, Kernel.prewitt
, Kernel.ando3
, Kernel.bickley
и ImageFiltering.imgradients
.
KernelFactors
#
ImageFiltering.KernelFactors.sobel
— Function
kern1, kern2 = sobel()
Возвращает разложенные фильтры Собеля для измерений 1 и 2 двухмерного изображения. Каждый из них представляет собой кортеж из двух одномерных фильтров.
Цитирование
P.-E. Danielsson and O. Seger, Generalized and separable sobel operators, in Machine Vision for Three-Dimensional Scenes, H. Freeman, Ed. Academic Press, 1990, pp. 347—379. doi:10.1016/b978-0-12-266722-0.50016-6
См. также описание функций Kernel.sobel
и ImageFiltering.imgradients
.
kern = sobel(extended::NTuple{N,Bool}, d)
Возвращает разложенный фильтр Собеля для вычисления градиента в N
измерениях по оси d
. Если extended[dim]
имеет значение false, kern
имеет размер 1 по соответствующему измерению.
См. также описание функций Kernel.sobel
и ImageFiltering.imgradients
.
#
ImageFiltering.KernelFactors.prewitt
— Function
kern1, kern2 = prewitt()
Возвращает разложенные фильтры Прюитта для измерений 1 и 2 изображения. Каждый из них представляет собой кортеж из двух одномерных фильтров.
Цитирование
J.M. Prewitt, Object enhancement and extraction, Picture processing and Psychopictorics, vol. 10, no. 1, pp. 15—19, 1970.
См. также описание функций Kernel.prewitt
и ImageFiltering.imgradients
.
kern = prewitt(extended::NTuple{N,Bool}, d)
Возвращает разложенный фильтр Прюитта для вычисления градиента в N
измерениях по оси d
. Если extended[dim]
имеет значение false, kern
имеет размер 1 по соответствующему измерению.
См. также описание функций Kernel.prewitt
и ImageFiltering.imgradients
.
#
ImageFiltering.KernelFactors.ando3
— Function
kern1, kern2 = ando3()
Возвращает разложенную форму «оптимальных» градиентных фильтров Андо для измерений 1 и 2 изображения.
Цитирование
S.Ando, Consistent gradient operators, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 22, no.3, pp. 252—265, 2000. doi:10.1109/34.841757
См. также описание функций Kernel.ando3
, KernelFactors.ando4
, KernelFactors.ando5
и ImageFiltering.imgradients
.
kern = ando3(extended::NTuple{N,Bool}, d)
Возвращает разложенный фильтр Андо (размера 3) для вычисления градиента в N
измерениях по оси d
. Если extended[dim]
имеет значение false, kern
имеет размер 1 по соответствующему измерению.
См. также описание функций KernelFactors.ando4
, KernelFactors.ando5
и ImageFiltering.imgradients
.
#
ImageFiltering.KernelFactors.ando4
— Function
kern1, kern2 = ando4()
Возвращает разделяемые аппроксимации «оптимальных» фильтров Андо 4x4 для измерений 1 и 2 изображения.
Цитирование
S.Ando, Consistent gradient operators, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 22, no.3, pp. 252—265, 2000. doi:10.1109/34.841757
См. также описание функций Kernel.ando4
и ImageFiltering.imgradients
.
kern = ando4(extended::NTuple{N,Bool}, d)
Возвращает разложенный фильтр Андо (размера 4) для вычисления градиента в N
измерениях по оси d
. Если extended[dim]
имеет значение false, kern
имеет размер 1 по соответствующему измерению.
Цитирование
S.Ando, Consistent gradient operators, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 22, no.3, pp. 252—265, 2000. doi:10.1109/34.841757
См. также описание функций Kernel.ando4
и ImageFiltering.imgradients
.
#
ImageFiltering.KernelFactors.ando5
— Function
kern1, kern2 = ando5()
Возвращает разделяемые аппроксимации «оптимальных» градиентных фильтров Андо 5x5 для измерений 1 и 2 изображения.
Цитирование
S.Ando, Consistent gradient operators, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 22, no.3, pp. 252—265, 2000. doi:10.1109/34.841757
См. также описание функций Kernel.ando5
и ImageFiltering.imgradients
.
kern = ando5(extended::NTuple{N,Bool}, d)
Возвращает разложенный фильтр Андо (размера 5) для вычисления градиента в N
измерениях по оси d
. Если extended[dim]
имеет значение false, kern
имеет размер 1 по соответствующему измерению.
#
ImageFiltering.KernelFactors.gaussian
— Function
gaussian(σ::Real, [l]) -> g
Создает одномерное гауссово ядро g
со среднеквадратичным отклонением σ
; при необходимости можно указать длину ядра l
. По умолчанию ядро простирается на два σ
в каждом направлении от центра. Значение l
должно быть нечетным.
gaussian((σ1, σ2, ...), [l]) -> (g1, g2, ...)
Создает многомерный фильтр Гаусса как произведение одномерных множителей со среднеквадратичным отклонением σd
по измерению d
. Можно также указать длину ядра l
в виде кортежа той же длины.
#
ImageFiltering.KernelFactors.IIRGaussian
— Function
IIRGaussian([T], σ; emit_warning::Bool=true)
Создает аппроксимацию бесконечной импульсной характеристики (БИХ) к гауссиану среднеквадратичного отклонения σ
. σ
может быть одним вещественным числом или кортежем чисел; в последнем случае создается кортеж таких фильтров, каждый из которых предназначен для фильтрации отдельного измерения массива.
При необходимости можно указать тип T
для коэффициентов фильтра; если тип не указан, он будет соответствовать типу σ
(если σ
не является значением с плавающей запятой, выбирается тип Float64
).
Цитирование
I.T. Young, L. J. van Vliet, and M. van Ginkel, Recursive Gabor Filtering. IEEE Trans. Sig. Proc., 50: 2798-2805 (2002).
#
ImageFiltering.KernelFactors.TriggsSdika
— Type
TriggsSdika(a, b, scale, M)
Определяет ядро для одномерной фильтрации с бесконечной импульсной характеристикой (БИХ). a
— это «прямой» фильтр, b
— «обратный» фильтр, M
— матрица для сопоставления граничных условий на правом краю, а scale
— константа масштабирования, применяемая к каждому элементу по завершении фильтрации.
Цитирование
B.Triggs and M. Sdika, Boundary conditions for Young-van Vliet recursive filtering. IEEE Trans. on Sig. Proc. 54: 2365-2367 (2006).
TriggsSdika(ab, scale)
Создает симметричный фильтр Триггса-Сдики (с a = b = ab
). M
вычисляется автоматически. В настоящее время поддерживаются только фильтры длиной 3.
#
ImageFiltering.KernelFactors.bickley
— Function
kern1, kern2 = bickley()
Возвращает разложенные фильтры Бикли для измерений 1 и 2 изображения. Каждый из них представляет собой кортеж из двух одномерных фильтров.
Цитирование
W.G. Bickley, Finite difference formulae for the square lattice, The Quarterly Journal of Mechanics and Applied Mathematics, vol. 1, no. 1, pp. 35—42, 1948. doi:10.1093/qjmam/1.1.35
См. также описание функций Kernel.bickley
и ImageFiltering.imgradients
.
kern = bickley(extended::NTuple{N,Bool}, d)
Возвращает разложенный фильтр Бикли для вычисления градиента в N
измерениях по оси d
. Если extended[dim]
имеет значение false, kern
имеет размер 1 по соответствующему измерению.
См. также описание функций Kernel.bickley
и ImageFiltering.imgradients
.
#
ImageFiltering.KernelFactors.scharr
— Function
kern1, kern2 = scharr()
Возвращает разложенные фильтры Шарра для измерений 1 и 2 изображения. Каждый из них представляет собой кортеж из двух одномерных фильтров.
Цитирование
H.Scharr and J. Weickert, An anisotropic diffusion algorithm with optimized rotation invariance, Mustererkennung 2000, pp. 460—467, 2000. doi:10.1007/978-3-642-59802-9_58
См. также описание функций Kernel.scharr
и ImageFiltering.imgradients
.
kern = scharr(extended::NTuple{N,Bool}, d)
Возвращает разложенный фильтр Шарра для вычисления градиента в N
измерениях по оси d
. Если extended[dim]
имеет значение false, kern
имеет размер 1 по соответствующему измерению.
См. также описание функций Kernel.scharr
и ImageFiltering.imgradients
.
Служебные средства для ядер
#
ImageFiltering.KernelFactors.kernelfactors
— Function
kernelfactors(factors::Tuple)
Подготавливает разложенное ядро для фильтрации. Если передан кортеж из двух векторов длиной m
и n
, возвращается кортеж из двух векторов ReshapedVector
, имеющих размеры m×1
и 1×n
. В общем случае форма каждого следующего множителя factor
изменяется так, чтобы он простирался вдоль соответствующего измерения.
Если передан кортеж общих массивов, предполагается, что каждый из них имеет соответствующую форму вдоль «ведущих» измерений; размерность каждого массива «расширяется» до N = length(factors)
с добавлением значений 1 к размеру при необходимости.
#
ImageFiltering.Kernel.reflect
— Function
reflect(kernel) --> reflectedkernel
Вычисляет поточечное отражение относительно 0, 0, … ядра kernel
. При использовании imfilter
с reflectedkernel
выполняется свертка, а не корреляция, относительно исходного ядра kernel
.
Границы и дополнение
#
ImageFiltering.padarray
— Function
padarray([T], img, border)
Generate a padded image from an array img
and a specification border
of the boundary conditions and amount of padding to add.
Return a padded image. The function supports one, two or multi-dimensional images. You can specify the element type T
of the output image.
Примеры
Дополнение
Основной синтаксис для Pad
имеет вид (style, m, n, ...)
или (style, (m, n))
, где m
пикселей добавляются к измерению 1 (сверху и снизу), n
пикселей — к измерению 2 и т. д.
Добавляем 30 пикселей слева и справа, 40 пикселей сверху и снизу:
padarray(A, Pad(:replicate, 30, 40))
padarray(A, Pad(:circular, 30, 40))
padarray(A, Pad(:symmetric, 30, 40))
padarray(A, Pad(:reflect, 30, 40))
Добавляем 30 пикселей сверху, 40 пикселей слева, 50 пикселей снизу, 60 пикселей справа:
padarray(A, Pad(0, (30, 40), (50, 60)))
padarray(A, Pad(0, (30, 40), (50, 60)))
3 измерения
padarray(A, Pad(:replicate, 1, 1, 1))
padarray(A, Fill(0, (1, 1, 1)))
Заполнение
Основной синтаксис для Fill
имеет вид (value, m, n)
или (value, (m, n))
, где в начале каждого измерения добавляется m
пикселей, а в конце — n
пикселей.
Добавляем 20 значений -1
сверху, 30 — слева, 40 — снизу, 50 — справа:
padarray(A, Fill(-1, (20, 30), (40, 50)))
#
ImageFiltering.Pad
— Type
struct Pad{N} <: AbstractBorder
style::Symbol
lo::Dims{N} # число, на которое следует расширить изображение с нижнего края каждого измерения
hi::Dims{N} # число, на которое следует расширить изображение с верхнего края каждого измерения
end
Pad
— это тип, определяющий форму дополнения, которая должна использоваться для экстраполяции пикселей за границами изображения. В экземплярах должен быть задан style
, символ, определяющий граничные условия изображения.
Вывод
Тип Pad
, определяющий способ дополнения границы изображения.
Расширенная справка
Когда операция фильтрации двухмерного пространственного изображения представлена в виде дискретной свертки между изображением и фильтром , результаты не определены для пикселей, которые находятся ближе пикселей к границе изображения. Чтобы определить операцию для пикселей, находящихся ближе к границе и на ней, требуется схема экстраполяции пикселей за границей. Тип Pad
позволяет указать необходимую схему экстраполяции.
Этот тип упрощает дополнение одно-, двух- или многомерных изображений.
Можно указать другую степень дополнения на нижней и верхней границах каждого измерения изображения (верхней, левой, нижней и правой границах в двух измерениях).
Параметры
Ниже описываются некоторые допустимые варианты style
. Для иллюстрации результаты дополнения с использованием каждого варианта показаны на примере изображения, состоящего из строки из шести пикселей, которые следуют по алфавиту:
┏━━━━━━┓
┃abcdef┃
┗━━━━━━┛
Результат дополнения демонстрируется только на левой и правой границах, но для верхней и нижней границ результат будет аналогичным.
:replicate
(по умолчанию)
Пиксели границы продолжаются за границами изображения.
╭────┏━━━━━━┓────╮
│aaaa┃abcdef┃ffff│
╰────┗━━━━━━┛────╯
:circular
Пиксели границы переносятся в противоположную сторону. Например, при обращении по индексам за пределами левой границы возвращаются значения начиная с правой границы.
╭────┏━━━━━━┓────╮
│cdef┃abcdef┃abcd│
╰────┗━━━━━━┛────╯
:symmetric
Пиксели границы отражаются относительно позиции между пикселями. Пиксель границы при этом опускается.
╭────┏━━━━━━┓────╮
│edcb┃abcdef┃edcb│
╰────┗━━━━━━┛────╯
:reflect
Пиксели границы отражаются относительно края изображения.
╭────┏━━━━━━┓────╮
│dcba┃abcdef┃fedc│
╰────┗━━━━━━┛────╯
#
ImageFiltering.Fill
— Type
struct Fill{T,N} <: AbstractBorder
value::T
lo::Dims{N}
hi::Dims{N}
end
Fill
— это тип, определяющий конкретное значение, которое будет использоваться для экстраполяции пикселей за границами изображения.
Вывод
Тип Fill
, определяющий значение, которым будет дополняться граница изображения.
Подробные сведения
Когда операция фильтрации двухмерного пространственного изображения представлена в виде дискретной свертки между изображением и фильтром , результаты не определены для пикселей, которые находятся ближе пикселей к границе изображения. Чтобы определить операцию для пикселей, находящихся ближе к границе и на ней, требуется схема экстраполяции пикселей за границей. Тип Fill
позволяет указать конкретное значение, которое будет использоваться при экстраполяции. Подробные схемы экстраполяции см. в описании типа Pad
.
Этот тип упрощает дополнение одно-, двух- или многомерных изображений.
Можно указать другую степень дополнения на нижней и верхней границах каждого измерения изображения (верхней, левой, нижней и правой границах в двух измерениях).
Пример
Для иллюстрации рассмотрим изображение, состоящее из строки из шести пикселей, которые следуют по алфавиту:
┏━━━━━━┓
┃abcdef┃
┗━━━━━━┛
Дополнение постоянным значением m
только на левой и правой границах выглядит следующим образом:
╭────┏━━━━━━┓────╮
│mmmm┃abcdef┃mmmm│
╰────┗━━━━━━┛────╯
(Аналогичным будет результат и для верхней и нижней границ.)
#
ImageFiltering.Inner
— Type
Inner()
Inner(lo, hi)
Указывает, что края при фильтрации должны отбрасываться: возвращается только внутренняя часть результата.
Пример:
imfilter(img, kernel, Inner())
#
ImageFiltering.NA
— Type
NA(na=isnan)
Выбор фильтрации с использованием граничных условий NA (недоступно). Лучше всего подходит для фильтров только с положительными весами, например фильтров размытия. Выходное значение фактически нормализуется следующим образом:
filtered array with Fill(0) boundary conditions output = ----------------------------------------------- filtered 1 with Fill(0) boundary conditions
Элементы массива, для которых na
возвращает значение true
, также считаются находящимися за границами массива.
#
ImageFiltering.NoPad
— Type
NoPad()
NoPad(border)
Указывает, что дополнение не должно применяться ко входному массиву или что входное изображение уже предварительно дополнено. Передача объекта border
позволяет сэкономить память на выборе границы; его можно получить по индексу в []
.
Пример
Следующие команды:
np = NoPad(Pad(:replicate)) imfilter!(out, img, kernel, np)
позволяют выполнить фильтрацию напрямую, пропустив дополнение. Каждый элемент out
должен быть вычислим с использованием операций в пределах границ с img
и kernel
.
Алгоритмы
#
ImageFiltering.Algorithm.FIR
— Type
Выполняет фильтрацию с использованием прямого алгоритма.
#
ImageFiltering.Algorithm.FFT
— Type
Выполняет фильтрацию с использованием быстрого преобразования Фурье.
#
ImageFiltering.Algorithm.IIR
— Type
Выполняет фильтрацию с использованием фильтра с бесконечной импульсной характеристикой.
#
ImageFiltering.Algorithm.Mixed
— Type
Выполняет фильтрацию с использованием каскада смешанных типов (БИХ, КИХ).
Внутренние механизмы
#
ImageFiltering.KernelFactors.ReshapedOneD
— Type
ReshapedOneD{N,Npre}(data)
Возвращает объект размерности N
, где data
должно иметь размерность 1. Он имеет оси 0:0
для первых Npre
измерений, оси data
для измерения Npre+1
и оси 0:0
для оставшихся измерений.
Объект data
должен поддерживать eltype
и ndims
, но не обязательно должен быть массивом AbstractArray.
ReshapedOneDs позволяет указать «измерение фильтрации» для одномерного фильтра.
Нелинейная фильтрация и преобразование
#
ImageFiltering.MapWindow.mapwindow
— Function
mapwindow(f::F, img, window;
border = "replicate",
indices = default_imginds(img, window, border), callmode=:copy!)
Применяет f
к скользящим окнам img
с заданным размером окна или осями, определяемыми окном. Например, mapwindow(median!, img, window)
возвращает массив значений, сходный с img
(естественно, отфильтрованный по медиане), а mapwindow(extrema, img, window)
возвращает массив кортежей (минимум, максимум) для окна размера window с центром в каждой точке img
.
Функция f
принимает буфер buf
для окна данных, окружающего текущую точку.
Если аргумент window
задан в виде кортежа измерений (целых чисел), все эти целые числа должны быть нечетными, а центром окна является текущая точка изображения.
Например, при window = (3,3)
функция f
принимает массив buf
, соответствующий смещениям (-1:1, -1:1) от точки imgf[i, j]
, для которой вычисляется функция. Окном может быть также кортеж значений типа AbstractUnitRange
. В этом случае в качестве буфера buf
применяются указанные диапазоны, что позволяет при необходимости использовать асимметричные окна.
Ограничение вычислений частью изображения
С помощью именованного аргумента indices
можно избежать ненужных вычислений, например, если нужно применить функцию mapwindow
к части изображения или использовать функцию mapwindow с заданным шагом.
Следующий вызов:
mapwindow(f, img, window, indices=(2:5, 1:2:7))
эффективнее, чем его аналог:
mapwindow(f, img, window)[2:5, 1:2:7]
так как ненужные значения не вычисляются.
Так как данные в буфере buf
, принимаемом функцией f
, копируются из img
и память буфера используется повторно, функция f
не должна возвращать ссылки на buf
.
Следующий код:
f = buf -> copy(buf) # а не f = buf -> buf
mapwindow(f, img, window, indices=(2:5, 1:2:7))
должен работать, как ожидается.
Для функций, принимающих только объекты типа AbstractVector
, может потребоваться сначала специализировать default_shape
:
f = v -> quantile(v, 0.75)
ImageFiltering.MapWindow.default_shape(::typeof(f)) = vec
В результате функция mapwindow(f, img, (m, n))
должна выполнять фильтрацию по 75-му квантилю.
См. также описание функции imfilter
.
Обнаружение краев
#
Images.magnitude
— Function
m = magnitude(grad_x, grad_y)
Вычисляет величину градиентных изображений, заданных посредством grad_x
и grad_y
. Эквивалентно sqrt(grad_x.^2 + grad_y.^2)
.
Возвращает изображение величины того же размера, что и grad_x
и grad_y
.
#
Images.phase
— Function
phase(grad_x, grad_y) -> p
Вычисляет угол поворота градиента, заданного посредством grad_x
и grad_y
. Эквивалентно atan(-grad_y, grad_x)
за тем исключением, что если и grad_x
, и grad_y
равны нулю, соответствующий угол задается равным нулю.
#
Images.orientation
— Function
orientation(grad_x, grad_y) -> orient
Вычисляет угол ориентации наиболее интенсивного края градиентных изображений, заданных посредством grad_x
и grad_y
. Эквивалентно atan(grad_x, grad_y)
. Если и grad_x
, и grad_y
равны нулю, соответствующий угол задается равным нулю.
#
Images.magnitude_phase
— Function
magnitude_phase(grad_x, grad_y) -> m, p
Вспомогательная функция для вычисления величины и фазы градиентных изображений, заданных посредством grad_x
и grad_y
. Возвращает кортеж, содержащий изображения величины и фазы. Подробные сведения см. в описании magnitude
и phase
.
#
Images.imedge
— Function
grad_y, grad_x, mag, orient = imedge(img, kernelfun=KernelFactors.ando3, border="replicate")
Фильтрация для обнаружения краев. kernelfun
— это допустимая функция ядра для imgradients
; по умолчанию KernelFactors.ando3
. border
— это любое из граничных условий, указанных в padarray
.
Возвращает кортеж (grad_y, grad_x, mag, orient)
, содержащий соответственно горизонтальный градиент, вертикальный градиент, а также величину и ориентацию самого интенсивного края.
#
Images.thin_edges
— Function
thinned = thin_edges(img, gradientangle, [border])
thinned, subpix = thin_edges_subpix(img, gradientangle, [border])
thinned, subpix = thin_edges_nonmaxsup(img, gradientangle, [border]; [radius::Float64=1.35], [theta=pi/180])
thinned, subpix = thin_edges_nonmaxsup_subpix(img, gradientangle, [border]; [radius::Float64=1.35], [theta=pi/180])
Утоньшение контуров на двухмерных контурных изображениях. В настоящее время доступен только алгоритм немаксимального подавления, который принимает контурное изображение и его угол градиента и проверяет каждую точку контура на локальную максимальность в направлении градиента. В возвращаемом изображении значения не равны нулю только в точках максимумов на контурах.
border
— это любое из граничных условий, указанных в padarray
.
Помимо изображения с максимальными контурами, версии _subpix
этих функций также возвращают оценку субпиксельного положения каждого локального максимума в виде двухмерного массива или изображения, состоящего из объектов Graphics.Point
. Кроме того, каждый локальный максимум корректируется с учетом расчетного значения в субпиксельном положении.
В настоящее время функции _nonmaxsup
идентичны первым двум вызовам функций за тем исключением, что они принимают дополнительные именованные аргументы. radius
указывает размер шага при поиске в направлении градиента; рекомендуются значения от 1,2 до 1,5 (по умолчанию 1,35). theta
указывает размер шага при дискретизации углов на изображении gradientangle
в радианах (по умолчанию 1 градус в радианах равен pi/180).
Пример:
g = rgb2gray(rgb_image) gx, gy = imgradients(g) mag, grad_angle = magnitude_phase(gx,gy) mag[mag .< 0.5] = 0.0 # Изображение пороговой величины thinned, subpix = thin_edges_subpix(mag, grad_angle)
#
Images.canny
— Function
canny_edges = canny(img, (upper, lower), sigma=1.4)
Выполняет обнаружение краев методом Кэнни на входном изображении.
Параметры:
(upper, lower): границы для сигмы порога гистерезиса; определяет среднеквадратичное отклонение гауссова фильтра
Пример
imgedg = canny(img, (Percentile(80), Percentile(20)))
#
Images.Percentile
— Type
Percentile(x)
Indicate that x
should be interpreted as a percentile rather than an absolute value. For example,
-
canny(img, 1.4, (80, 20))
uses absolute thresholds on the edge magnitude image -
canny(img, 1.4, (Percentile(80), Percentile(20)))
uses percentiles of the edge magnitude image as threshold
Обнаружение углов
#
Images.imcorner
— Function
corners = imcorner(img; [method])
corners = imcorner(img, threshold; [method])
Performs corner detection using one of the following methods -
1. harris 2. shi_tomasi 3. kitchen_rosenfeld
The parameters of the individual methods are described in their documentation. The maxima values of the resultant responses are taken as corners. If a threshold is specified, the values of the responses are thresholded to give the corner pixels. If threshold
is a Percentile
then its type will be preserved.
#
Images.harris
— Function
harris_response = harris(img; [k], [border], [weights])
Performs Harris corner detection. The covariances can be taken using either a mean weighted filter or a gamma kernel.
#
Images.shi_tomasi
— Function
shi_tomasi_response = shi_tomasi(img; [border], [weights])
Performs Shi Tomasi corner detection. The covariances can be taken using either a mean weighted filter or a gamma kernel.
#
Images.kitchen_rosenfeld
— Function
kitchen_rosenfeld_response = kitchen_rosenfeld(img; [border])
Performs Kitchen Rosenfeld corner detection. The covariances can be taken using either a mean weighted filter or a gamma kernel.
#
Images.fastcorners
— Function
fastcorners(img, n, threshold) -> corners
Performs FAST Corner Detection. n
is the number of contiguous pixels which need to be greater (lesser) than intensity + threshold (intensity - threshold) for a pixel to be marked as a corner. The default value for n is 12.
Извлечение признаков
Более полный набор инструментов представлен в пакете ImageFeatures.
#
ImageFiltering.blob_LoG
— Function
blob_LoG(img, σscales; edges::Tuple=(true, false, ...), σshape::Tuple=(1, ...), rthresh=0.001) -> Vector{BlobLoG}
Находит «пятна» на N-мерном изображении, используя отрицательный лапласиан гауссианов с указанным вектором или кортежем значений σ. Алгоритм ищет места, где отфильтрованное изображение (для определенного σ) имеет пиковое значение по сравнению со всеми пространственно- и σ-смежными вокселами, где σ равно σscales[i] * σshape
для некоторого i. По умолчанию σshape
— это кортеж ntuple, состоящий из единиц.
Необязательный аргумент edges
определяет, включаются ли пики на краях. Значением edges
может быть true
, false
или кортеж из N+1 элементов, в котором первый элемент определяет, могут ли краевые значения σ выступать в качестве пиков, а остальные N элементов определяют каждое из N измерений изображения img
.
rthresh
определяет минимальную амплитуду пиков на изображении, отфильтрованном посредством лапласиана гауссианов, как частное от деления maximum(abs, img)
на объем гауссиана.
Примеры
Хотя изображения, как правило, являются двух- или трехмерными, проиллюстрировать это будет проще на примере одномерного «изображения», содержащего два гауссовых пятна разных размеров:
julia> σs = 2.0.^(1:6);
julia> img = zeros(100); img[20:30] = [exp(-x^2/(2*4^2)) for x=-5:5]; img[50:80] = [exp(-x^2/(2*8^2)) for x=-15:15];
julia> blob_LoG(img, σs; edges=false)
2-element Vector{BlobLoG{Float64, Tuple{Float64}, 1}}:
BlobLoG(location=CartesianIndex(25,), σ=(4.0,), amplitude=0.10453155018303673)
BlobLoG(location=CartesianIndex(65,), σ=(8.0,), amplitude=0.046175719034527364)
Два других располагаются по центру соответствующих «объектов», а σ
— это ширина самого объекта.
blob_LoG
, как правило, лучше всего работает с формами, похожими на гауссовы, но с некоторым обобщением.
Цитирование
Lindeberg T (1998), Feature Detection with Automatic Scale Selection, International Journal of Computer Vision, 30(2), 79—116.
См. также описание типа BlobLoG
.
#
ImageFiltering.BlobLoG
— Type
В BlobLoG хранится информация о положении пиков, обнаруженных функцией blob_LoG
. Поля этого типа следующие:
-
location: положение пика на отфильтрованном изображении (CartesianIndex)
-
σ: значение σ, которое приводит к наибольшей отфильтрованной методом
-LoG
амплитуде в данном положении -
amplitude: значение отфильтрованного методом
-LoG(σ)
изображения в положении пика
Обратите внимание, что радиус равен σ√2.
См. также описание функции blob_LoG
.
#
ImageFiltering.findlocalmaxima
— Function
findlocalmaxima(img; window=default_window(img), edges=true) -> Vector{CartesianIndex}
Возвращает координаты элементов, значения которых больше, чем у всех смежных с ними элементов. edges
— это логическое значение, указывающее, следует ли включать первый и последний элементы каждого измерения, или кортеж логических значений, определяющий поведение на границах для каждого измерения по отдельности.
default_window
имеет значение 3 для каждого пространственного измерения img
и значение 1 в остальных случаях, что подразумевает нахождение максимумов среди смежных элементов по умолчанию в каждом пространственном «срезе».
#
ImageFiltering.findlocalminima
— Function
findlocalminima(img; window=default_window(img), edges=true) -> Vector{CartesianIndex}
Аналогично findlocalmaxima
, но возвращает координаты наименьших элементов.
Экспозиция
#
ImageContrastAdjustment.build_histogram
— Function
edges, count = build_histogram(img) # Только для 8-битных изображений
edges, count = build_histogram(img, nbins)
edges, count = build_histogram(img, nbins; minval, maxval)
edges, count = build_histogram(img, edges)
Создает гистограмму для изображения по распределению nbins
в интервале [minval, maxval]
. Цветные изображения автоматически преобразуются в оттенки серого.
Вывод
Возвращает объект edges
типа AbstractRange
, определяющий то, как интервал [minval, maxval]
делится на столбцы, и массив count
, в котором записываются сопутствующие частоты столбцов. В частности, count
обладает следующими свойствами.
-
count[0]
— это число, отвечающее условиюx < edges[1]
. -
count[i]
— это количество значенийx
, отвечающих условиюedges[i] <= x < edges[i+1]
. -
count[end]
— это число, отвечающее условиюx >= edges[end]
. -
length(count) == length(edges)+1
.
Подробные сведения
Гистограмму можно рассматривать как кусочно-постоянную модель функции плотности вероятности [1]. Предположим, что имеет опору на некотором интервале ]. Let — это целое число, а a = a_1 < a_2 < \ldots < a_m < a_{m+1} = b
— последовательность вещественных чисел. Построим последовательность интервалов
разделяющая на подмножества , на которых имеет постоянное значение. Эти подмножества отвечают условиям и обычно называются столбцами. Вместе они охватывают весь диапазон значений данных, так что . Каждый столбец имеет ширину и высоту , которая представляет собой постоянную плотность вероятности в области столбца. Интегрирование постоянной плотности вероятности по ширине столбца дает вероятностную меру для столбца.
Пусть для выборки
представляют собой количество значений, попадающих в интервал . Оценка вероятностной меры -го столбца определяется относительной частотой , а оценка гистограммы для функции плотности вероятности — следующим образом.
Функция является истинной оценкой плотности, так как и
Параметры
Различные варианты параметров этой функции более подробно описываются ниже.
Варианты для nbins
Вы можете указать количество дискретных столбцов для гистограммы. При указании количества столбцов учитывайте максимальное количество уровней серого, поддерживаемое типом изображения. Например, на изображении типа N0f8
может быть максимум 256 уровней серого. Поэтому при запросе более 256 столбцов для этого типа изображения следует ожидать получения нулевых значений для большого количества столбцов.
Варианты для minval
Есть возможность указать нижнюю границу интервала, по которому будет вычисляться гистограмма. Если minval
не указано, то в качестве нижней границы принимается минимальное значение, имеющееся на изображении.
Варианты для maxval
Есть возможность указать верхнюю границу интервала, по которому будет вычисляться гистограмма. Если maxval
не указано, то в качестве верхней границы принимается максимальное значение, имеющееся на изображении.
Варианты для edges
Если не задано ни количество столбцов, ни нижняя или верхняя граница интервала, то есть возможность напрямую указать, как будут делиться интервалы, с помощью типа AbstractRange
.
Пример
Вычисляет гистограмму изображения в оттенках серого.
using TestImages, FileIO, ImageView
img = testimage("mandril_gray");
edges, counts = build_histogram(img, 256, minval = 0, maxval = 1)
Для цветного изображения вычисляет гистограмму красного канала.
img = testimage("mandrill")
r = red.(img)
edges, counts = build_histogram(r, 256, minval = 0, maxval = 1)
Справочные материалы
[1] E. Herrholz, Parsimonious Histograms, Ph.D. dissertation, Inst. of Math. and Comp. Sci., University of Greifswald, Greifswald, Germany, 2011.
#
ImageContrastAdjustment.HistogramAdjustmentAPI.adjust_histogram
— Function
adjust_histogram([T::Type,] img, f::AbstractHistogramAdjustmentAlgorithm, args...; kwargs...)
Корректирует гистограмму img
, используя алгоритм f
.
Вывод
Возвращаемое изображение img_adjusted
является Array{T}
.
Если T
не указан, он выводится.
Примеры
Просто передайте входное изображение и алгоритм функции adjust_histogram
.
img_adjusted = adjust_histogram(img, f)
Это означает «обнаружение краев (adjust_histogram
) изображения (img
) с использованием алгоритма f
».
Вы также можете явным образом указать возвращаемый тип:
img_adjusted_float32 = adjust_histogram(Gray{Float32}, img, f)
Сведения о корректировке гистограммы на месте см. в описании функции adjust_histogram!
.
#
ImageContrastAdjustment.HistogramAdjustmentAPI.adjust_histogram!
— Function
adjust_histogram!([out,] img, f::AbstractHistogramAdjustmentAlgorithm, args...; kwargs...)
Корректирует гистограмму img
, используя алгоритм f
.
Вывод
Если out
указан, он будет изменен на месте. В противном случае img
будет изменен на месте.
Примеры
Просто передайте алгоритм функции adjust_histogram!
:
img_adjusted = similar(img)
adjust_histogram!(img_adjusted, img, f)
Когда вы просто хотите изменить img
на месте, необязательно вручную выделять img_adjusted
. Достаточно воспользоваться вспомогательным методом:
adjust_histogram!(img, f)
См. также описание adjust_histogram
.
#
ImageContrastAdjustment.AdaptiveEqualization
— Type
AdaptiveEqualization <: AbstractHistogramAdjustmentAlgorithm
AdaptiveEqualization(; nbins = 256, minval = 0, maxval = 1, rblocks = 8, cblocks = 8, clip = 0.1)
adjust_histogram([T,] img, f::AdaptiveEqualization)
adjust_histogram!([out,] img, f::AdaptiveEqualization)
Выполняет адаптивное выравнивание гистограммы с ограничением контрастности (CLAHE) для входного изображения. Отличается от обычного выравнивания гистограммы тем, что адаптивный метод вычисляет несколько гистограмм, каждая из которых соответствует отдельному участку изображения, и использует их для перераспределения значений освещенности изображения. Поэтому данный метод подходит для улучшения локальной контрастности и повышения четкости границ в каждой области изображения.
Подробные сведения
Выравнивание гистограммы изначально задумывалось для улучшения контрастности на одноканальном изображении в оттенках серого. Данный метод преобразует распределение уровней интенсивности на изображении так, чтобы оно было максимально равномерным [1]. Естественным обоснованием этой равномерности является то, что изображение имеет лучшую контрастность, если уровни интенсивности на нем охватывают широкий диапазон. Как оказалось, необходимое преобразование представляет собой сопоставление на основе кумулятивной гистограммы; более подробные сведения см. в разделе Equalization.
Естественным развитием метода выравнивания гистограммы является применение усиления контрастности локально, а не глобально [2]. Концептуально можно представить, что процесс предполагает разбиение изображения на сетку прямоугольных областей и применение выравнивания гистограммы на основе локальной интегральной функции распределения (CDF) к каждой контекстной области. Однако для сглаживания перехода пикселей из одной контекстной области в другую сопоставление пикселя не обязательно выполняется исключительно на основе локальной функции CDF его контекстной области. Вместо этого сопоставление пикселя может быть интерполировано на основе функции CDF его контекстной области и функций CDF смежных с ней областей.
При адаптивном выравнивании гистограммы изображение разбивается на подматриц одинакового размера:
Для каждой подматрицы
Чтобы определить, какие именно функции CDF будут использоваться на этапе интерполяции, полезно (i) ввести функцию
(ii) построить последовательности
Случай I (внутренняя часть)
Для пикселя
значения
Билинейное интерполяционное преобразование, которое сопоставляет интенсивность
Случай II (вертикальная граница)
Для пикселя
Линейное интерполяционное преобразование, которое сопоставляет интенсивность
Случай III (горизонтальная граница)
Для пикселя
Линейное интерполяционное преобразование, которое сопоставляет интенсивность
Случай IV (углы)
Для пикселя
верно следующее:
Преобразование, которое сопоставляет интенсивность
Ограничение контрастности
Неприятным побочным эффектом усиления контрастности является тенденция к увеличению уровня шума на изображении, особенно когда величина усиления контрастности очень высока. Величина усиления контрастности связана с градиентом
Так как производная
Параметры
Различные варианты параметров этой функции более подробно описываются ниже.
Варианты для img
Функция может обрабатывать различные типы входных данных. Возвращаемое изображение зависит от типа входных данных.
Для цветных изображений входные данные преобразуются в тип YIQ, и выравнивается канал Y. Результат объединяется с каналами I и Q, и полученное изображение преобразуется во входной тип.
Варианты для nbins
в AdaptiveEqualization
Вы можете указать общее количество столбцов в гистограмме каждой локальной области.
Варианты для rblocks
и cblocks
в AdaptiveEqualization
Параметры rblocks
и cblocks
определяют количество блоков, на которые следует разделить входное изображение в каждом направлении. По умолчанию оба параметра имеют значение 8.
Варианты для clip
в AdaptiveEqualization
Параметр clip
должен иметь значение от 0 до 1. Он определяет неявный порог, по которому обрезается гистограмма. Отсчеты, превышающие пороговое значение, перераспределяется максимально равномерно так, чтобы ни один столбец не превышал порог. Нулевое значение означает отсутствие обрезания, тогда как значение 1 задает порог равным минимально возможному пределу для столбца. Предел для столбца является возможным, если все отсчеты столбца можно перераспределить так, чтобы ни один из них не превышал предел. На практике нулевое значение clip
соответствует максимальному усилению контрастности, а значение clip
, равное единице, — минимальному усилению. Значение по умолчанию — 0.1
.
Варианты для minval
и maxval
в AdaptiveEqualization
Если параметры minval
и maxval
заданы, то уровни интенсивности выравниваются в диапазоне [minval
, maxval
]. Значения по умолчанию — 0 и 1.
Пример
using TestImages, FileIO, ImageView
img = testimage("mandril_gray")
imgeq = adjust_histogram(img, AdaptiveEqualization(nbins = 256, rblocks = 4, cblocks = 4, clip = 0.2))
imshow(img)
imshow(imgeq)
Справочные материалы
-
R. C. Gonzalez and R. E. Woods. Digital Image Processing (3rd Edition). Upper Saddle River, NJ, USA: Prentice-Hall, 2006.
-
S. M. Pizer, E. P. Amburn, J. D. Austin, R. Cromartie, A. Geselowitz, T. Greer, B. ter Haar Romeny, J. B. Zimmerman and K. Zuiderveld. Adaptive histogram equalization and its variations. Computer Vision, Graphics, and Image Processing, vol. 38, no. 1, p. 99, Apr. 1987. 10.1016/S0734-189X(87)80186-X
-
W. H. Press, S. A. Teukolsky, W. T. Vetterling, and B. P. Flannery. Numerical Recipes: The Art of Scientific Computing (3rd Edition). New York, NY, USA: Cambridge University Press, 2007.
#
ImageContrastAdjustment.Equalization
— Type
Equalization <: AbstractHistogramAdjustmentAlgorithm
Equalization(; nbins = 256, minval = 0, maxval = 1)
adjust_histogram([T,] img, f::Equalization)
adjust_histogram!([out,] img, f::Equalization)
Возвращает изображение с выровненной гистограммой с детальностью (числом столбцов) nbins
.
Подробные сведения
Выравнивание гистограммы изначально задумывалось для улучшения контрастности на одноканальном изображении в оттенках серого. Данный метод преобразует распределение уровней интенсивности на изображении так, чтобы оно было максимально равномерным [1]. Естественным обоснованием этой равномерности является то, что изображение имеет лучшую контрастность, если уровни интенсивности на нем охватывают широкий диапазон. Как оказалось, необходимое преобразование представляет собой сопоставление на основе кумулятивной гистограммы.
Тогда изображение можно рассматривать как матрицу случайных величин
а каждая функция
где
представляет количество раз, которое уровень серого с интенсивностью
Параметры
Различные варианты параметров функции adjust_histogram
и типа Equalization
более подробно описываются ниже.
Варианты для img
Функция adjust_histogram
может обрабатывать различные типы входных данных. По умолчанию тип возвращаемого изображения совпадает с входным типом.
Для цветных изображений входные данные преобразуются в тип YIQ, и выравнивается канал Y. Результат объединяется с каналами I и Q, и полученное изображение преобразуется во входной тип.
Варианты для nbins
в Equalization
Вы можете указать общее количество столбцов в гистограмме.
Варианты для minval
и maxval
в Equalization
Если параметры minval
и maxval
заданы, то уровни интенсивности выравниваются в диапазоне [minval
, maxval
]. Значения по умолчанию — 0 и 1.
Пример
using TestImages, FileIO, ImageView
img = testimage("mandril_gray")
imgeq = adjust_histogram(img, Equalization(nbins = 256, minval = 0, maxval = 1))
imshow(img)
imshow(imgeq)
Справочные материалы
-
R. C. Gonzalez and R. E. Woods. Digital Image Processing (3rd Edition). Upper Saddle River, NJ, USA: Prentice-Hall, 2006.
#
ImageContrastAdjustment.GammaCorrection
— Type
GammaCorrection <: AbstractHistogramAdjustmentAlgorithm
GammaCorrection(; gamma = 1)
adjust_histogram([T,] img, f::GammaCorrection)
adjust_histogram!([out,] img, f::GammaCorrection)
Возвращает изображение с гамма-коррекцией.
Подробные сведения
Гамма-коррекция — это нелинейное преобразование, определяемое соотношением
Оно называется преобразованием по степенному закону, потому что одна величина изменяется пропорционально степени другой.
Гамма-коррекция традиционно использовалась для предварительной обработки изображения с целью компенсировать тот факт, что интенсивность света, излучаемого физическим устройством, обычно не является линейной функцией приложенного сигнала, а подчиняется степенному закону [1]. Например, во многих электронно-лучевых трубках (ЭЛТ) интенсивность излучаемого света на дисплее приблизительно равна напряжению в степени γ, где γ ∈ [1.8, 2.8]. Следовательно, предварительная обработка исходного изображения с показателем 1/γ обеспечила бы линейную реакцию на яркость.
Исследования в области психофизики также выявили эмпирическую степенную зависимость между интенсивностью света и воспринимаемой яркостью. Поэтому гамма-коррекция часто служит полезным инструментом улучшения изображений.
Параметры
Различные варианты параметров функции adjust_histogram
и типа Gamma
более подробно описываются ниже.
Варианты для img
Функция может обрабатывать различные типы входных данных. Возвращаемое изображение зависит от типа входных данных.
Для цветных изображений входные данные преобразуются в тип YIQ, и производится гамма-коррекция канала Y. Результат объединяется с каналами I и Q, и полученное изображение преобразуется во входной тип.
Варианты для gamma
Значение gamma
должно быть ненулевым положительным числом. Значение gamma
меньше единицы дает более яркое изображение, тогда как значение больше единицы дает более темное изображение. Если значение не указано, используется значение по умолчанию 1.
Пример
using ImageContrastAdjustment, ImageView
# Создаем пример изображения, на котором уровни интенсивности изменяются линейно.
n = 32
intensities = 0.0:(1.0/n):1.0
img = repeat(intensities, inner=(20,20))'
# Повышаем яркость темных тонов.
imgadj = adjust_histogram( img, GammaCorrection(gamma = 1/2))
# Отображаем исходное и скорректированное изображения.
imshow(img)
imshow(imgadj)
Справочные материалы
-
W. Burger and M. J. Burge. Digital Image Processing. Texts in Computer Science, 2016. doi:10.1007/978-1-4471-6684-9
#
ImageContrastAdjustment.LinearStretching
— Type
LinearStretching <: AbstractHistogramAdjustmentAlgorithm
LinearStretching(; [src_minval], [src_maxval],
dst_minval=0, dst_maxval=1,
no_clamp=false)
LinearStretching((src_minval, src_maxval) => (dst_minval, dst_maxval))
LinearStretching((src_minval, src_maxval) => nothing)
LinearStretching(nothing => (dst_minval, dst_maxval))
adjust_histogram([T,] img, f::LinearStretching)
adjust_histogram!([out,] img, f::LinearStretching)
Возвращает изображение, на котором уровни интенсивности лежат в интервале [dst_minval
, dst_maxval
].
Подробные сведения
Линейное растяжение (также называемое нормализацией) — это улучшающее контрастность преобразование, которое используется для изменения динамического диапазона изображения. В частности, предположим, что входное изображение содержит значения серого в диапазоне [A,B] и требуется изменить динамический диапазон на [a,b] с помощью линейного сопоставления. В этом случае необходимое преобразование задается соотношением
Параметры
Различные варианты параметров функции adjust_histogram
и типа LinearStretching
более подробно описываются ниже.
Варианты для img
Функция может обрабатывать различные типы входных данных. Возвращаемое изображение зависит от типа входных данных.
Для цветных изображений входные данные преобразуются в тип YIQ, и уровни интенсивности канала Y растягиваются до указанного диапазона. Измененный канал Y затем объединяется с каналами I и Q, и полученное изображение преобразуется во входной тип.
Варианты для dst_maxval
и dst_minval
Если задан конечный диапазон значений от dst_minval
до dst_maxval
, то уровни интенсивности сопоставляются с диапазоном [dst_minval
, dst_maxval
]. Значения по умолчанию — 0 и 1.
Варианты для src_maxval
и src_minval
Диапазон исходных значений от src_minval
до src_maxval
определяет диапазон уровней интенсивности входного изображения. По умолчанию значения равны extrema(img)
(конечные). Если указаны пользовательские значения, выходное значение интенсивности ограничивается диапазоном [dst_minval, dst_maxval]
в случае выхода из него.
no_clamp
При no_clamp=true
автоматическое ограничение отключается, даже если выходное значение интенсивности выходит за пределы диапазона [dst_minval, dst_maxval]
. Имейте в виду, что ограничение по-прежнему применяется к типам с ограниченным диапазоном значений, например, если тип входных данных — N0f8
, выходные данные ограничиваются диапазоном [0.0N0f8, 1.0N0f8]
даже при no_clamp==true
.
Пример
using ImageContrastAdjustment, TestImages
img = testimage("mandril_gray")
# Растягивает контрастность в `img` так, чтобы она охватывала единичный интервал.
imgo = adjust_histogram(img, LinearStretching(dst_minval = 0, dst_maxval = 1))
Для удобства также поддерживается создание объекта LinearStretching
с использованием Pair
:
# эти два конструктора эквивалентны
LinearStretching(src_minval=0.1, src_maxval=0.9, dst_minval=0.05, dst_maxval=0.95)
LinearStretching((0.1, 0.9) => (0.05, 0.95))
# заменяем часть со значениями `nothing` значениями по умолчанию, например,
# указываем только диапазон конечных значений
LinearStretching(nothing => (0.05, 0.95))
# указываем только диапазон исходных значений и используем диапазон конечных значений по умолчанию, то есть (0, 1)
LinearStretching((0.1, 0.9) => nothing)
Справочные материалы
-
W. Burger and M. J. Burge. Digital Image Processing. Texts in Computer Science, 2016. doi:10.1007/978-1-4471-6684-9
#
ImageContrastAdjustment.Matching
— Type
Matching <: AbstractHistogramAdjustmentAlgorithm
Matching(targetimg; nbins = 256, edges = nothing)
adjust_histogram([T,] img, f::Matching)
adjust_histogram!([out,] img, f::Matching)
Возвращает сопоставленное с гистограммой изображение с детальностью (числом столбцов) nbins
. Первый аргумент img
— это изображение, которое необходимо сопоставить, а второй аргумент targetimg
в Matching()
— это изображение, с гистограммой которого должно производиться сопоставление.
Подробные сведения
Целью сопоставления с гистограммой является преобразование уровней интенсивности на исходном изображении таким образом, чтобы они распределялись в соответствии с гистограммой указанного целевого изображения. Если рассматривать гистограммы как кусочно-постоянные модели функций плотности вероятности (см. описание функции link:@ref build_histogram(::AbstractArray, ::Integer, ::Union{Real,AbstractGray}, ::Union{Real,AbstractGray})[build_histogram
]), то задачу сопоставления с гистограммой можно смоделировать как задачу преобразования одного вероятностного распределения в другое [1]. Оказывается, решение этой задачи преобразования включает в себя интегральные и обратные интегральные функции распределения исходной и целевой функций плотности вероятности.
В частности, пусть случайные величины
представляет сопутствующие интегральные функции распределения. Тогда искомое сопоставление
где
Данная формула предполагает, что сопоставление с гистограммой можно представить как выравнивание гистограмм исходного и целевого изображений и соотнесение этих двух выровненных гистограмм. Дополнительные сведения о выравнивании гистограмм см. в описании функции adjust_histogram
.
Параметры
Различные варианты параметров функции adjust_histogram
и типа Matching
более подробно описываются ниже.
Варианты для targetimg
и img
Функция adjust_histogram(img, Matching())
может обрабатывать различные типы входных данных. Тип возвращаемого изображения совпадает с входным типом.
Для цветных изображений входные данные преобразуются в тип YIQ, и сопоставляются распределения каналов Y. Измененный канал Y затем объединяется с каналами I и Q, и полученное изображение преобразуется во входной тип.
Варианты для nbins
Вы можете указать общее количество столбцов в гистограмме. Если количество столбцов не указано, по умолчанию используется 256 столбцов.
Варианты для edges
Если количество столбцов не задано, то есть возможность напрямую указать, как будут делиться интервалы, с помощью типа AbstractRange
.
Пример
using Images, TestImages, ImageView
img_source = testimage("mandril_gray")
img_target = adjust_histogram(img_source, GammaCorrection(gamma = 0.5))
img_transformed = adjust_histogram(img_source, Matching(targetimg = img_target))
#=
A visual inspection confirms that img_transformed resembles img_target
much more closely than img_source.
=#
imshow(img_source)
imshow(img_target)
imshow(img_transformed)
Справочные материалы
-
W. Burger and M. J. Burge. Digital Image Processing. Texts in Computer Science, 2016. doi:10.1007/978-1-4471-6684-9
#
ImageContrastAdjustment.MidwayEqualization
— Type
MidwayEqualization <: AbstractHistogramAdjustmentAlgorithm
MidwayEqualization(; nbins = 256, minval = 0, maxval = 1)
adjust_histogram([T,] img_sequence, f::MidwayEqualization(nbins = 256, edges = nothing))
adjust_histogram!([out_sequence,] img_sequence, f::MidwayEqualization(nbins = 256, edges = nothing))
Приводит пару изображений к одинаковой гистограмме, максимально сохраняя их предыдущую динамику уровней серого.
Подробные сведения
Целью промежуточного выравнивания гистограммы является преобразование уровней интенсивности на паре изображений таким образом, чтобы они имели общее «среднее» распределение. Гистограмма, представляющая общее распределение, выбирается так, чтобы максимально сохранить исходную динамику уровней серого на изображениях. Если рассматривать гистограммы как кусочно-постоянные модели функций плотности вероятности (см. описание функции link:@ref build_histogram(::AbstractArray, ::Integer, ::Union{Real,AbstractGray}, ::Union{Real,AbstractGray})[build_histogram
]), то задачу промежуточного выравнивания гистограммы можно смоделировать как задачу преобразования одного вероятностного распределения в другое (см. описание функции adjust_histogram
). Оказывается, решение этой задачи преобразования включает в себя интегральные и обратные интегральные функции распределения исходной и «средней» функций плотности вероятности. В частности, пусть случайные величины
представляют соответственно интегральные функции распределения двух входных изображений и их гармоническое среднее. Тогда искомое сопоставление
где
Параметры
Различные варианты параметров функции adjust_histogram
и типа MidwayEqualization
более подробно описываются ниже.
Варианты для img_sequence
Функция adjust_histogram
ожидает объект Vector
из двух изображений (пару изображений) и возвращает объект Vector
из двух измененных изображений. Функция может обрабатывать различные типы входных данных. Тип возвращаемого изображения совпадает с входным типом.
Для цветных изображений входные данные преобразуются в тип YIQ, и распределения каналов Y преобразуются согласно «среднему» распределению. Измененный канал Y затем объединяется с каналами I и Q, и полученное изображение преобразуется во входной тип.
Варианты для nbins
Вы можете указать общее количество столбцов в гистограмме. Если количество столбцов не указано, по умолчанию используется 256 столбцов.
Варианты для edges
Если количество столбцов не задано, то есть возможность напрямую указать, как будут делиться интервалы, с помощью типа AbstractRange
.
Пример
using Images, TestImages, ImageView, ImageContrastAdjustment
img = testimage("mandril_gray")
# То же изображение, но с другими распределениями интенсивности
img1 = adjust_histogram(img, GammaCorrection(gamma = 2))
img2 = adjust_histogram(img, GammaCorrection(gamma = 1.2))
# Промежуточное выравнивание гистограммы преобразует эти два изображения так, что их
# распределения интенсивности будут практически идентичными.
img_sequence = adjust_histogram([img1, img2], MidwayEqualization(nbins = 256))
img1o = first(img_sequence)
img2o = last(img_sequence)
Справочные материалы
-
T. Guillemot and J. Delon. Implementation of the Midway Image Equalization. Image Processing On Line, vol. 5, pp. 114—129, Jun. 2016. doi:10.5201/ipol.2016.140
#
Images.cliphist
— Function
clipped_hist = cliphist(hist, clip)
Clips the histogram above a certain value clip
. The excess left in the bins exceeding clip
is redistributed among the remaining bins.
#
Images.imstretch
— Function
imgs = imstretch(img, m, slope)
enhances or reduces (for slope > 1 or < 1, respectively) the contrast near saturation (0 and 1). This is essentially a symmetric gamma-correction. For a pixel of brightness p
, the new intensity is 1/(1+(m/(p+eps))^slope)
.
This assumes the input img
has intensities between 0 and 1.
#
Images.imadjustintensity
— Function
imadjustintensity(img [, (minval,maxval)]) -> Image
Map intensities over the interval (minval,maxval)
to the interval [0,1]
. This is equivalent to map(ScaleMinMax(eltype(img), minval, maxval), img)
. (minval,maxval) defaults to extrema(img)
.
Пространственные преобразования и изменение размера
#
ImageTransformations.imresize
— Function
imresize(img, sz; [method]) -> imgr
imresize(img, inds; [method]) -> imgr
imresize(img; ratio, [method]) -> imgr
Повышает или понижает дискретизацию изображения img
до указанного размера sz
или осей inds
с использованием интерполяций. Если предоставлено значение ratio
, выходной размер равен ceil(Int, size(img).*ratio)
.
Значения интерполируются в субпиксельных положениях. При уменьшении изображения есть риск получить ступенчатость, если только сначала не применить к |
Аргументы
-
img
: входной массив изображения -
sz
: размер выходного массива -
inds
: оси выходного массива. Если аргументinds
передан, выходной массивimgr
будет иметь типOffsetArray
.
Параметры
Для создания |
-
ratio
: используемое отношение повышения или понижения дискретизации. Выходной размер —ceil(Int, size(img).*ratio)
. Еслиratio
больше1
, это операция повышения дискретизации. В противном случае это операция понижения дискретизации.ratio
также может быть кортежем; в этом случаеratio[i]
означает коэффициент изменения размера в измеренииi
. -
method::InterpolationType
: указывает метод интерполяции, используемый для реконструкции. Для удобстваmethold
также может иметь типDegree
; в этом случае создается объектBSpline
. Например,method = Linear()
эквивалентноmethod = BSpline(Linear())
.
Примеры
using ImageTransformations, TestImages, Interpolations
img = testimage("lighthouse") # 512*768
# передаем целые числа в качестве размера
imresize(img, 256, 384) # 256*384
imresize(img, (256, 384)) # 256*384
imresize(img, 256) # 256*768
# передаем индексы в качестве осей
imresize(img, 1:256, 1:384) # 256*384
imresize(img, (1:256, 1:384)) # 256*384
imresize(img, (1:256, )) # 256*768
# передаем коэффициент изменения размера
imresize(img, ratio = 0.5) #256*384
imresize(img, ratio = (2, 1)) # 1024*768
# используем другой метод интерполяции
imresize(img, (256, 384), method=Linear()) # билинейная интерполяция 256*384
imresize(img, (256, 384), method=Lanczos4OpenCV()) # интерполяция по Ланцошу 4, совместимая с OpenCV, 256*384
Для понижения дискретизации с ratio=0.5
функция restrict
будет гораздо более быстрой реализацией.
#
ImageTransformations.imrotate
— Function
imrotate(img, θ, [indices]; kwargs...) -> imgr
Поворачивает изображение img
на θ
∈[0,2π) по часовой стрелке вокруг центральной точки.
Аргументы
-
img::AbstractArray
: исходное изображение, которое необходимо повернуть. -
θ::Real
: угол поворота по часовой стрелке. Чтобы повернуть изображение против часовой стрелки, используйте отрицательное значение. Чтобы повернуть изображение наd
градусов, используйте формулуθ=d*π/180
. -
indices
(необязательно): указывает оси выходного изображения. По умолчанию повернутое изображениеimgr
не обрезается, поэтому равенствоaxes(imgr) == axes(img)
в общем случае не выполняется.
Параметры
Для построения значений |
-
method::Union{Degree, InterpolationType}
: метод интерполяции, который необходимо использовать. По умолчаниюLinear()
. -
fillvalue
: значение, используемое для заполнения новой области. Значение по умолчанию —NaN
, если это возможно; в противном случае —0
.
Эта функция представляет собой простой высокоуровневый интерфейс для warp
; дополнительные сведения и пояснения см. в описании функции warp
.
Примеры
using TestImages, ImageTransformations
img = testimage("cameraman")
# Поворачиваем изображение на π/4 по часовой стрелке
imgr = imrotate(img, π/4) # выходные оси (-105:618, -105:618)
# Поворачиваем изображение на π/4 против часовой стрелки
imgr = imrotate(img, -π/4) # выходные оси (-105:618, -105:618)
# Сохраняем исходные оси
# Обратите внимание, что этот вариант эффективнее, чем `@view imrotate(img, π/4)[axes(img)...]`
imgr = imrotate(img, π/4, axes(img)) # выходные оси (1:512, 1:512)
По умолчанию imrotate
использует билинейную интерполяцию с постоянным значением заполнения (NaN
или 0
). Например, можно использовать интерполяцию по ближайшим элементам и заполнить новую область белыми пикселями:
using Interpolations, ImageCore
imrotate(img, π/4, method=Constant(), fillvalue=oneunit(eltype(img)))
А можно сделать и что-то более изощренное, например произвести заполнение периодическими значениями и объединить результаты в мозаику:
using Interpolations, ImageCore
imgr = imrotate(img, π/4, fillvalue = Periodic())
mosaicview([imgr for _ in 1:9]; nrow=3)
#
ImageTransformations.warp
— Function
warp(img, tform, [indices]; kwargs...) -> imgw
Преобразует координаты img
, возвращая новое изображение imgw
, для которого выполняется условие imgw[I] = img[tform(I)]
.
Вывод
Выходной массив imgw
имеет тип OffsetArray
. Если это не указано вручную, равенство axes(imgw) == axes(img)
в общем случае не выполняется. Если нужен простой массив, можно «отбросить» пользовательские индексы с помощью parent(imgw)
или OffsetArrays.no_offset_view(imgw)
.
Аргументы
-
img
: исходное изображение, координаты которого необходимо преобразовать. -
tform
: функция преобразования координат или подобный функции объект; должен приниматьSVector
в качестве входных данных. Полезным пакетом для создания широкого спектра таких преобразований является CoordinateTransformations.jl. -
indices
(необязательно): указывает оси выходного изображения. По умолчанию индексы вычисляются с помощью link:@ref ImageTransformations.autorange[autorange
] таким образом, чтоimgw
содержит все исходные пиксели изimg
. Для этого необходимо вычислитьinv(tform)
. Если преобразованиеtform
не поддерживаетinv
, параметрindices
необходимо указать вручную.
Параметры
Для построения значений |
-
method::Union{Degree, InterpolationType}
: метод интерполяции, который необходимо использовать. По умолчаниюBSpline(Linear())
. Для создания экземпляра метода может потребоваться загрузить пакетInterpolations
. -
fillvalue
: значение, используемое для заполнения новой области. Значение по умолчанию —NaN
, если это возможно; в противном случае —0
. Можно также передать граничное условие экстраполяции:Flat()
,Reflect()
иPeriodic()
.
Дополнительные материалы
Существуют высокоуровневые интерфейсы warp
:
Есть также отложенные версии warp
:
-
WarpedView
is almost equivalent towarp
except that it does not allocate memory. -
InvWarpedView(img, tform, [indices\]; kwargs...)
почти эквивалентноwarp(img, inv(tform), [indices]; kwargs...)
за тем исключением, что память не выделяется.
Расширенная справка
Подробные сведения о параметрах
Этот подход известен как деформация в обратном режиме. Он называется «обратным», потому что внутреннее преобразование координат на самом деле является обратным сопоставлением из axes(imgr)
в axes(img)
.
Вы можете вручную указать поведение интерполяции, создав объект AbstractExtrapolation
и передав его в warp
как img
. Однако обычно это обременительно. По этой причине есть два именованных аргумента method
и fillvalue
, позволяющих легко создавать объект AbstractExtrapolation
во время выполнения warp
.
Если |
method::Union{Degree, InterpolationType}
Метод интерполяции, который необходимо использовать для воссоздания значений на деформированном изображении.
Среди возможных вариантов InterpolationType
есть несколько часто используемых методов, которые вы, возможно, использовали в других языках:
-
ближайшие соседние элементы:
BSpline(Constant())
; -
треугольный или билинейный:
BSpline(Linear())
; -
бикубический:
BSpline(Cubic(Line(OnGrid())))
; -
lanczos2:
Lanczos(2)
; -
lanczos3:
Lanczos(3)
; -
lanczos4:
Lanczos(4)
илиLanczos4OpenCV()
.
При передаче Degree
ожидается, что это будет BSpline
. Например, Linear()
эквивалентно BSpline(Linear())
.
fillvalue
Если tform(I)
сопоставляется с индексами за пределами исходного изображения img
, этим позициям присваивается значение fillvalue
. Значением fillvalue по умолчанию является NaN
, если тип элементов img
его поддерживает, и 0
в противном случае.
Параметр fillvalue
может иметь тип Number
или Colorant
. В этом случае он сначала преобразуется в eltype(imgr)
. Например, fillvalue = 1
преобразуется в Gray(1)
, в результате чего внешние индексы заполняются белыми пикселями.
Кроме того, значением fillvalue
может быть схема экстраполяции: Flat()
, Periodic()
и Reflect()
. Понять эти схемы проще всего на небольшом примере:
using ImageTransformations, TestImages, Interpolations
using OffsetArrays: IdOffsetRange
img = testimage("lighthouse")
imgr = imrotate(img, π/4; fillvalue=Flat()) # нулевой наклон экстраполяции
imgr = imrotate(img, π/4; fillvalue=Periodic()) # периодическая граница
imgr = imrotate(img, π/4; fillvalue=Reflect()) # зеркальная граница
axes(imgr)
# output
(IdOffsetRange(values=-196:709, indices=-196:709), IdOffsetRange(values=-68:837, indices=-68:837))
Значение координат
В imgw
отслеживаются индексы, которые получатся в результате применения inv(tform)
к индексам img
. Это может быть очень удобно для отслеживания того, как пиксели в imgw
соответствуют пикселям в img
.
using ImageTransformations, TestImages, Interpolations
img = testimage("lighthouse")
imgr = imrotate(img, π/4)
imgr_cropped = imrotate(img, π/4, axes(img))
# Не нужно вычислять смещения вручную.
imgr[axes(img)...] == imgr_cropped
# output
true
Из соображений производительности рекомендуется передавать позиционный аргумент |
Примеры: поворот двухмерного изображения
В этом примере показано только, как создать |
Поворот вокруг центра img
:
using ImageTransformations, CoordinateTransformations, Rotations, TestImages, OffsetArrays
using OffsetArrays: IdOffsetRange
img = testimage("lighthouse") # оси (1:512, 1:768)
tfm = recenter(RotMatrix(-pi/4), center(img))
imgw = warp(img, tfm)
axes(imgw)
# output
(IdOffsetRange(values=-196:709, indices=-196:709), IdOffsetRange(values=-68:837, indices=-68:837))
#
ImageTransformations.WarpedView
— Type
WarpedView(img, tform, [indices]; kwargs...) -> wv
Создает представление img
, которое выполняет отложенное преобразование любого заданного индекса I
, переданного в wv[I]
, так, что wv[I] == img[tform(I)]
.
Это отложенная версия warp
на основе представления. Дополнительные сведения см. в описании warp
.
#
ImageTransformations.InvWarpedView
— Type
InvWarpedView(img, tinv, [indices]; kwargs...) -> wv
InvWarpedView(inner_view, tinv) -> wv
Создает представление img
, которое выполняет отложенное преобразование любого заданного индекса I
, переданного в wv[I]
, так, что wv[I] == img[inv(tinv)(I)]
.
За тем исключением, что вычисление производится в отложенном режиме, следующие две строки должны быть эквивалентными:
warp(img, inv(tform), [indices]; kwargs...)
invwarpedview(img, tform, [indices]; kwargs...)
Принципиальное отличие от WarpedView
заключается в том, что тип InvWarpedView
предназначен для использования в тех случаях, когда анализировать удобнее изображение, а не индексы. Кроме того, тип InvWarpedView
обеспечивает простое вложение преобразований, при котором несколько преобразований объединяются в одно.
Подробное описание деформации, связанных с ней аргументов и параметров см. в описании функции warp
.
Статистика по изображению
Функции для получения статистики по изображениям распределены по пакетам Images.jl, ImageDistances.jl и ImageQualityIndexes.jl.
#
ImageQualityIndexes.entropy
— Function
entropy(logᵦ, img; nbins=256)
entropy(img; kind=:shannon, nbins=256)
Вычисляет энтропию сигнала изображения, определяемую как -sum(p.*logᵦ(p))
, где p — гистограмма изображения.
Основание β логарифма (также известное как единица энтропии) может быть следующим:
-
:shannon
(логарифм по основанию 2, по умолчанию), либо используйте logᵦ = log2; -
:nat
(логарифм по основанию e), либо используйте logᵦ = log; -
:hartley
(логарифм по основанию 10), либо используйте logᵦ = log10.
Именованный аргумент nbins
определяет способ вычисления гистограммы.
Примеры
julia> img = rand(1:10, 5, 5)
5×5 Matrix{Int64}:
2 8 2 5 6
7 9 2 7 3
7 8 8 1 3
3 1 3 9 4
5 7 10 4 6
julia> entropy(img)
3.223465189601647
julia> entropy(log2, img) # kind=:shannon
3.223465189601647
julia> entropy(img; kind=:nat)
2.234335807805511
При условии что распределения (гистограммы) одинаковы, энтропия также будет одинаковой:
julia> img = rand(Gray, 5, 5);
julia> entropy(img)
4.5638561897747225
julia> entropy(RGB.(img))
4.5638561897747225
julia> entropy(repeat(img, inner=(2, 2), outer=(2, 2)))
4.5638561897747225
Общие расстояния
Имя типа | Удобный синтаксис | Математическое определение |
---|---|---|
Euclidean |
|
|
SqEuclidean |
|
|
Cityblock |
|
|
TotalVariation |
|
|
Minkowski |
|
|
Hamming |
|
|
SumAbsoluteDifference |
|
|
SumSquaredDifference |
|
|
MeanAbsoluteError |
|
|
MeanSquaredError |
|
|
RootMeanSquaredError |
|
|
NCC |
|
|
Расстояния, относящиеся к изображениям
Тип расстояния | Удобный синтаксис | Справочные материалы |
---|---|---|
|
|
Dubuisson, M-P et al. 1994. A Modified Hausdorff Distance for Object-Matching. |
|
|
Sharma, G., Wu, W., and Dalal, E. N., 2005. The CIEDE2000 color‐difference formula. |
Метрики изображений
#
ImageQualityIndexes.PSNR
— Type
PSNR <: FullReferenceIQI
assess(PSNR(), x, ref, [, peakval])
assess_psnr(x, ref [, peakval])
Пиковое отношение сигнала к шуму (PSNR) используется для измерения качества изображения в присутствии шума и искажений.
Для изображения x
в оттенках серого PSNR (в дБ) рассчитывается как 10log10(peakval^2/mse(x, ref))
, где peakval
— максимально возможное значение пикселя на изображении ref
. При необходимости x
преобразуется в тип ref
.
Как правило, для изображения x
не в оттенках серого PSNR сообщается для каждого канала ref
и выводится Vector
; peakval
также должен быть вектором.
Традиционно изображение RGB размером |
#
ImageQualityIndexes.SSIM
— Type
SSIM([kernel], [(α, β, γ)]; crop=false) <: FullReferenceIQI
assess(iqi::SSIM, img, ref)
assess_ssim(img, ref; crop=false)
Индекс структурного сходства (SSIM) — это метод оценки качества изображения, основанный на ухудшении структурной информации.
Индекс SSIM состоит из трех компонентов: яркости, контрастности и структуры: ssim = 𝐿ᵅ * 𝐶ᵝ * 𝑆ᵞ
, где W := (α, β, γ)
определяет относительную важность каждого компонента. По умолчанию W = (1.0, 1.0, 1.0)
.
На практике используется усредненный индекс SSIM. Для каждого пикселя SSIM вычисляется локально в окрестности, взвешенной по kernel
, и возвращается карта SSIM; ssim
— это фактически mean(ssim_map)
. По умолчанию kernel = KernelFactors.gaussian(1.5, 11)
.
Параметры по умолчанию взяты из работы [1]. Для эталонного использования рекомендуется не изменять параметры, так как в большинстве других реализаций SSIM используются они же. Именованный аргумент |
Пример
assess_ssim(img, ref)
должно быть достаточно для получения базовой конфигурации для алгоритмов. Можно также создать экземпляр пользовательского SSIM, а затем передать его в assess
или использовать как функцию. Например:
iqi = SSIM(KernelFactors.gaussian(2.5, 17), (1.0, 1.0, 2.0))
assess(iqi, img, ref)
iqi(img, ref) # оба варианта использования эквивалентны
Индекс SSIM определен только для изображений в оттенках серого. Способ обработки |
Справочные материалы
[1] Wang, Z., Bovik, A. C., Sheikh, H. R., & Simoncelli, E. P. (2004). Image quality assessment: from error visibility to structural similarity. IEEE transactions on image processing, 13(4), 600—612.
[2] Wang, Z., Bovik, A. C., Sheikh, H. R., & Simoncelli, E. P. (2003). The SSIM Index for Image Quality Assessment. Retrived May 30, 2019, from http://www.cns.nyu.edu/~lcv/ssim/
#
ImageQualityIndexes.colorfulness
— Function
M = colorfulness(img)
M = colorfulness(HASLER_AND_SUSSTRUNK_M3(), img)
Измеряет цветность естественного изображения. По умолчанию используется метод HASLER_AND_SUSSTRUNK_M3
.
См. также описание метода HASLER_AND_SUSSTRUNK_M3
.
#
ImageQualityIndexes.HASLER_AND_SUSSTRUNK_M3
— Type
HASLER_AND_SUSSTRUNK_M3 <: NoReferenceIQI
M = hasler_and_susstrunk_m3(img)
Вычисляет цветность естественного изображения с использованием метода M3 из работы [1]. Авторы предлагают следующие ориентиры для интерпретации результатов:
Атрибут | M3 |
---|---|
Цветность отсутствует |
0 |
Невысокая цветность |
15 |
Умеренная цветность |
33 |
Средняя цветность |
45 |
Значительная цветность |
59 |
Высокая цветность |
82 |
Крайне высокая цветность |
109 |
[1] Hasler, D. and Süsstrunk, S.E., 2003, June. Measuring colorfulness in natural images. In Human vision and electronic imaging VIII (Vol. 5007, pp. 87—96). International Society for Optics and Photonics.
Морфологические операции
#
ImageMorphology.dilate
— Function
dilate(img; dims=coords_spatial(img), r=1)
dilate(img, se)
Применяет фильтр максимума к окрестности img
, определяемой структурирующим элементом se
.
se
— это структурирующий элемент, определяющий окрестность изображения. Дополнительные сведения см. в описании функции strel
. Если элемент se
не указан, используется функция strel_box
с дополнительным именованным аргументом dims
, определяющим измерения для фильтрации, и половинным размером r
, определяющим размер ромба.
Примеры
julia> img = falses(5, 5); img[3, [2, 4]] .= true; img
5×5 BitMatrix:
0 0 0 0 0
0 0 0 0 0
0 1 0 1 0
0 0 0 0 0
0 0 0 0 0
julia> dilate(img)
5×5 BitMatrix:
0 0 0 0 0
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
0 0 0 0 0
julia> dilate(img; dims=1)
5×5 BitMatrix:
0 0 0 0 0
0 1 0 1 0
0 1 0 1 0
0 1 0 1 0
0 0 0 0 0
julia> dilate(img, strel_diamond(img)) # используем СЭ ромбовидной формы
5×5 BitMatrix:
0 0 0 0 0
0 1 0 1 0
1 1 1 1 1
0 1 0 1 0
0 0 0 0 0
См. также
!!! note "symmetricity"
Если элемент se
симметричен относительно начала координат, то есть se[b] == se[-b]
для любого b
, то расширение сводится к сумме Минковского: A⊕B={a+b|a∈A, b∈B}.
#
ImageMorphology.erode
— Function
out = erode(img; dims=coords_spatial(img), r=1)
out = erode(img, se)
Применяет фильтр минимума к окрестности img
, определяемой структурирующим элементом se
.
se
— это структурирующий элемент, определяющий окрестность изображения. Дополнительные сведения см. в описании функции strel
. Если элемент se
не указан, используется функция strel_box
с дополнительным именованным аргументом dims
, определяющим измерения для фильтрации, и половинным размером r
, определяющим размер ромба.
Примеры
julia> img = trues(5, 5); img[3, [2, 4]] .= false; img
5×5 BitMatrix:
1 1 1 1 1
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
1 1 1 1 1
julia> erode(img)
5×5 BitMatrix:
1 1 1 1 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 1 1 1
julia> erode(img; dims=1)
5×5 BitMatrix:
1 1 1 1 1
1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
1 1 1 1 1
julia> erode(img, strel_diamond(img)) # используем СЭ ромбовидной формы
5×5 BitMatrix:
1 1 1 1 1
1 0 1 0 1
0 0 0 0 0
1 0 1 0 1
1 1 1 1 1
См. также
!!! note "symmetricity"
Если элемент se
симметричен относительно начала координат, то есть se[b] == se[-b]
для любого b
, то эрозия сводится к разности Минковского: A⊖B={a-b|a∈A, b∈B}.
#
ImageMorphology.opening
— Function
opening(img; dims=coords_spatial(img), r=1)
opening(img, se)
Выполняет морфологическое открытие для img
. Операция открытия определяется как эрозия с последующим расширением: dilate(erode(img, se), se)
.
se
— это структурирующий элемент, определяющий окрестность изображения. Дополнительные сведения см. в описании функции strel
. Если элемент se
не указан, используется функция strel_box
с дополнительным именованным аргументом dims
, определяющим измерения для фильтрации, и половинным размером r
, определяющим размер ромба.
Примеры
julia> img = trues(7,7); img[2, 2] = false; img[3:5, 3:5] .= false; img[4, 4] = true; img
7×7 BitMatrix:
1 1 1 1 1 1 1
1 0 1 1 1 1 1
1 1 0 0 0 1 1
1 1 0 1 0 1 1
1 1 0 0 0 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
julia> opening(img)
7×7 BitMatrix:
0 0 1 1 1 1 1
0 0 1 1 1 1 1
1 1 0 0 0 1 1
1 1 0 0 0 1 1
1 1 0 0 0 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
julia> opening(img, strel_diamond(img)) # используем СЭ ромбовидной формы
7×7 BitMatrix:
1 1 1 1 1 1 1
1 0 1 1 1 1 1
1 1 0 0 0 1 1
1 1 0 0 0 1 1
1 1 0 0 0 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
См. также
#
ImageMorphology.closing
— Function
closing(img; dims=coords_spatial(img), r=1)
closing(img, se)
Выполняет морфологическое закрытие для img
. Операция закрытия определяется как расширение с последующей эрозией: erode(dilate(img, se), se)
.
se
— это структурирующий элемент, определяющий окрестность изображения. Дополнительные сведения см. в описании функции strel
. Если элемент se
не указан, используется функция strel_box
с дополнительным именованным аргументом dims
, определяющим измерения для фильтрации, и половинным размером r
, определяющим размер ромба.
Примеры
julia> img = falses(7,7); img[2, 2] = true; img[3:5, 3:5] .= true; img[4, 4] = false; img
7×7 BitMatrix:
0 0 0 0 0 0 0
0 1 0 0 0 0 0
0 0 1 1 1 0 0
0 0 1 0 1 0 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
julia> closing(img)
7×7 BitMatrix:
1 1 0 0 0 0 0
1 1 0 0 0 0 0
0 0 1 1 1 0 0
0 0 1 1 1 0 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
julia> closing(img, strel_diamond(img)) # # используем СЭ ромбовидной формы
7×7 BitMatrix:
0 0 0 0 0 0 0
0 1 0 0 0 0 0
0 0 1 1 1 0 0
0 0 1 1 1 0 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
См. также
#
ImageMorphology.tophat
— Function
tophat(img; dims=coords_spatial(img), r=1)
tophat(img, se)
Выполняет морфологическое преобразование «верх шляпы» (Top Hat) для данного изображения, то есть img - opening(img, se)
.
se
— это структурирующий элемент, определяющий окрестность изображения. Дополнительные сведения см. в описании функции strel
. Если элемент se
не указан, используется функция strel_box
с дополнительным именованным аргументом dims
, определяющим измерения для фильтрации, и половинным размером r
, определяющим размер ромба.
Это белое преобразование «верх шляпы» может использоваться для выделения небольших белых элементов и деталей на изображении. Для выделения черных деталей можно использовать черное преобразование «верх шляпы», также известное как преобразование «дно шляпы», bothat
.
Примеры
julia> img = falses(5, 5); img[1, 1] = true; img[3:5, 3:5] .= true; img
5×5 BitMatrix:
1 0 0 0 0
0 0 0 0 0
0 0 1 1 1
0 0 1 1 1
0 0 1 1 1
julia> Int.(tophat(img))
5×5 Matrix{Int64}:
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
julia> Int.(tophat(img, strel_diamond(img))) # используем СЭ ромбовидной формы
5×5 Matrix{Int64}:
1 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
#
ImageMorphology.bothat
— Function
bothat(img; dims=coords_spatial(img), r=1)
bothat(img, se)
Выполняет морфологическое преобразование «дно шляпы» (Bottom Hat) для данного изображения, то есть closing(img, se) - img
.
se
— это структурирующий элемент, определяющий окрестность изображения. Дополнительные сведения см. в описании функции strel
. Если элемент se
не указан, используется функция strel_box
с дополнительным именованным аргументом dims
, определяющим измерения для фильтрации, и половинным размером r
, определяющим размер ромба.
Преобразование «дно шляпы», также известное как черное преобразование «верх шляпы», может использоваться для выделения небольших черных элементов и деталей на изображении. Для выделения белых деталей можно использовать белое преобразование «верх шляпы», tophat
.
Примеры
julia> img = falses(7, 7); img[3:5, 3:5] .= true; img[4, 6] = true; img[4, 4] = false; img
7×7 BitMatrix:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 1 1 1 0 0
0 0 1 0 1 1 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
julia> Int.(bothat(img))
7×7 Matrix{Int64}:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 1 0 0 1
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
julia> Int.(bothat(img, strel_diamond(img))) # используем СЭ ромбовидной формы
7×7 Matrix{Int64}:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
Есть также выполняемая на месте версия: bothat!
.
#
ImageMorphology.morphogradient
— Function
imgmg = morphogradient(img; dims=coords_spatial(img))
returns morphological gradient of the image, which is the difference between the dilation and the erosion of a given image. dims
allows you to control the dimensions over which this operation is performed.
Examples
julia> img = zeros(7, 7); img[3:5, 3:5] .= 1.; img
7×7 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 1.0 1.0 1.0 0.0 0.0
0.0 0.0 1.0 1.0 1.0 0.0 0.0
0.0 0.0 1.0 1.0 1.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
julia> morphogradient(img)
7×7 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 1.0 1.0 1.0 1.0 1.0 0.0
0.0 1.0 1.0 1.0 1.0 1.0 0.0
0.0 1.0 1.0 0.0 1.0 1.0 0.0
0.0 1.0 1.0 1.0 1.0 1.0 0.0
0.0 1.0 1.0 1.0 1.0 1.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
#
ImageMorphology.morpholaplace
— Function
imgml = morpholaplace(img; dims=coords_spatial(img))
performs Morphological Laplacian
of an image, which is defined as the arithmetic difference between the internal and the external gradient. dims
allows you to control the dimensions over which this operation is performed.
Examples
julia> img = zeros(7, 7); img[3:5, 3:5] .= 1.; img[4, 4] = 0.; img
7×7 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 1.0 1.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0 1.0 0.0 0.0
0.0 0.0 1.0 1.0 1.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
julia> morpholaplace(img)
7×7 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 1.0 1.0 1.0 1.0 1.0 0.0
0.0 1.0 -1.0 -1.0 -1.0 1.0 0.0
0.0 1.0 -1.0 1.0 -1.0 1.0 0.0
0.0 1.0 -1.0 -1.0 -1.0 1.0 0.0
0.0 1.0 1.0 1.0 1.0 1.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
#
ImageMorphology.label_components
— Function
label = label_components(A; [dims=coords_spatial(A)], [r=1], [bkg])
label = label_components(A, se; [bkg])
Находит и маркирует связанные компоненты массива A
, где связь определяется структурирующим элементом se
. Каждому компоненту присваивается уникальное целочисленное значение в качестве метки, где 0
представляет фон, указанный в bkg
.
se
— это структурирующий элемент, определяющий окрестность изображения. Дополнительные сведения см. в описании функции strel
. Если элемент se
не указан, используется функция strel_box
с дополнительным именованным аргументом dims
, определяющим измерения для фильтрации, и половинным размером r
, определяющим размер ромба.
Примеры
julia> A = [false true false true false;
true false false true true]
2×5 Matrix{Bool}:
0 1 0 1 0
1 0 0 1 1
julia> label_components(A) # связь C4 по умолчанию ромбовидной формы
2×5 Matrix{Int64}:
0 2 0 3 0
1 0 0 3 3
julia> label_components(A; dims=2) # учитываются только строки
2×5 Matrix{Int64}:
0 2 0 3 0
1 0 0 4 4
julia> label_components(A, strel_box((3, 3))) # связь C8 прямоугольной формы
2×5 Matrix{Int64}:
0 1 0 2 0
1 0 0 2 2
Выполняемая на месте версия — label_components!
. Основные свойства маркируемых компонентов см. в описании component_boxes
, component_lengths
, component_indices
, component_centroids
.
#
ImageMorphology.component_boxes
— Function
boxes = component_boxes(labeled_array)
Вычисляет минимальные ограничивающие прямоугольники для каждой метки, включая метку фона. Метки можно вычислить с помощью функции label_components
.
Каждый ограничивающий прямоугольник представлен в виде CartesianIndices
. boxes
смещается в вектор с индексацией с нуля так, что фоновый участок равен boxes[0]
.
julia> A = [2 2 2 2 2; 1 1 1 0 1; 1 0 2 1 1; 1 1 2 2 2; 1 0 2 2 2]
5×5 Matrix{Int64}:
2 2 2 2 2
1 1 1 0 1
1 0 2 1 1
1 1 2 2 2
1 0 2 2 2
julia> label = label_components(A) # четыре несмежных компонента
5×5 Matrix{Int64}:
1 1 1 1 1
2 2 2 0 4
2 0 3 4 4
2 2 3 3 3
2 0 3 3 3
julia> boxes = component_boxes(label) # получаем ограничивающие прямоугольники всех участков
5-element OffsetArray(::Vector{CartesianIndices{2, Tuple{UnitRange{Int64}, UnitRange{Int64}}}}, 0:4) with eltype CartesianIndices{2, Tuple{UnitRange{Int64}, UnitRange{Int64}}} with indices 0:4:
CartesianIndices((2:5, 2:4))
CartesianIndices((1:1, 1:5))
CartesianIndices((2:5, 1:3))
CartesianIndices((3:5, 3:5))
CartesianIndices((2:3, 4:5))
julia> A[boxes[1]] # обрезаем участок изображения с меткой 1
1×5 Matrix{Int64}:
2 2 2 2 2
julia> A[boxes[4]] # обрезаем участок изображения с меткой 4
2×2 Matrix{Int64}:
0 1
1 1
#
ImageMorphology.component_lengths
— Function
counts = component_lengths(labeled_array)
Подсчитывает количество каждой метки во входном маркированном массиве. counts
смещается в вектор с индексацией с нуля так, что количество фоновых пикселей равно counts[0]
.
julia> A = [2 2 2 2 2; 1 1 1 0 1; 1 0 2 1 1; 1 1 2 2 2; 1 0 2 2 2]
5×5 Matrix{Int64}:
2 2 2 2 2
1 1 1 0 1
1 0 2 1 1
1 1 2 2 2
1 0 2 2 2
julia> label = label_components(A) # четыре несмежных компонента
5×5 Matrix{Int64}:
1 1 1 1 1
2 2 2 0 4
2 0 3 4 4
2 2 3 3 3
2 0 3 3 3
julia> component_lengths(label)
5-element OffsetArray(::Vector{Int64}, 0:4) with eltype Int64 with indices 0:4:
3
5
7
7
3
Для изображений в оттенках серого метки можно вычислить с помощью функции label_components
.
#
ImageMorphology.component_indices
— Function
indices = component_indices([T], labeled_array)
Возвращает индексы каждой метки во входном маркированном массиве. indices
смещается в вектор с индексацией с нуля так, что индексы фоновых пикселей равны indices[0]
.
Необязательным типом T
, определяющим тип индексов, может быть либо Int
/IndexLinear()
, либо CartesianIndex
/IndexCartesian()
. По умолчанию используется IndexStyle(labeled_array)
.
julia> A = [2 2 2 2 2; 1 1 1 0 1; 1 0 2 1 1; 1 1 2 2 2; 1 0 2 2 2]
5×5 Matrix{Int64}:
2 2 2 2 2
1 1 1 0 1
1 0 2 1 1
1 1 2 2 2
1 0 2 2 2
julia> label = label_components(A) # четыре несмежных компонента
5×5 Matrix{Int64}:
1 1 1 1 1
2 2 2 0 4
2 0 3 4 4
2 2 3 3 3
2 0 3 3 3
julia> indices = component_indices(label)
5-element OffsetArray(::Vector{Vector{Int64}}, 0:4) with eltype Vector{Int64} with indices 0:4:
[8, 10, 17]
[1, 6, 11, 16, 21]
[2, 3, 4, 5, 7, 9, 12]
[13, 14, 15, 19, 20, 24, 25]
[18, 22, 23]
julia> indices = component_indices(CartesianIndex, label)
5-element OffsetArray(::Vector{Vector{CartesianIndex{2}}}, 0:4) with eltype Vector{CartesianIndex{2}} with indices 0:4:
[CartesianIndex(3, 2), CartesianIndex(5, 2), CartesianIndex(2, 4)]
[CartesianIndex(1, 1), CartesianIndex(1, 2), CartesianIndex(1, 3), CartesianIndex(1, 4), CartesianIndex(1, 5)]
[CartesianIndex(2, 1), CartesianIndex(3, 1), CartesianIndex(4, 1), CartesianIndex(5, 1), CartesianIndex(2, 2), CartesianIndex(4, 2), CartesianIndex(2, 3)]
[CartesianIndex(3, 3), CartesianIndex(4, 3), CartesianIndex(5, 3), CartesianIndex(4, 4), CartesianIndex(5, 4), CartesianIndex(4, 5), CartesianIndex(5, 5)]
[CartesianIndex(3, 4), CartesianIndex(2, 5), CartesianIndex(3, 5)]
Для изображений в оттенках серого метки можно вычислить с помощью функции label_components
.
#
ImageMorphology.component_subscripts
— Function
component_subscripts(labeled_array)
-> массив пикселей для каждой метки, включая метку фона 0.
#
ImageMorphology.component_centroids
— Function
centroids = component_centroids(labeled_array)
Вычисляет центроид каждой метки во входном маркированном массиве. centroids
смещается в вектор с индексацией с нуля так, что центроид фоновых пикселей равен centroids[0]
.
Центроид конечного множества X
, также называемый геометрическим центром, вычисляется как sum(X)/length(X)
. Если дана метка i
, для построения множества X
используются все (декартовы) индексы пикселей с меткой i
.
julia> A = [2 2 2 2 2; 1 1 1 0 1; 1 0 2 1 1; 1 1 2 2 2; 1 0 2 2 2]
5×5 Matrix{Int64}:
2 2 2 2 2
1 1 1 0 1
1 0 2 1 1
1 1 2 2 2
1 0 2 2 2
julia> label = label_components(A) # четыре несмежных компонента
5×5 Matrix{Int64}:
1 1 1 1 1
2 2 2 0 4
2 0 3 4 4
2 2 3 3 3
2 0 3 3 3
julia> component_centroids(label)
5-element OffsetArray(::Vector{Tuple{Float64, Float64}}, 0:4) with eltype Tuple{Float64, Float64} with indices 0:4:
(3.3333333333333335, 2.6666666666666665)
(1.0, 3.0)
(3.142857142857143, 1.5714285714285714)
(4.285714285714286, 3.857142857142857)
(2.6666666666666665, 4.666666666666667)
Для изображений в оттенках серого метки можно вычислить с помощью функции label_components
.
#
ImageMorphology.FeatureTransform.feature_transform
— Function
feature_transform(img::AbstractArray{Bool, N};
weights=nothing, nthreads=Threads.nthreads()) -> F
Вычисляет преобразование признаков для двоичного изображения I
, находя «ближайший» признак (позиции, где I
имеет значение true
) для каждой позиции в I
. В частности, F[i]
— это объект CartesianIndex
, кодирующий ближайшую к i
позицию, для которой I[F[i]]
имеет значение true
. В случае если два или более признаков в I
находятся на одинаковом расстоянии от i
, один из них выбирается произвольным образом. Если в I
нет значений true
, все позиции сопоставляются с индексом, каждая координата которого равна typemin(Int)
.
При необходимости можно указать вес w
для каждой координаты. Например, если I
соответствует изображению с анизотропными вокселами, весом w
может быть интервал между вокселами по каждой координатной оси. Значение по умолчанию nothing
эквивалентно w=(1,1,...)
.
См. также описание функции distance_transform
.
Цитирование
-
[1] Maurer, Calvin R., Rensheng Qi, and Vijay Raghavan. A linear time algorithm for computing exact Euclidean distance transforms of binary images in arbitrary dimensions. IEEE Transactions on Pattern Analysis and Machine Intelligence 25.2 (2003): 265—270.
#
ImageMorphology.FeatureTransform.distance_transform
— Function
distance_transform(F::AbstractArray{CartesianIndex}, [w=nothing]) -> D
Вычисляет преобразование расстояний для F
, где каждый элемент F[i]
представляет местоположение «цели» или «признака», присвоенное i
. В частности, D[i]
— это расстояние между i
и F[i]
. При необходимости можно указать вес w
для каждой координаты. Значение по умолчанию nothing
эквивалентно w=(1,1,...)
.
См. также описание функции feature_transform
.
#
ImageMorphology.convexhull
— Function
chull = convexhull(img)
Вычисляет выпуклую оболочку двоичного изображения и возвращает ее вершины в виде массива элементов типа CartesianIndex.
#
ImageMorphology.GuoAlgo
— Type
struct GuoAlgo <: ThinAlgo end
Алгоритм Го оценивает три условия для определения того, какие пиксели изображения следует удалить.
Эти три условия описываются на странице 361 в работе Guo, Z., & Hall, R. W. (1989). Parallel thinning with two-subiteration algorithms. Communications of the ACM, 32(3), 359—373.
Пирамиды
#
Images.gaussian_pyramid
— Function
pyramid = gaussian_pyramid(img, n_scales, downsample, sigma)
Возвращает гауссову пирамиду масштабов n_scales
, каждый из которых подвергнут понижающей дискретизации с коэффициентом downsample
> 1 и sigma
для гауссова ядра.
Служебные средства для работы с метаданными изображений
#
ImageMetadata.ImageMeta
— Type
ImageMeta
— это массив AbstractArray, который может иметь метаданные, хранящиеся в словаре.
Строит изображение с помощью ImageMeta(A, props)
(для словаря свойств props
) или с помощью ImageMeta(A, prop1=val1, prop2=val2, ...)
.
#
ImageAxes.arraydata
— Function
arraydata(img::ImageMeta) -> array
Извлекает данные из img
, исключая словарь свойств. array
хранится в одной области памяти с img
, поэтому изменение одного объекта влияет на другой.
См. также описание функции properties
.
#
ImageMetadata.copyproperties
— Function
copyproperties(img::ImageMeta, data) -> imgnew
Создает новое «изображение», копируя словарь свойств из img
, но используя данные из массива data
типа AbstractArray. Обратите внимание, что изменение свойств imgnew
не влияет на свойства img
.
См. также описание функции shareproperties
.
shareproperties(img::ImageMeta, data) -> imgnew
Создает новое «изображение», используя словарь свойств из img
, но данные из массива data
типа AbstractArray. У двух изображений свойства синхронизированы: изменение свойств одного из них влияет на свойства другого.
См. также описание функции copyproperties
.
#
ImageMetadata.spatialproperties
— Function
spatialproperties(img)
Возвращает вектор строк с именами свойств, которые объявлены как «пространственные» и, следовательно, должны быть переставлены при вызове permutedims
. Такие свойства объявляются следующим образом:
img[:spatialproperties] = [:spacedirections]
Сегментация изображений
#
ImageSegmentation.SegmentedImage
— Type
Тип SegmentedImage
содержит сопоставление индексов и меток, присвоенные метки, среднюю интенсивность сегмента и количество пикселей в каждом сегменте.
#
ImageSegmentation.ImageEdge
— Type
edge = ImageEdge(index1, index2, weight)
Создает ребро графа смежности областей. index1
и index2
— это целые числа, соответствующие отдельным пикселям или вокселам (при линейном индексировании посредством sub2ind
), а weight
— вес ребра (соответствует расхождению между пикселями или вокселами).
#
Images.otsu_threshold
— Function
thres = otsu_threshold(img)
thres = otsu_threshold(img, bins)
Computes threshold for grayscale image using Otsu’s method.
Parameters:
-
img = Grayscale input image
-
bins = Number of bins used to compute the histogram. Needed for floating-point images.
#
ImageSegmentation.labels_map
— Function
img_labeled = labels_map(seg)
Возвращает массив с метками, присвоенными каждому пикселю.
#
ImageSegmentation.segment_labels
— Function
labels = segment_labels(seg)
Возвращает список присвоенных меток.
#
ImageSegmentation.segment_pixel_count
— Function
c = segment_pixel_count(seg, l)
Возвращает количество пикселей, которым присвоена метка l
. Если метка не указана, возвращает Dict(label=>pixel_count) всех меток.
#
ImageSegmentation.segment_mean
— Function
m = segment_mean(seg, l)
Возвращает среднюю интенсивность метки l
. Если метка не указана, возвращает Dict(label=>mean) всех меток.
#
ImageSegmentation.seeded_region_growing
— Function
seg_img = seeded_region_growing(img, seeds, [kernel_dim], [diff_fn])
seg_img = seeded_region_growing(img, seeds, [neighbourhood], [diff_fn])
Сегментирует N-мерное изображение img
, используя алгоритм выращивания областей от начальных точек, и возвращает объект SegmentedImage
с информацией о сегментах.
Аргументы:
-
img
: сегментируемое N-мерное изображение (допускаются произвольные оси). -
seeds
: объектVector
с начальными точками. Каждая начальная точка — это кортеж из
CartesianIndex{N} и метки. Дополнительные сведения о метках см. в примечании ниже.
-
kernel_dim
: (необязательно) векторVector{Int}
длиной N или кортежNTuple{N,Int}
,
i-й элемент которого — это нечетное положительное число, представляющее длину i-го ребра N-ортотопической окрестности.
-
neighbourhood
: (необязательно) функция, принимающая CartesianIndex{N} в качестве входных данных и
возвращающая окрестность этой точки.
-
diff_fn
: (необязательно) функция, которая возвращает меру различия (δ)
между средним цветом области и цветом точки.
Метки, присваиваемые точкам, должны быть положительными целыми числами, однако нескольким точкам можно присвоить одну и ту же метку. Выходные данные включают маркированный массив с теми же индексами, что и у входного изображения. Каждый индекс присваивается либо одной из меток, либо специальной метке 0, означающей, что алгоритму не удалось присвоить данный индекс уникальной метке. |
Примеры
julia> img = zeros(Gray{N0f8},4,4);
julia> img[2:4,2:4] .= 1;
julia> seeds = [(CartesianIndex(3,1),1),(CartesianIndex(2,2),2)];
julia> seg = seeded_region_growing(img, seeds);
julia> labels_map(seg)
4×4 Matrix{Int64}:
1 1 1 1
1 2 2 2
1 2 2 2
1 2 2 2
Цитирование
Albert Mehnert, Paul Jackaway (1997). An improved seeded region growing algorithm. Pattern Recognition Letters 18 (1997), 1065—1071
#
ImageSegmentation.unseeded_region_growing
— Function
seg_img = unseeded_region_growing(img, threshold, [kernel_dim], [diff_fn])
seg_img = unseeded_region_growing(img, threshold, [neighbourhood], [diff_fn])
Сегментирует N-мерное изображение, используя алгоритм автоматического выращивания областей (без начальных точек), и возвращает объект SegmentedImage
с информацией о сегментах.
Аргументы:
-
img
: сегментируемое N-мерное изображение (допускаются произвольные оси). -
threshold
: верхняя граница меры различия (δ) для определения
пикселя как относящегося к тому же сегменту.
-
kernel_dim
: (необязательно) векторVector{Int}
длиной N или кортежNTuple{N,Int}
,
i-й элемент которого — это нечетное положительное число, представляющее длину i-го ребра N-ортотопической окрестности.
-
neighbourhood
: (необязательно) функция, принимающая CartesianIndex{N} в качестве входных данных и
возвращающая окрестность этой точки.
-
diff_fn
: (необязательно) функция, которая возвращает меру различия (δ)
между средним цветом области и цветом точки.
Примеры
julia> img = zeros(Gray{N0f8},4,4);
julia> img[2:4,2:4] .= 1;
julia> seg = unseeded_region_growing(img, 0.2);
julia> labels_map(seg)
4×4 Matrix{Int64}:
1 1 1 1
1 2 2 2
1 2 2 2
1 2 2 2
#
ImageSegmentation.felzenszwalb
— Function
index_map, num_segments = felzenszwalb(edges, num_vertices, k, min_size=0)
Сегментирует изображение, представленное в виде графа смежности областей (RAG), используя алгоритм сегментации Фельценшвальба. Каждый пиксель или область соответствует узлу графа, а вес каждого ребра соответствует расхождению между пикселями. Функция возвращает количество сегментов и сопоставление индексов узлов RAG и сегментов.
Параметры:
-
edges
: массив ребер графа RAG. Каждое ребро представлено объектомImageEdge
. -
num_vertices
: количество вершин графа RAG. -
k
: порог для этапа слияния областей. Чем выше порог, тем больше сегменты. -
min_size
: минимальный размер сегмента (в пикселях).
segments = felzenszwalb(img, k, [min_size])
Сегментирует изображение, используя алгоритм сегментации Фельценшвальба, и возвращает результат в виде SegmentedImage
. Алгоритм использует евклидово расстояние в цветовом пространстве в качестве весов ребер для графа смежности областей.
Параметры:
-
img
: входное изображение. -
k
: порог для этапа слияния областей. Чем выше порог, тем больше сегменты. -
min_size
: минимальный размер сегмента (в пикселях).
#
ImageSegmentation.fast_scanning
— Function
seg_img = fast_scanning(img, threshold, [diff_fn])
Сегментирует N-мерное изображение, используя алгоритм быстрого сканирования, и возвращает объект SegmentedImage
с информацией о сегментах.
Аргументы:
-
img
: сегментируемое N-мерное изображение (допускаются произвольные оси). -
threshold
: верхняя граница меры различия (δ) для определения
пикселя как относящегося к тому же сегменту; можно передать AbstractArray
с тем же количеством измерений, что и у img
, для адаптивного определения порога.
-
diff_fn
: (необязательно) функция, которая возвращает меру различия (δ)
между средним цветом области и цветом точки.
Примеры:
julia> img = zeros(Float64, (3,3));
julia> img[2,:] .= 0.5;
julia> img[:,2] .= 0.6;
julia> seg = fast_scanning(img, 0.2);
julia> labels_map(seg)
3×3 Matrix{Int64}:
1 4 5
4 4 4
3 4 6
Цитирование
Jian-Jiun Ding, Cheng-Jin Kuo, Wen-Chih Hong. An efficient image segmentation technique by fast scanning and adaptive merging
#
ImageSegmentation.watershed
— Function
segments = watershed(img, markers; compactness, mask)
Сегментирует изображение с использованием преобразования по морфологическим водоразделам. Каждый бассейн, образованный путем преобразования по морфологическим водоразделам, соответствует сегменту. При использовании локальных минимумов изображения в качестве маркеров рекомендуется применять hmin_transform
, чтобы избежать чрезмерной сегментации.
Параметры:
-
img: входное изображение в оттенках серого.
-
markers: массив (того же размера, что и img), в котором каждому маркеру области присвоен индекс начиная с 1. Ноль означает, что это не маркер.
Если у двух маркеров одинаковый индекс, их области объединяются в одну область. Если маркеры заданы в виде массива логических значений, используйте label_components
.
-
compactness: используется компактный алгоритм морфологических водоразделов с заданным параметром компактности. Чем больше значения, тем более правильную
форму имеют бассейны.[1]
-
mask: сегментируются только те пиксели, для которых
mask
имеет значение true; используется для ограничения сегментации только областями интереса.
Пример
julia> seeds = falses(100, 100); seeds[50, 25] = true; seeds[50, 75] = true;
julia> dists = distance_transform(feature_transform(seeds)); # вычисляем расстояния между начальными точками
julia> markers = label_components(seeds); # присваиваем каждой начальной точке уникальный целочисленный идентификатор
julia> results = watershed(dists, markers);
julia> labels_map(results); # метки сегментированного изображения
#
ImageSegmentation.hmin_transform
— Function
out = hmin_transform(img, h)
Подавляет все минимумы на изображении в оттенках серого, глубина которых меньше h.
Преобразование методом H-минимумов определяется как реконструкция путем эрозии (img + h) по img. См. работу Morphological image analysis автора Pierre Soille, стр. 170—172.
#
ImageSegmentation.region_adjacency_graph
— Function
G, vert_map = region_adjacency_graph(seg, weight_fn)
Создает граф смежности областей (RAG) на основе SegmentedImage
. Возвращает RAG вместе с картой Dict(label=>vertex). weight_fn
служит для присвоения весов ребрам.
weight_fn(label1, label2)
Возвращает вещественное число, соответствующее весу ребра между label1 и label2.
#
ImageSegmentation.remove_segment
— Function
new_seg = remove_segment(seg, label, diff_fn)
Удаляет сегмент с меткой label
и возвращает новый объект SegmentedImage
. Дополнительные сведения см. в описании функции remove_segment!
.
#
ImageSegmentation.remove_segment!
— Function
remove_segment!(seg, label, diff_fn)
Удаляет сегмент с меткой label
на месте, заменяя его соседним сегментом с наименьшим значением diff_fn
.
d = diff_fn(rem_label, neigh_label)
Мера различия между удаляемой меткой и ее соседними элементами. isless
должно быть определено для объектов типа d
.
Примеры
# Удаляет метку `l` и заменяет ее меткой соседнего сегмента
# с максимальным количеством пикселей.
julia> remove_segment!(seg, l, (i,j)->(-seg.segment_pixel_count[j]))
# Удаляет метку `l` и заменяет ее меткой соседнего сегмента
# с наименьшим значением евклидовой метрики.
julia> remove_segment!(seg, l, (i,j)->sum(abs2, seg.segment_means[i]-seg.segment_means[j]))
#
ImageSegmentation.prune_segments
— Function
new_seg = prune_segments(seg, rem_labels, diff_fn)
Удаляет все сегменты с метками из rem_labels
, заменяя их соседним сегментом с наименьшим значением diff_fn
. rem_labels
— это вектор Vector
меток.
new_seg = prune_segments(seg, is_rem, diff_fn)
Удаляет все сегменты, для которых is_rem
возвращает значение true, заменяя их соседним сегментом с наименьшим значением diff_fn
.
is_rem(label) -> Bool
Возвращает true, если метку label
необходимо удалить; в противном случае возвращает false.
d = diff_fn(rem_label, neigh_label)
Мера различия между удаляемой меткой и ее соседними элементами. isless
должно быть определено для объектов типа d
.
#
ImageSegmentation.region_tree
— Function
t = region_tree(img, homogeneous)
Создает дерево областей на основе изображения img
, рекурсивно разбивая его до тех пор, пока все области не станут однородными.
b = homogeneous(img)
Возвращает true, если изображение img
является однородным.
Примеры
julia> img = 0.1*rand(6, 6);
julia> img[4:end, 4:end] .+= 10;
julia> function homogeneous(img)
min, max = extrema(img)
max - min < 0.2
end
homogeneous (generic function with 1 method)
julia> t = region_tree(img, homogeneous);
#
ImageSegmentation.region_splitting
— Function
seg = region_splitting(img, homogeneous)
Сегментирует изображение img
, рекурсивно разбивая его до тех пор, пока все сегменты не станут однородными.
b = homogeneous(img)
Возвращает true, если изображение img
является однородным.
Примеры
julia> img = 0.1*rand(6, 6);
julia> img[4:end, 4:end] .+= 10;
julia> function homogeneous(img)
min, max = extrema(img)
max - min < 0.2
end
homogeneous (generic function with 1 method)
julia> seg = region_splitting(img, homogeneous);
ImageFeatures
Геометрические признаки
#
ImageFeatures.hough_transform_standard
— Function
lines = hough_transform_standard(
img_edges::AbstractMatrix;
stepsize=1,
angles=range(0,stop=pi,length=minimum(size(img))),
vote_threshold=minimum(size(img)) / stepsize -1,
max_linecount=typemax(Int))
Возвращает вектор кортежей, соответствующих кортежам (r,t), где r и t — параметры для нормальной формы прямой: x * cos(t) + y * sin(t) = r
-
r
= длина перпендикуляра из точки (1,1) к прямой -
t
= угол между перпендикуляром из точки (1,1) к прямой и осью x
Прямые строятся путем применения преобразования Хафа к изображению.
Параметры:
-
img_edges
: преобразовываемое изображение (тип элементов должен бытьBool
) -
stepsize
: размер дискретного шага для длины перпендикуляра к прямой -
angles
: список углов, для которых вычисляется преобразование -
vote_threshold
: накопительный порог для обнаружения прямой -
max_linecount
: максимальное количество возвращаемых прямых
Пример
julia> using ImageFeatures
julia> img = fill(false,5,5); img[3,:] .= true; img
5×5 Array{Bool,2}:
false false false false false
false false false false false
true true true true true
false false false false false
false false false false false
julia> hough_transform_standard(img)
1-element Array{Tuple{Float64,Float64},1}:
(3.0, 1.5707963267948966)
#
ImageFeatures.hough_circle_gradient
— Function
circle_centers, circle_radius = hough_circle_gradient(img_edges, img_phase, radii; scale=1, min_dist=minimum(radii), vote_threshold)
Возвращает два вектора, соответствующие центрам и радиусам окружностей.
Окружности генерируются с помощью варианта преобразования Хафа, в котором ненулевая точка голосует только за центры окружностей, перпендикулярные локальному градиенту. В случае концентрических окружностей обнаруживается только самая большая окружность.
Параметры:
-
img_edges
: края изображения -
img_phase
: фаза градиентного изображения -
radii
: диапазон радиусов окружностей -
scale
: относительный накопительный коэффициент разложения -
min_dist
: минимальное расстояние между обнаруженными центрами окружностей -
vote_threshold
: накопительный порог для обнаружения окружностей
Пример
julia> using Images, ImageFeatures, FileIO, ImageView
julia> img = load(download("http://docs.opencv.org/3.1.0/water_coins.jpg"));
julia> img = Gray.(img);
julia> img_edges = canny(img, (Percentile(99), Percentile(80)));
julia> dx, dy=imgradients(img, KernelFactors.ando5);
julia> img_phase = phase(dx, dy);
julia> centers, radii = hough_circle_gradient(img_edges, img_phase, 20:30);
julia> img_demo = Float64.(img_edges); for c in centers img_demo[c] = 2; end
julia> imshow(img_demo)
Типы
#
ImageFeatures.Feature
— Type
feature = Feature(keypoint, orientation = 0.0, scale = 0.0)
Тип Feature
содержит ключевую точку, ее ориентацию и масштаб.
#
ImageFeatures.Features
— Type
features = Features(boolean_img)
features = Features(keypoints)
Возвращает вектор Vector{Feature}
признаков, сгенерированных из значений true
изображения в логической форме или из списка ключевых точек.
#
ImageFeatures.Keypoint
— Type
keypoint = Keypoint(y, x)
keypoint = Keypoint(feature)
Keypoint
можно создать путем передачи координат точки или на основе признака.
#
ImageFeatures.Keypoints
— Type
keypoints = Keypoints(boolean_img)
keypoints = Keypoints(features)
Создает вектор Vector{Keypoint}
на основе значений true
изображения в логической форме или на основе списка признаков.
#
ImageFeatures.BRIEF
— Type
brief_params = BRIEF([size = 128], [window = 9], [sigma = 2 ^ 0.5], [sampling_type = gaussian], [seed = 123])
Аргумент | Тип | Описание |
---|---|---|
size |
Int |
Размера дескриптора |
window |
Int |
Размер окна выборки |
sigma |
Float64 |
Значение сигмы, используемое для начального гауссова сглаживания изображения |
sampling_type |
Функция |
Тип выборки, используемый для построения дескриптора (см. раздел Шаблон выборки BRIEF) |
seed |
Int |
Для генерирования пар выборки используется случайное начальное значение. При сопоставлении двух дескрипторов начальное значение, которое использовалось для их построения, должно быть одинаковым. |
#
ImageFeatures.ORB
— Type
orb_params = ORB([num_keypoints = 500], [n_fast = 12], [threshold = 0.25], [harris_factor = 0.04], [downsample = 1.3], [levels = 8], [sigma = 1.2])
Аргумент | Тип | Описание |
---|---|---|
num_keypoints |
Int |
Количество извлекаемых ключевых точек и размер вычисляемого дескриптора |
n_fast |
Int |
Количество последовательных пикселей, используемых для поиска углов с помощью FAST. См. описание [ |
threshold |
Float64 |
Порог, используемый для нахождения углов в FAST. См. описание [ |
harris_factor |
Float64 |
Коэффициент Харриса |
downsample |
Float64 |
Параметр понижения дискретизации, используемый при построении гауссовой пирамиды. См. описание [ |
levels |
Int |
Количество уровней в гауссовой пирамиде. См. описание [ |
sigma |
Float64 |
Используется для гауссовского сглаживания на каждом уровне гауссовой пирамиды. См. описание [ |
#
ImageFeatures.FREAK
— Type
freak_params = FREAK([pattern_scale = 22.0])
Аргумент | Тип | Описание |
---|---|---|
pattern_scale |
Float64 |
Коэффициент масштабирования для окна выборки |
#
ImageFeatures.BRISK
— Type
brisk_params = BRISK([pattern_scale = 1.0])
Аргумент | Тип | Описание |
---|---|---|
|
|
Коэффициент масштабирования для окна выборки |
#
ImageFeatures.HOG
— Type
hog_params = HOG([orientations = 9], [cell_size = 8], [block_size = 2], [block_stride = 1], [norm_method = "L2-norm"])
Гистограмма направленных градиентов (HOG) — это плотный дескриптор признаков, обычно используемый для обнаружения объектов. См. работу Histograms of Oriented Gradients for Human Detection авторов Dalal и Triggs.
Параметры:
-
orientations: число столбцов ориентации
-
cellsize: размер ячейки равен cellsize x cell_size (в пикселях)
-
blocksize: размер блока равен blocksize x block_size (в ячейках)
-
block_stride: шаг блоков. Определяет то, насколько перекрываются смежные блоки.
-
norm_method: метод нормализации блоков. Параметры: L2-norm, L2-hys, L1-norm, L2-sqrt.
Углы
#
ImageFeatures.corner_orientations
— Function
orientations = corner_orientations(img)
orientations = corner_orientations(img, corners)
orientations = corner_orientations(img, corners, kernel)
Возвращает ориентации угловых участков изображения. Ориентация углового участка соответствует ориентации вектора между центроидом интенсивности и углом. Центроид интенсивности можно вычислить как C = (m01/m00, m10/m00)
, где mpq определяется как
`mpq = (x^p)(y^q)I(y, x) for each p, q in the corner patch`
Ядро, используемое для участка, можно задать посредством аргумента kernel
. По умолчанию используется гауссово ядро размером 5x5
.
Шаблоны выборки BRIEF
#
ImageFeatures.random_uniform
— Function
sample_one, sample_two = random_uniform(size, window, seed)
Создает пары выборки с использованием случайной равномерной выборки.
#
ImageFeatures.random_coarse
— Function
sample_one, sample_two = random_coarse(size, window, seed)
Создает пары выборки с использованием случайной выборки по грубой сетке.
#
ImageFeatures.gaussian
— Function
sample_one, sample_two = gaussian(size, window, seed)
Создает пары выборки с использованием гауссовой выборки.
#
ImageFeatures.gaussian_local
— Function
sample_one, sample_two = gaussian_local(size, window, seed)
Пары (Xi, Yi)
выбираются случайным образом с использованием гауссова распределения, причем сначала выбирается X
со среднеквадратичным отклонением 0.04*S^2
, а затем выбираются Yi’s
с использованием гауссова распределения — каждая точка Yi
выбирается со средним значением Xi
и среднеквадратичным отклонением 0.01 * S^2
.
#
ImageFeatures.center_sample
— Function
sample_one, sample_two = center_sample(size, window, seed)
Создает пары выборки (Xi, Yi)
, где Xi
— это точка (0, 0)
, а Yi
выбирается равномерно из окна.
Описание признака
#
ImageFeatures.create_descriptor
— Function
desc, keypoints = create_descriptor(img, keypoints, params)
desc, keypoints = create_descriptor(img, params)
Создает дескриптор для каждого элемента в keypoints
изображения img
. params
определяет параметры для любого из нескольких дескрипторов:
Некоторые дескрипторы поддерживают обнаружение keypoints
из fastcorners
.
Сопоставление признаков
#
ImageFeatures.hamming_distance
— Function
distance = hamming_distance(desc_1, desc_2)
Вычисляет расстояние Хэмминга между двумя дескрипторами.
#
ImageFeatures.match_keypoints
— Function
matches = match_keypoints(keypoints_1, keypoints_2, desc_1, desc_2, threshold = 0.1)
С помощью функции hamming_distance
находит соответствующие ключевые точки, расстояние между которыми меньше threshold
.