Документация Engee

Сводка и справка по функциям

Загрузка и сохранение изображений

FileIO.jl — это интерфейс ввода-вывода, который предоставляет функции save и load для легкой загрузки изображений. В настоящее время для файлов изображений доступны следующие бэкенды.

  • ImageMagick.jl охватывает большинство форматов изображений и имеет дополнительные возможности. Его можно выбрать первым, если у вас нет особых предпочтений.

  • QuartzImageIO.jl делает доступными собственные функции ввода-вывода изображений macOS в Julia. В некоторых случаях он быстрее, чем ImageMagick, но может удовлетворять не все потребности.

  • ImageIO.jl — это новый бэкенд ввода-вывода изображений (требуется Julia версии не ниже 1.3), который обеспечивает повышенную производительность для файлов PNG. Результат тестов производительности см. здесь.

  • OMETIFF.jl поддерживает файлы OME-TIFF. Если вы не знаете, что это такое, то, скорее всего, этот пакет вам не нужен.

Стандартные тестовые изображения доступны в пакете TestImages.jl

  • load(filename) загружает содержимое форматированного файла, пытаясь вывести формат из filename и (или) магических байтов в файле (см. описание функции query).

  • load(strm) загружает данные из IOStream или аналогичного объекта. В данном случае расширения имени файла нет, поэтому формат распознается на основе магических байтов.

  • load(File{format"PNG"}(filename)) задает формат напрямую; формат из query игнорируется.

  • load(Stream{format"PNG"}(io)) задает формат напрямую; формат из query игнорируется.

  • load(f; options...) передает именованные аргументы в метод загрузки.

  • save(filename, data...) сохраняет содержимое форматированного файла, пытаясь вывести формат из filename.

  • save(Stream{format"PNG"}(io), data...) задает формат напрямую; формат из query игнорируется.

  • save(File{format"PNG"}(filename), data...) задает формат напрямую; формат из query игнорируется.

  • save(f, data...; options...) передает именованные аргументы в метод сохранения.

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"

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 и т. д.) автоматически отображаются как изображения.

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)
channelview(A)

Возвращает представление массива A, разделяя (при необходимости) цветовые каналы A и помещая их в новое первое измерение.

Для таких типов, как RGB и BGR, каналы возвращаемого массива следуют в порядке аргументов конструктора, а не в порядке размещения в памяти (если требуется порядок размещения в памяти, см. reinterpretc).

Пример

img = rand(RGB{N0f8}, 10, 10)
A = channelview(img)   # массив 3×10×10

См. также описание colorview.

normedview([T], img::AbstractArray{Unsigned})

Возвращает «представление» изображения img, интерпретируя значения как числовые типы Normed. Например, если img — это Array{UInt8}, представление будет работать как Array{N0f8}. Если тип элементов img — UInt16, укажите в T нужный тип результата: N6f10, N4f12, N2f14 или N0f16.

См. также описание rawview.

rawview(img::AbstractArray{FixedPoint})

Возвращает «представление» изображения img, интерпретируя значения как базовый тип хранения. Например, если img — это Array{N0f8}, представление будет работать как Array{UInt8}.

См. также описание normedview.

StackedView(B, C, ...) -> A

Представляет массивы B, C и т. д. как отдельные каналы по первому измерению A. В частности,

B == A[1,:,:...]
C == A[2,:,:...]

и т. д. В сочетании с colorview позволяет объединять два или более изображений в оттенках серого в одно цветное.

См. также описание функции colorview.

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
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
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
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
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.

Эта функция не является устойчивой по типу, поэтому ее следует использовать только в том случае, если производительность не имеет первостепенного значения. Для оптимальной производительности объекты MosaicView следует создавать вручную.

Примеры

Простейший вариант использования — применение 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
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")

Типажи

Эти функции являются предпочтительным способом доступа к определенным типам «внутренних» данных об изображении. Иногда они могут быть полезны для написания универсального кода.

pixelspacing(img) -> (sx, sy, ...)

Возвращает кортеж, представляющий расстояние между соседними пикселями по каждой оси изображения. По умолчанию (1,1,…​). Используйте ImagesAxes для изображений с анизотропными интервалами или для кодирования интервала с использованием физических единиц.

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), причем интервал задается по «диагонали». При необходимости можно задать это свойство в физических единицах, причем у каждой оси они могут быть своими.

sdims(img)

Возвращает количество пространственных измерений на изображении. По умолчанию результат тот же, что и у ndims, но при использовании ImagesAxes можно указать, что некоторые оси соответствуют другим величинам (например, времени) и поэтому не учитываются sdims.

coords_spatial(img)

Возвращает кортеж с пространственными измерениями img.

Обратите внимание, что более эффективной стратегией может быть использование ImagesAxes и создание срезов по оси времени.

size_spatial(img)

Возвращает кортеж с размерами пространственных измерений изображения. По умолчанию результат тот же, что и у size, но при использовании ImagesAxes можно пометить некоторые оси как непространственные.

indices_spatial(img)

Возвращает кортеж с индексами пространственных измерений изображения. По умолчанию результат тот же, что и у indices, но при использовании ImagesAxes можно пометить некоторые оси как непространственные.

nimages(img)

Возвращает количество временных точек в массиве изображения. По умолчанию

  1. Если требуется явное измерение времени, используйте ImagesAxes.

timeaxis(A)

Возвращает ось времени массива A, если она есть, или nothing в противном случае.

istimeaxis(ax)

