Дескрипторы и ключевые точки

Ключевые слова: Target, opencv, matplotlib, numpy, BFMatcher, queryIdx, trainIdx, distance, img2kp, similarity

Библиотеки, которые понадобятся в процессе данного урока: это numpy, opencv и библиотека для визуализации изображения и графиков — matplotlib.

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

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

Следующая строчка позволяет выделить ключевые точки и дескрипторы.

Реализуем функцию, которая рисует ключевые точки поверх изображения. На вход этой функции передается изображение и ключевые точки. Первая строчка позволяет из объекта key points выделять координаты ключевых точек, а следующие строчки отвечают за отрисовку.

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

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

Выделим ключевые точки и отрисуем их поверх рисунка.

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

Посмотрим подробнее на то, что хранится в объекте matches. Параметры, которые есть в совпадениях, это параметр distance. Это расстояние, от каждой точки до точки, с которой ее сопоставили. imgIdx — это индекс изображения, однако данный параметр не пригодится. queryIdx и trainIdx будут рассмотрены в конце лекции.

Сопоставим ключевые точки таргета и ключевые точки со снимка. Для этого используем специальный алгоритм, который уже есть в opencvdrawMatches. Внутрь него передадим изображение, ключевые точки с таргета, фото, снимок, сделанный с таргетом, ключевые точки, которые есть на таргете и так же объект matches. Передаем в него только 10 сопоставлений и, соответственно, отрисовываться тоже будет всего 10 точек.

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

Реализуем класс, который будет называться ImageBase. Какие методы будут у данного класса? Метод инициализации, в котором инициализируем алгоритм orb и алгоритм bf для сопоставления изображений в базе и снимков.

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

Также необходим метод img2kp, в этот метод передается изображение, а он возвращает ключевые точки и дескрипторы.

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

Далее реализуем метод find_similar. Он будет искать по всей базе наиболее подходящий таргет к нашему снимку.

И дополнительно, на всякий случай, реализуем метод find_similar_desc. Который будет искать наилучшие совпадение, но только по ключевым точкам.

Давайте посмотрим какие изображения есть базе. Все 10 картинок имеют множество деталей, поэтому они будут хорошо работать для данного алгоритма. Загрузим изображения.

В объекте img_paths хранится путь к каждой картинке.

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

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

Визуализируем картинку.

Попробуем найти таргет для этого снимка.

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

Что влияет на качество распознавания?

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

Можно попробовать передавать не все ключевые точки, а передавать только первые 50. Это очень важный момент, иногда такой подход может срабатывать, потому что при инициализации объекта matches, ключевые точки в нем отсортированы по наименьшей дистанции. Самые первые ключевые точки, это те ключевые точки, которые наилучшим образом описывает наш объект. Однако снова возвращается не тот объект, который мы ждем.

Давайте приведем изображение в базе и изображение, которое передается, к одному масштабу. Для этого напишем специальную функцию zip_img. Она принимает изображение, некоторый параметр, к примерному размеру которого нужно свести наше оригинальное изображение и реальный размер картинки. Функция старается привести изображение в real_size (таргет) к тому размеру, который есть в базе.

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

Посмотрим, что можно сделать со снимком. На вход передается снимок, размер выходного таргета и размер real_size (реальный размер таргета). Указываем 400х300.

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

Дополнительные источники информации:

Задание: Сейчас в функции zip_img, параметры real_size подбираются вручную. Задание - придумать алгоритм для вычисления этого параметра.

Подсказка: посчитайте ключевые точки на исходном изображении и по ним найдите ширину и высоту. Какие проблемы могут возникнуть при таком подходе?

Last updated