Массивы: более сложное индексирование
Отслеживание позиции с помощью нетрадиционных индексов
Рассмотрим следующую пару изображений:
imgref | img |
---|---|
Как легко догадаться, изображение справа — это повернутая версия изображения слева. Но на какой угол? Было ли также выполнено преобразование?
«Примитивный» способ проверить это — поворачивать и смещать изображение справа до тех пор, пока оно не совпадет с изображением слева. Мы можем наложить два изображения (Using colorview to make color overlays), чтобы узнать, насколько точно они совпадают.
julia> using Images, CoordinateTransformations, Rotations
julia> tfm = recenter(RotMatrix(pi/8), center(img))
AffineMap([0.9238795325112867 -0.3826834323650898; 0.3826834323650898 0.9238795325112867], [88.77855462171088, -59.31993370357884])
julia> imgrot = warp(img, tfm);
julia> summary(img)
"386×386 Array{Gray{N0f8},2} with eltype Gray{N0f8}"
julia> summary(imgrot)
"506×506 OffsetArray(::Array{Gray{N0f8},2}, -59:446, -59:446) with eltype Gray{N0f8} with indices -59:446×-59:446"
В то время как у img
оси, как обычно, начинаются с 1, в сводке по изображению imgrot
указано, что оно имеет оси (-59:446, -59:446)
. Это означает, что первый элемент imgrot
имеет индексы imgrot[-59,-59]
, а последний элемент — индексы imgrot[446,446]
.
Каков смысл таких индексов, которые выходят за пределы исходного массива в обоих направлениях? Это можно понять при отображении повернутого изображения, особенно если наложить его на исходное:
julia> imgov = colorview(RGB, paddedviews(0, img, imgrot, zeroarray)...)
Дополнение со всех сторон массива нужно по той причине, что часть пикселей повернутого изображения (зеленого) выходит за пределы области, занимаемой исходным изображением (красным). Из-за того, что в Julia допускаются отрицательные индексы, у нас не возникает проблем с «дополнением» исходного изображения: мы просто копируем оригинал в дополненный массив, используя исходные индексы.
Мы можем проверить, хорошо ли imgrot
совпадает с исходным неповернутым изображением imgref
, приведенным в начале этой страницы:
julia> imgov_ref = colorview(RGB, paddedviews(0, imgref, imgrot, zeroarray)...)
Тот факт, что перекрывающаяся часть выглядит желтой (сочетание красного и зеленого), означает, что совпадение идеальное.
Дополнительные сведения о поддержке произвольных индексов в Julia см. в этой записи в блоге.
Отслеживание ориентации с помощью именованных осей
Предположим, у вас есть трехмерное изображение в оттенках серого. Это фильм (двухмерное изображение во времени) или трехмерное изображение (x, y и z)? Для ориентации в таких ситуациях один из лучших способов — присвоить осям имена. В пакете TestImages есть пример файла, иллюстрирующего такую ситуацию:
julia> using Images, TestImages
julia> img = testimage("mri");
julia> println(summary(img))
3-dimensional AxisArray{Gray{N0f8},3,...} with axes:
:P, 0:1:225
:R, 0:1:185
:S, 0:5:130
And data, a 226×186×27 Array{Gray{N0f8},3} with eltype Gray{N0f8}
TestImages использует пакет AxisArrays для присвоения имен осям данного изображения в терминах системы координат RAS (правая, передняя, верхняя), которая обычно применяется в магнитно-резонансной томографии. Дополнительные сведения о создании собственных объектов AxisArray
см. в документации к этому пакету.
Эта система координат может упрощать визуализацию. Давайте посмотрим на «горизонтальный срез», перпендикулярный оси «верх-низ» (то есть срез с постоянным значением S
):
Из сводки видно, что в срезе остались только оси :A
и :R
.
Можно было бы также выполнить срезы по осям R
и A
, но для этого изображения (очень анизотропного) они не столь информативны.
Пакеты ImageAxes и ImageMetadata расширяют функциональность AxisArrays и могут быть полезны, когда нужно закодировать больше информации об изображении.