Проверяет, соответствует ли ось ax времени.

timedim(img) -> d::Int

Возвращает измерение массива, используемое для кодирования времени, или 0, если для этой цели ось не используется.

Обратите внимание: для восстановления информации об оси времени обычно лучше использовать timeaxis.

assert_timedim_last(img)

Выдает ошибку, если у изображения есть измерение времени и оно не последнее.

style = StreamIndexStyle(A)

Типаж, указывающий степень поддержки индексирования потоковых осей A. Возможные варианты: IndexAny() и IndexIncremental() (для массивов, которые допускают продвижение только по оси времени, например видеопотока с веб-камеры). Значение по умолчанию — IndexAny().

Специализация должна производиться для типа, а не для экземпляра. Для объекта StreamingContainer S этот типаж можно определить следующим образом:

StreamIndexStyle(::Type{P}, ::typeof(f!)) = IndexIncremental()

где P = typeof(parent(S)).

IndexAny()

Указывает, что ось поддерживает полное индексирование с произвольным доступом.

IndexIncremental()

Указывает, что ось поддерживает только инкрементное индексирование, то есть от i к i+1. Обычно используется для временной оси в потоках мультимедиа.

Преобразование элементов и масштабирование интенсивности

clamp01(x) -> y

Выдает значение y в диапазоне от 0 до 1, которое равно x, если x уже находится в этом диапазоне. Эквивалентно clamp(x, 0, 1) для числовых значений. В случае с цветами эта функция применяется к каждому цветовому каналу отдельно.

См. также описание функций clamp01!, clamp01nan.

clamp01!(array::AbstractArray)

Ограничивает значения в массиве интервалом [0, 1] на месте. См. также описание функции clamp01.

clamp01nan(x) -> y

То же, что и clamp01, но все значения NaN изменяются на 0.

См. также описание функций clamp01nan!, clamp01.

clamp01nan!(array::AbstractArray)

То же, что и clamp01!, но все значения NaN изменяются на 0.

См. также описание функций clamp01!, clamp01nan.

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.

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.

colorsigned()
colorsigned(colorneg, colorpos) -> f
colorsigned(colorneg, colorcenter, colorpos) -> f

Определяет функцию, которая сопоставляет отрицательные значения (в диапазоне [-1,0]) с линейной цветовой картой от colorneg до colorcenter, а положительные значения (в диапазоне [0,1]) — с линейной цветовой картой от colorcenter до colorpos.

Цвета по умолчанию:

  • colorcenter: белый

  • colorneg: зеленый 1

  • colorpos: пурпурный

См. также описание функции scalesigned.

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

Преобразование типа хранения

float32.(img)

Преобразует базовый тип хранения img в Float32, не изменяя цветовое пространство.

float64.(img)

Преобразует базовый тип хранения img в Float64, не изменяя цветовое пространство.

n0f8.(img)

Преобразует базовый тип хранения img в N0f8, не изменяя цветовое пространство.

n6f10.(img)

Преобразует базовый тип хранения img в N6f10, не изменяя цветовое пространство.

n4f12.(img)

Преобразует базовый тип хранения img в N4f12, не изменяя цветовое пространство.

n2f14.(img)

Преобразует базовый тип хранения img в N2f14, не изменяя цветовое пространство.

n0f16.(img)

Преобразует базовый тип хранения img в N0f16, не изменяя цветовое пространство.

Цветовые каналы

Вы можете извлечь числовые значения определенных цветовых каналов:

gray(c) возвращает серый компонент непрозрачного или прозрачного цвета изображения в оттенках серого.

red(c) возвращает красный компонент непрозрачного или прозрачного цвета изображения AbstractRGB.

green(c) возвращает зеленый компонент непрозрачного или прозрачного цвета изображения AbstractRGB.

blue(c) возвращает синий компонент непрозрачного или прозрачного цвета изображения AbstractRGB.

alpha(p) извлекает альфа-компонент цвета. Для цвета без альфа-канала всегда возвращает 1.

Можно также выполнять операции с каналами:

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)
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 есть альфа-канал, он всегда подлежит редукции последним.

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.

Алгоритмы обработки изображений

Линейная фильтрация

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 (недоступно). Лучше всего подходит для фильтров только с положительными весами, например фильтров размытия.

См. также описание Pad, padarray, Inner, NA и NoPad.

Варианты для alg

Параметр alg позволяет выбрать алгоритм: Algorithm.FIR() (конечная импульсная характеристика, то есть традиционная цифровая фильтрация) или Algorithm.FFT() (фильтрация методом Фурье). Если алгоритм не указан, он выбирается с учетом размера изображения и ядра так, чтобы обеспечивалась высокая производительность. Помимо этого, можно использовать фильтр пользовательского типа, например KernelFactors.IIRGaussian.

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.

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...)

Ядро

    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.

    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.

    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.

    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.

    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.

gaussian((σ1, σ2, ...), [(l1, l2, ...)]) -> g
gaussian(σ)                  -> g

Создает многомерный фильтр Гаусса со среднеквадратичным отклонением σd по измерению d. Можно также указать длину ядра l в виде кортежа той же длины.

Если значение σ задано в виде одного числа, возвращается симметричное двухмерное ядро.

См. также описание функции KernelFactors.gaussian.

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.

LoG((σ1, σ2, ...)) -> k
LoG(σ)             -> k

Создает ядро на основе лапласиана гауссиана k. σd — это ширина гауссиана по измерению d. Если значение σ задано в виде одного числа, возвращается симметричное двухмерное ядро.

