ImageFeatures.jl
Пакет ImageFeatures позволяет вычислять компактные «дескрипторы» изображений или областей изображений. Форма этих дескрипторов позволяет сравнивать их с аналогичными дескрипторами на других изображениях или в других частях того же изображения. Это может быть полезно при выполнении различных задач, таких как распознавание объектов, локализация или регистрация изображений.
У ImagesFeatures есть собственная документация. Ознакомьтесь с ней, чтобы получить полное представление о функциональных возможностях пакета. Здесь мы вкратце рассмотрим один тип признаков и его применение для регистрации изображений — дескриптор BRISK.
Дескриптор BRISK исследует структуру изображения вокруг ключевой точки. Для данной ключевой точки средняя интенсивность вычисляется на основе набора окружающих ее участков:
Затем BRISK представляет эти уровни интенсивности способом, который является инвариантным относительно поворота. Это позволяет сравнивать дескрипторы на двух изображениях, одно из которых может быть повернутой версией другого.
Давайте рассмотрим простой пример, в котором дескриптор BRISK используется для сопоставления двух изображений, одно из которых было смещено на (50, 40)
пикселей, а затем повернуто на угол 75 градусов. В этом примере используется изображение lighthouse
из пакета TestImages.
Сначала создадим два изображения, которые будут сопоставляться с помощью BRISK.
using ImageFeatures, TestImages, Images, ImageDraw, CoordinateTransformations, Rotations
img = testimage("lighthouse")
img1 = Gray.(img)
rot = recenter(RotMatrix(5pi/6), [size(img1)...] .÷ 2) # поворот вокруг центра
tform = rot ∘ Translation(-50, -40)
img2 = warp(img1, tform, axes(img1))
Для вычисления дескрипторов сначала нужно получить ключевые точки. В этом руководстве мы будем использовать углы FAST для генерирования ключевых точек (см. описание функции fastcorners
).
features_1 = Features(fastcorners(img1, 12, 0.35))
features_2 = Features(fastcorners(img2, 12, 0.35))
Чтобы создать дескриптор BRISK, сначала нужно определить параметры, вызвав конструктор BRISK
.
brisk_params = BRISK()
Теперь передайте изображение с ключевыми точками и параметрами в функцию create_descriptor
.
desc_1, ret_features_1 = create_descriptor(img1, features_1, brisk_params)
desc_2, ret_features_2 = create_descriptor(img2, features_2, brisk_params)
Полученные дескрипторы можно использовать для поиска соответствий между двумя изображениями с помощью функции match_keypoints
.
matches = match_keypoints(Keypoints(ret_features_1), Keypoints(ret_features_2), desc_1, desc_2, 0.1)
Просмотреть результаты можно с помощью пакета ImageDraw.jl.
grid = hcat(img1, img2)
offset = CartesianIndex(0, size(img1, 2))
map(m -> draw!(grid, LineSegment(m[1], m[2] + offset)), matches)
Как видите, точки были точно сопоставлены несмотря на большой угол поворота.