См. также описание функций KernelFactors.IIRGaussian и Kernel.Laplacian.

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

Laplacian((true,true,false,...))
Laplacian(dims, N)
Laplacian()

Ядро на основе лапласиана в N измерениях, принимающее производные в направлениях, помеченных как true в переданном кортеже. В аргументе dims можно также передать список измерений для дифференцирования. (Однако такой вариант не является выводимым.)

Laplacian() — это двухмерный лапласиан, эквивалентный Laplaciantrue,true.

Ядро представлено как непрозрачный тип, но с помощью функции convert(AbstractArray, L) его можно преобразовать в формат массива.

    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.

    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

    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.

    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.

    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.

    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.

    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 по соответствующему измерению.

gaussian(σ::Real, [l]) -> g

Создает одномерное гауссово ядро g со среднеквадратичным отклонением σ; при необходимости можно указать длину ядра l. По умолчанию ядро простирается на два σ в каждом направлении от центра. Значение l должно быть нечетным.

gaussian((σ1, σ2, ...), [l]) -> (g1, g2, ...)

Создает многомерный фильтр Гаусса как произведение одномерных множителей со среднеквадратичным отклонением σd по измерению d. Можно также указать длину ядра l в виде кортежа той же длины.

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).

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.

    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.

    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.

Служебные средства для ядер

kernelfactors(factors::Tuple)

Подготавливает разложенное ядро для фильтрации. Если передан кортеж из двух векторов длиной m и n, возвращается кортеж из двух векторов ReshapedVector, имеющих размеры m×1 и 1×n. В общем случае форма каждого следующего множителя factor изменяется так, чтобы он простирался вдоль соответствующего измерения.

Если передан кортеж общих массивов, предполагается, что каждый из них имеет соответствующую форму вдоль «ведущих» измерений; размерность каждого массива «расширяется» до N = length(factors) с добавлением значений 1 к размеру при необходимости.

reflect(kernel) --> reflectedkernel

Вычисляет поточечное отражение относительно 0, 0, …​ ядра kernel. При использовании imfilter с reflectedkernel выполняется свертка, а не корреляция, относительно исходного ядра kernel.

Границы и дополнение

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 и Fill.

Примеры

Дополнение

Основной синтаксис для 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)))
    struct Pad{N} <: AbstractBorder
        style::Symbol
        lo::Dims{N}    # число, на которое следует расширить изображение с нижнего края каждого измерения
        hi::Dims{N}    # число, на которое следует расширить изображение с верхнего края каждого измерения
    end

Pad — это тип, определяющий форму дополнения, которая должна использоваться для экстраполяции пикселей за границами изображения. В экземплярах должен быть задан style, символ, определяющий граничные условия изображения.

Вывод

Тип Pad, определяющий способ дополнения границы изображения.

Расширенная справка

Когда операция фильтрации двухмерного пространственного изображения представлена в виде дискретной свертки между изображением и фильтром , результаты не определены для пикселей, которые находятся ближе пикселей к границе изображения. Чтобы определить операцию для пикселей, находящихся ближе к границе и на ней, требуется схема экстраполяции пикселей за границей. Тип Pad позволяет указать необходимую схему экстраполяции.

Этот тип упрощает дополнение одно-, двух- или многомерных изображений.

Можно указать другую степень дополнения на нижней и верхней границах каждого измерения изображения (верхней, левой, нижней и правой границах в двух измерениях).

Параметры

Ниже описываются некоторые допустимые варианты style. Для иллюстрации результаты дополнения с использованием каждого варианта показаны на примере изображения, состоящего из строки из шести пикселей, которые следуют по алфавиту:

        ┏━━━━━━┓
        ┃abcdef┃
        ┗━━━━━━┛

Результат дополнения демонстрируется только на левой и правой границах, но для верхней и нижней границ результат будет аналогичным.

:replicate (по умолчанию)

Пиксели границы продолжаются за границами изображения.

   ╭────┏━━━━━━┓────╮
   │aaaa┃abcdef┃ffff│
   ╰────┗━━━━━━┛────╯

См. также описание Fill, padarray, Inner и NoPad.

:circular

Пиксели границы переносятся в противоположную сторону. Например, при обращении по индексам за пределами левой границы возвращаются значения начиная с правой границы.

   ╭────┏━━━━━━┓────╮
   │cdef┃abcdef┃abcd│
   ╰────┗━━━━━━┛────╯

См. также описание Fill, padarray, Inner и NoPad.

:symmetric

Пиксели границы отражаются относительно позиции между пикселями. Пиксель границы при этом опускается.

   ╭────┏━━━━━━┓────╮
   │edcb┃abcdef┃edcb│
   ╰────┗━━━━━━┛────╯

:reflect

Пиксели границы отражаются относительно края изображения.

   ╭────┏━━━━━━┓────╮
   │dcba┃abcdef┃fedc│
   ╰────┗━━━━━━┛────╯

См. также описание Fill, padarray, Inner и NoPad.

struct Fill{T,N} <: AbstractBorder
    value::T
    lo::Dims{N}
    hi::Dims{N}
end

Fill — это тип, определяющий конкретное значение, которое будет использоваться для экстраполяции пикселей за границами изображения.

Вывод

Тип Fill, определяющий значение, которым будет дополняться граница изображения.

Подробные сведения

Когда операция фильтрации двухмерного пространственного изображения представлена в виде дискретной свертки между изображением и фильтром , результаты не определены для пикселей, которые находятся ближе пикселей к границе изображения. Чтобы определить операцию для пикселей, находящихся ближе к границе и на ней, требуется схема экстраполяции пикселей за границей. Тип Fill позволяет указать конкретное значение, которое будет использоваться при экстраполяции. Подробные схемы экстраполяции см. в описании типа Pad.

Этот тип упрощает дополнение одно-, двух- или многомерных изображений.

Можно указать другую степень дополнения на нижней и верхней границах каждого измерения изображения (верхней, левой, нижней и правой границах в двух измерениях).

Пример

Для иллюстрации рассмотрим изображение, состоящее из строки из шести пикселей, которые следуют по алфавиту:

    ┏━━━━━━┓
    ┃abcdef┃
    ┗━━━━━━┛

Дополнение постоянным значением m только на левой и правой границах выглядит следующим образом:

╭────┏━━━━━━┓────╮
│mmmm┃abcdef┃mmmm│
╰────┗━━━━━━┛────╯

(Аналогичным будет результат и для верхней и нижней границ.)

См. также описание Pad, padarray, Inner и NoPad.

Inner()
Inner(lo, hi)

Указывает, что края при фильтрации должны отбрасываться: возвращается только внутренняя часть результата.

Пример:

imfilter(img, kernel, Inner())
NA(na=isnan)

Выбор фильтрации с использованием граничных условий NA (недоступно). Лучше всего подходит для фильтров только с положительными весами, например фильтров размытия. Выходное значение фактически нормализуется следующим образом:

          filtered array with Fill(0) boundary conditions
output =  -----------------------------------------------
          filtered 1     with Fill(0) boundary conditions

Элементы массива, для которых na возвращает значение true, также считаются находящимися за границами массива.

NoPad()
NoPad(border)

Указывает, что дополнение не должно применяться ко входному массиву или что входное изображение уже предварительно дополнено. Передача объекта border позволяет сэкономить память на выборе границы; его можно получить по индексу в [].

Пример

Следующие команды:

np = NoPad(Pad(:replicate))
imfilter!(out, img, kernel, np)

позволяют выполнить фильтрацию напрямую, пропустив дополнение. Каждый элемент out должен быть вычислим с использованием операций в пределах границ с img и kernel.

Алгоритмы

Выполняет фильтрацию с использованием прямого алгоритма.

Выполняет фильтрацию с использованием быстрого преобразования Фурье.

Выполняет фильтрацию с использованием фильтра с бесконечной импульсной характеристикой.

Выполняет фильтрацию с использованием каскада смешанных типов (БИХ, КИХ).

Внутренние механизмы

ReshapedOneD{N,Npre}(data)

Возвращает объект размерности N, где data должно иметь размерность 1. Он имеет оси 0:0 для первых Npre измерений, оси data для измерения Npre+1 и оси 0:0 для оставшихся измерений.

Объект data должен поддерживать eltype и ndims, но не обязательно должен быть массивом AbstractArray.

ReshapedOneDs позволяет указать «измерение фильтрации» для одномерного фильтра.

Нелинейная фильтрация и преобразование

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.

Обнаружение краев

m = magnitude(grad_x, grad_y)

Вычисляет величину градиентных изображений, заданных посредством grad_x и grad_y. Эквивалентно sqrt(grad_x.^2 + grad_y.^2).

Возвращает изображение величины того же размера, что и grad_x и grad_y.

phase(grad_x, grad_y) -> p

Вычисляет угол поворота градиента, заданного посредством grad_x и grad_y. Эквивалентно atan(-grad_y, grad_x) за тем исключением, что если и grad_x, и grad_y равны нулю, соответствующий угол задается равным нулю.

orientation(grad_x, grad_y) -> orient

Вычисляет угол ориентации наиболее интенсивного края градиентных изображений, заданных посредством grad_x и grad_y. Эквивалентно atan(grad_x, grad_y). Если и grad_x, и grad_y равны нулю, соответствующий угол задается равным нулю.

magnitude_phase(grad_x, grad_y) -> m, p

Вспомогательная функция для вычисления величины и фазы градиентных изображений, заданных посредством grad_x и grad_y. Возвращает кортеж, содержащий изображения величины и фазы. Подробные сведения см. в описании magnitude и phase.

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), содержащий соответственно горизонтальный градиент, вертикальный градиент, а также величину и ориентацию самого интенсивного края.

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)
canny_edges = canny(img, (upper, lower), sigma=1.4)

Выполняет обнаружение краев методом Кэнни на входном изображении.

Параметры:

(upper, lower): границы для сигмы порога гистерезиса; определяет среднеквадратичное отклонение гауссова фильтра

Пример

imgedg = canny(img, (Percentile(80), Percentile(20)))
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

Обнаружение углов

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.

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.

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.

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.

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.

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.

В BlobLoG хранится информация о положении пиков, обнаруженных функцией blob_LoG. Поля этого типа следующие:

  • location: положение пика на отфильтрованном изображении (CartesianIndex)

  • σ: значение σ, которое приводит к наибольшей отфильтрованной методом -LoG амплитуде в данном положении

  • amplitude: значение отфильтрованного методом -LoG(σ) изображения в положении пика

Обратите внимание, что радиус равен σ√2.

См. также описание функции blob_LoG.

findlocalmaxima(img; window=default_window(img), edges=true) -> Vector{CartesianIndex}

Возвращает координаты элементов, значения которых больше, чем у всех смежных с ними элементов. edges — это логическое значение, указывающее, следует ли включать первый и последний элементы каждого измерения, или кортеж логических значений, определяющий поведение на границах для каждого измерения по отдельности.

default_window имеет значение 3 для каждого пространственного измерения img и значение 1 в остальных случаях, что подразумевает нахождение максимумов среди смежных элементов по умолчанию в каждом пространственном «срезе».

findlocalminima(img; window=default_window(img), edges=true) -> Vector{CartesianIndex}

Аналогично findlocalmaxima, но возвращает координаты наименьших элементов.

Экспозиция

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.

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!.

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.

    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, которую мы обозначим как . В самом общем случае потребуется четыре функции CDF:

Чтобы определить, какие именно функции CDF будут использоваться на этапе интерполяции, полезно (i) ввести функцию

(ii) построить последовательности и и (iii) определить

Случай I (внутренняя часть)

Для пикселя в диапазоне

значения и неявно определяются решением неравенств

Билинейное интерполяционное преобразование, которое сопоставляет интенсивность в точке на изображении с интенсивностью , задается следующей формулой [3]:

Случай II (вертикальная граница)

Для пикселя в диапазоне

неявно определяется решением неравенств , а

Линейное интерполяционное преобразование, которое сопоставляет интенсивность в точке на изображении с интенсивностью , задается следующей формулой:

Случай III (горизонтальная граница)

Для пикселя в диапазоне

неявно определяется решением неравенств , а

Линейное интерполяционное преобразование, которое сопоставляет интенсивность в точке на изображении с интенсивностью , задается следующей формулой:

Случай IV (углы)

Для пикселя в диапазоне

верно следующее:

Преобразование, которое сопоставляет интенсивность в точке на изображении с интенсивностью , задается следующей формулой:

Ограничение контрастности

Неприятным побочным эффектом усиления контрастности является тенденция к увеличению уровня шума на изображении, особенно когда величина усиления контрастности очень высока. Величина усиления контрастности связана с градиентом , так как градиент определяет степень, в которой последовательные входные уровни интенсивности растягиваются по спектру уровней серого. Уровень усиления шума можно снизить, ограничив величину усиления контрастности, то есть величину градиента.

Так как производная является эмпирической плотностью , наклон функции сопоставления при любой входной интенсивности пропорционален высоте гистограммы при данной интенсивности. Таким образом, ограничение наклона функции локального сопоставления равносильно обрезанию гистограммы по высоте. Подробное описание того, как реализован процесс обрезания, см. в работе [2].

Параметры

Различные варианты параметров этой функции более подробно описываются ниже.

Варианты для 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)

Справочные материалы

  1. R. C. Gonzalez and R. E. Woods. Digital Image Processing (3rd Edition). Upper Saddle River, NJ, USA: Prentice-Hall, 2006.

  2. 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

  3. 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.

    Equalization <: AbstractHistogramAdjustmentAlgorithm
    Equalization(; nbins = 256, minval = 0, maxval = 1)

    adjust_histogram([T,] img, f::Equalization)
    adjust_histogram!([out,] img, f::Equalization)

Возвращает изображение с выровненной гистограммой с детальностью (числом столбцов) nbins.

Подробные сведения

Выравнивание гистограммы изначально задумывалось для улучшения контрастности на одноканальном изображении в оттенках серого. Данный метод преобразует распределение уровней интенсивности на изображении так, чтобы оно было максимально равномерным [1]. Естественным обоснованием этой равномерности является то, что изображение имеет лучшую контрастность, если уровни интенсивности на нем охватывают широкий диапазон. Как оказалось, необходимое преобразование представляет собой сопоставление на основе кумулятивной гистограммы.

-битное одноканальное изображение размером со значениями серого из множества можно рассматривать как совокупность независимых и одинаково распределенных случайных величин. В частности, пусть пространство выборок будет множеством всех кортежей , где каждый элемент . Кроме того, введем для вероятностную меру такую, что функции будут независимыми и одинаково распределенными.

Тогда изображение можно рассматривать как матрицу случайных величин ], где каждая функция определяется как

а каждая функция распределяется с некоторой известной плотностью . Хотя функция неизвестна, ее можно аппроксимировать с помощью нормализованной гистограммы уровней серого:

где

представляет количество раз, которое уровень серого с интенсивностью встречается в . Чтобы преобразовать распределение уровней интенсивности так, чтобы оно было максимально равномерным, необходимо найти сопоставление такое, что . Требуемое сопоставление оказывается интегральной функцией распределения (CDF) эмпирической плотности :

Параметры

Различные варианты параметров функции 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)

Справочные материалы

  1. R. C. Gonzalez and R. E. Woods. Digital Image Processing (3rd Edition). Upper Saddle River, NJ, USA: Prentice-Hall, 2006.

    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)

Справочные материалы

  1. W. Burger and M. J. Burge. Digital Image Processing. Texts in Computer Science, 2016. doi:10.1007/978-1-4471-6684-9

    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)

Справочные материалы

  1. W. Burger and M. J. Burge. Digital Image Processing. Texts in Computer Science, 2016. doi:10.1007/978-1-4471-6684-9

    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]. Оказывается, решение этой задачи преобразования включает в себя интегральные и обратные интегральные функции распределения исходной и целевой функций плотности вероятности.

В частности, пусть случайные величины и представляют интенсивность на исходном и целевом изображениях соответственно, и пусть

представляет сопутствующие интегральные функции распределения. Тогда искомое сопоставление такое, что , описывается формулой

где is the inverse cumulative distribution function of .

Данная формула предполагает, что сопоставление с гистограммой можно представить как выравнивание гистограмм исходного и целевого изображений и соотнесение этих двух выровненных гистограмм. Дополнительные сведения о выравнивании гистограмм см. в описании функции 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)

Справочные материалы

  1. W. Burger and M. J. Burge. Digital Image Processing. Texts in Computer Science, 2016. doi:10.1007/978-1-4471-6684-9

    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). Оказывается, решение этой задачи преобразования включает в себя интегральные и обратные интегральные функции распределения исходной и «средней» функций плотности вероятности. В частности, пусть случайные величины и представляют интенсивность на первом, втором и «среднем» изображениях соответственно, и пусть

представляют соответственно интегральные функции распределения двух входных изображений и их гармоническое среднее. Тогда искомое сопоставление such that описывается формулой

где is the inverse cumulative distribution function of .

Параметры

Различные варианты параметров функции 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)

Справочные материалы

  1. 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

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.

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.

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).

Пространственные преобразования и изменение размера

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 фильтр низких частот.

Аргументы

  • img: входной массив изображения

  • sz: размер выходного массива

  • inds: оси выходного массива. Если аргумент inds передан, выходной массив imgr будет иметь тип OffsetArray.

Параметры

Для создания method может потребоваться сначала загрузить пакет Interpolations.

  • 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 будет гораздо более быстрой реализацией.

imrotate(img, θ, [indices]; kwargs...) -> imgr

Поворачивает изображение img на θ∈[0,2π) по часовой стрелке вокруг центральной точки.

Аргументы

  • img::AbstractArray: исходное изображение, которое необходимо повернуть.

  • θ::Real: угол поворота по часовой стрелке. Чтобы повернуть изображение против часовой стрелки, используйте отрицательное значение. Чтобы повернуть изображение на d градусов, используйте формулу θ=d*π/180.

  • indices (необязательно): указывает оси выходного изображения. По умолчанию повернутое изображение imgr не обрезается, поэтому равенство axes(imgr) == axes(img) в общем случае не выполняется.

Параметры

Для построения значений method и fillvalue может потребоваться сначала загрузить пакет Interpolations.

  • 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)
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 и fillvalue может потребоваться сначала загрузить пакет Interpolations.

  • method::Union{Degree, InterpolationType}: метод интерполяции, который необходимо использовать. По умолчанию BSpline(Linear()). Для создания экземпляра метода может потребоваться загрузить пакет Interpolations.

  • fillvalue: значение, используемое для заполнения новой области. Значение по умолчанию — NaN, если это возможно; в противном случае — 0. Можно также передать граничное условие экстраполяции: Flat(), Reflect() и Periodic().

Дополнительные материалы

Существуют высокоуровневые интерфейсы warp:

  • поворот изображения: imrotate;

  • изменение размера изображения: imresize.

Есть также отложенные версии warp:

  • WarpedView is almost equivalent to warp 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.

Если img — это объект AbstractExtrapolation, дополнительные именованные аргументы method и fillvalue игнорируются.

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

Из соображений производительности рекомендуется передавать позиционный аргумент inds в warp вместо обрезки выходных данных с помощью imgw[inds...].

Примеры: поворот двухмерного изображения

В этом примере показано только, как создать tform и вызвать warp. В общем случае рекомендуется использовать функцию imrotate напрямую.

Поворот вокруг центра 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))
WarpedView(img, tform, [indices]; kwargs...) -> wv

Создает представление img, которое выполняет отложенное преобразование любого заданного индекса I, переданного в wv[I], так, что wv[I] == img[tform(I)].

Это отложенная версия warp на основе представления. Дополнительные сведения см. в описании warp.

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.

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

euclidean(x, y)

sqrt(sum((x - y) .^ 2))

SqEuclidean

sqeuclidean(x, y)

sum((x - y).^2)

Cityblock

cityblock(x, y)

sum(abs(x - y))

TotalVariation

totalvariation(x, y)

sum(abs(x - y)) / 2

Minkowski

minkowski(x, y, p)

sum(abs(x - y).^p) ^ (1/p)

Hamming

hamming(x, y)

sum(x .!= y)

SumAbsoluteDifference

sad(x, y)

sum(abs(x - y))

SumSquaredDifference

ssd(x, y)

sum((x - y).^2)

MeanAbsoluteError

mae(x, y), sadn(x, y)

sum(abs(x - y))/len(x)

MeanSquaredError

mse(x, y), ssdn(x, y)

sum((x - y).^2)/len(x)

RootMeanSquaredError

rmse(x, y)

sqrt(sum((x - y) .^ 2))

NCC

ncc(x, y)

dot(x,y)/(norm(x)*norm(y))

Расстояния, относящиеся к изображениям

Тип расстояния Удобный синтаксис Справочные материалы

Hausdorff и ModifiedHausdorff

hausdorff(imgA,imgB) и modified_hausdorff(imgA,imgB)

Dubuisson, M-P et al. 1994. A Modified Hausdorff Distance for Object-Matching.

CIEDE2000

ciede2000(imgA,imgB) и ciede2000(imgA,imgB; metric=DE_2000())

Sharma, G., Wu, W., and Dalal, E. N., 2005. The CIEDE2000 color‐difference formula.

Метрики изображений

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 размером m×n рассматривается как изображение в оттенках серого размером m×n×3. Чтобы рассчитать PSNR по каналам изображения RGB, можно передать peakval как вектор, например psnr(x, ref, [1.0, 1.0, 1.0]).

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 используются они же. Именованный аргумент crop определяет, следует ли отбросить границу карты SSIM; его необходимо установить в значение true, чтобы воспроизвести результат из работы [1].

Пример

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 определен только для изображений в оттенках серого. Способ обработки RGB и других изображений Color3 может различаться в разных реализациях. Для изображений RGB каналы обрабатываются отдельно при вычислении xD835xDC3F*, *xD835xDC36 и xD835__xDC46. Универсальные изображения Color3 перед вычислением преобразуются в RGB.

Справочные материалы

[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/

 M =  colorfulness(img)
 M =  colorfulness(HASLER_AND_SUSSTRUNK_M3(), img)

Измеряет цветность естественного изображения. По умолчанию используется метод HASLER_AND_SUSSTRUNK_M3.

См. также описание метода HASLER_AND_SUSSTRUNK_M3.

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.

Морфологические операции

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

См. также

  • dilate! is the in-place version of this function

  • erode is the dual operator of dilate in the sense that complement.(dilate(img)) == erode(complement.(img)).

!!! note "symmetricity" Если элемент se симметричен относительно начала координат, то есть se[b] == se[-b] для любого b, то расширение сводится к сумме Минковского: A⊕B={a+b|a∈A, b∈B}.

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

См. также

  • erode! is the in-place version of this function

  • dilate is the dual operator of erode in the sense that complement.(dilate(img)) == erode(complement.(img)).

!!! note "symmetricity" Если элемент se симметричен относительно начала координат, то есть se[b] == se[-b] для любого b, то эрозия сводится к разности Минковского: A⊖B={a-b|a∈A, b∈B}.

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

См. также

  • opening! is the in-place version of this function.

  • closing is the dual operator of opening in the sense that complement.(opening(img)) == closing(complement.(img)).

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

См. также

  • opening! is the in-place version of this function.

  • closing is the dual operator of opening in the sense that complement.(opening(img)) == closing(complement.(img)).

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
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!.

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

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
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.

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
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.

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.

component_subscripts(labeled_array) -> массив пикселей для каждой метки, включая метку фона 0.

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.

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.

distance_transform(F::AbstractArray{CartesianIndex}, [w=nothing]) -> D

Вычисляет преобразование расстояний для F, где каждый элемент F[i] представляет местоположение «цели» или «признака», присвоенное i. В частности, D[i] — это расстояние между i и F[i]. При необходимости можно указать вес w для каждой координаты. Значение по умолчанию nothing эквивалентно w=(1,1,...).

См. также описание функции feature_transform.

chull = convexhull(img)

Вычисляет выпуклую оболочку двоичного изображения и возвращает ее вершины в виде массива элементов типа CartesianIndex.

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.

thinning(img::AbstractArray{Bool}; algo::ThinAlgo=GuoAlgo())

Применяет двоичную операцию утончения пятен для скелетизации входного изображения.

См. также описание GuoAlgo.

Интерполяция

Интегральные изображения

Пирамиды

pyramid = gaussian_pyramid(img, n_scales, downsample, sigma)

Возвращает гауссову пирамиду масштабов n_scales, каждый из которых подвергнут понижающей дискретизации с коэффициентом downsample > 1 и sigma для гауссова ядра.

Служебные средства для работы с метаданными изображений

ImageMeta — это массив AbstractArray, который может иметь метаданные, хранящиеся в словаре.

Строит изображение с помощью ImageMeta(A, props) (для словаря свойств props) или с помощью ImageMeta(A, prop1=val1, prop2=val2, ...).

arraydata(img::ImageMeta) -> array

Извлекает данные из img, исключая словарь свойств. array хранится в одной области памяти с img, поэтому изменение одного объекта влияет на другой.

См. также описание функции properties.

properties(imgmeta) -> props

Извлекает словарь свойств props для imgmeta. props хранится в одной области памяти с img, поэтому изменение одного объекта влияет на другой.

См. также описание функции arraydata.

copyproperties(img::ImageMeta, data) -> imgnew

Создает новое «изображение», копируя словарь свойств из img, но используя данные из массива data типа AbstractArray. Обратите внимание, что изменение свойств imgnew не влияет на свойства img.

См. также описание функции shareproperties.

shareproperties(img::ImageMeta, data) -> imgnew

Создает новое «изображение», используя словарь свойств из img, но данные из массива data типа AbstractArray. У двух изображений свойства синхронизированы: изменение свойств одного из них влияет на свойства другого.

См. также описание функции copyproperties.

spatialproperties(img)

Возвращает вектор строк с именами свойств, которые объявлены как «пространственные» и, следовательно, должны быть переставлены при вызове permutedims. Такие свойства объявляются следующим образом:

img[:spatialproperties] = [:spacedirections]

Сегментация изображений

Тип SegmentedImage содержит сопоставление индексов и меток, присвоенные метки, среднюю интенсивность сегмента и количество пикселей в каждом сегменте.

edge = ImageEdge(index1, index2, weight)

Создает ребро графа смежности областей. index1 и index2 — это целые числа, соответствующие отдельным пикселям или вокселам (при линейном индексировании посредством sub2ind), а weight — вес ребра (соответствует расхождению между пикселями или вокселами).

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.

img_labeled = labels_map(seg)

Возвращает массив с метками, присвоенными каждому пикселю.

labels = segment_labels(seg)

Возвращает список присвоенных меток.

c = segment_pixel_count(seg, l)

Возвращает количество пикселей, которым присвоена метка l. Если метка не указана, возвращает Dict(label=>pixel_count) всех меток.

m = segment_mean(seg, l)

Возвращает среднюю интенсивность метки l. Если метка не указана, возвращает Dict(label=>mean) всех меток.

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

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
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: минимальный размер сегмента (в пикселях).

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

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); # метки сегментированного изображения
out = hmin_transform(img, h)

Подавляет все минимумы на изображении в оттенках серого, глубина которых меньше h.

Преобразование методом H-минимумов определяется как реконструкция путем эрозии (img + h) по img. См. работу Morphological image analysis автора Pierre Soille, стр. 170—​172.

G, vert_map = region_adjacency_graph(seg, weight_fn)

Создает граф смежности областей (RAG) на основе SegmentedImage. Возвращает RAG вместе с картой Dict(label=>vertex). weight_fn служит для присвоения весов ребрам.

weight_fn(label1, label2)

Возвращает вещественное число, соответствующее весу ребра между label1 и label2.

new_seg = remove_segment(seg, label, diff_fn)

Удаляет сегмент с меткой label и возвращает новый объект SegmentedImage. Дополнительные сведения см. в описании функции remove_segment!.

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]))
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.

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);
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

Геометрические признаки

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)
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: накопительный порог для обнаружения окружностей

Для получения imgedges и imgphase можно использовать соответственно canny и phase.

Пример

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)

Типы

feature = Feature(keypoint, orientation = 0.0, scale = 0.0)

Тип Feature содержит ключевую точку, ее ориентацию и масштаб.

features = Features(boolean_img)
features = Features(keypoints)

Возвращает вектор Vector{Feature} признаков, сгенерированных из значений true изображения в логической форме или из списка ключевых точек.

keypoint = Keypoint(y, x)
keypoint = Keypoint(feature)

Keypoint можно создать путем передачи координат точки или на основе признака.

keypoints = Keypoints(boolean_img)
keypoints = Keypoints(features)

Создает вектор Vector{Keypoint} на основе значений true изображения в логической форме или на основе списка признаков.

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

Для генерирования пар выборки используется случайное начальное значение. При сопоставлении двух дескрипторов начальное значение, которое использовалось для их построения, должно быть одинаковым.

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. См. описание [fastcorners].

threshold

Float64

Порог, используемый для нахождения углов в FAST. См. описание [fastcorners].

harris_factor

Float64

Коэффициент Харриса k, используемый для ранжирования ключевых точек по реакциям Харриса и выбора лучших из них

downsample

Float64

Параметр понижения дискретизации, используемый при построении гауссовой пирамиды. См. описание [gaussian_pyramid] в Images.jl.

levels

Int

Количество уровней в гауссовой пирамиде. См. описание [gaussian_pyramid] в Images.jl.

sigma

Float64

Используется для гауссовского сглаживания на каждом уровне гауссовой пирамиды. См. описание [gaussian_pyramid] в Images.jl.

freak_params = FREAK([pattern_scale = 22.0])
Аргумент Тип Описание

pattern_scale

Float64

Коэффициент масштабирования для окна выборки

brisk_params = BRISK([pattern_scale = 1.0])
Аргумент Тип Описание

pattern_scale

Float64

Коэффициент масштабирования для окна выборки

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.

Углы

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

sample_one, sample_two = random_uniform(size, window, seed)

Создает пары выборки с использованием случайной равномерной выборки.

sample_one, sample_two = random_coarse(size, window, seed)

Создает пары выборки с использованием случайной выборки по грубой сетке.

sample_one, sample_two = gaussian(size, window, seed)

Создает пары выборки с использованием гауссовой выборки.

sample_one, sample_two = gaussian_local(size, window, seed)

Пары (Xi, Yi) выбираются случайным образом с использованием гауссова распределения, причем сначала выбирается X со среднеквадратичным отклонением 0.04*S^2, а затем выбираются Yi’s с использованием гауссова распределения — каждая точка Yi выбирается со средним значением Xi и среднеквадратичным отклонением 0.01 * S^2.

sample_one, sample_two = center_sample(size, window, seed)

Создает пары выборки (Xi, Yi), где Xi — это точка (0, 0), а Yi выбирается равномерно из окна.

Описание признака

desc, keypoints = create_descriptor(img, keypoints, params)
desc, keypoints = create_descriptor(img, params)

Создает дескриптор для каждого элемента в keypoints изображения img. params определяет параметры для любого из нескольких дескрипторов:

Некоторые дескрипторы поддерживают обнаружение keypoints из fastcorners.

Сопоставление признаков

distance = hamming_distance(desc_1, desc_2)

Вычисляет расстояние Хэмминга между двумя дескрипторами.

matches = match_keypoints(keypoints_1, keypoints_2, desc_1, desc_2, threshold = 0.1)

С помощью функции hamming_distance находит соответствующие ключевые точки, расстояние между которыми меньше threshold.

Сопоставление текстур

Матрица совместной встречаемости уровней серого

glcm
glcm_symmetric
glcm_norm
glcm_prop
max_prob
contrast
ASM
IDM
glcm_entropy
energy
dissimilarity
correlation
glcm_mean_ref
glcm_mean_neighbour
glcm_var_ref
glcm_var_neighbour

Локальные двоичные структуры

lbp
modified_lbp
direction_coded_lbp
lbp_original
lbp_uniform
lbp_rotation_invariant
multi_block_lbp