- PVSM.RU - https://www.pvsm.ru -

Дополненная реальность — это просто

Для кого эта статья?

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

Предисловие

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

В качестве мобильной платформы был выбран Android, так как имелся небольшой опыт написания приложений под него, и Java мы знаем гораздо лучше, чем Objective-C. Для обработки изображений мы решили использовать известную библиотеку OpenCV [1].
Под катом история создания нашего простенького приложения.

Какие приложения дополненной реальности уже есть на Google Play?

Условно их можно разделить на три категории:

  1. Получающие данные с акселерометра, компаса и GPS, и, ориентируясь лишь на них, накладывающие что-то на изображение (пример [2])
  2. Использующие какие-либо метки, которые нужно распечатать или которые распространены (пример [3])
  3. Не получающие и не использующие вообще никаких данных, а просто накладывающие картинку (пример [4])

И это, в общем-то, всё, что можно найти на Google Play.

С чего начать?

Проще всего начинать знакомство с компьютерным зрением, используя библиотеку OpenCV. Мы рекомендуем книгу O’Reilly “Learning OpenCV” (есть на рутрекере). Также нужно будет часто заглядывать на Wiki разработчиков [5].

Постановка задачи

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

Реализация

Что же мы придумали? Брать несколько ключевых точек на одном кадре и смотреть, где они окажутся на следующем. Затем считать их сдвиг и распределять по кластерам, которые бы представляли собой объекты. Фоном можно считать кластер с наибольшей площадью (либо с наибольшим количеством точек, но от этого подхода мы в результате отказались).

Для определения сдвига ключевых точек мы решили использовать алгоритм Лукаса-Канада (Lucas-Kanade method [6]). На вход ему нужны две картинки и массив точек с первой из них, а на выходе получается массив с этими же точками, но уже найденными на второй картинке. Как раз то, что нам нужно, и работает достаточно быстро.

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

Проблемы и советы

  1. Невозможно определить сдвиг камеры с хорошей точностью.
    Первоначально мы планировали следующий подход: вырезать общие части двух кадров и вычитать один из другого. В теории ненулевая часть показывала бы, где находятся движущиеся объекты. Но на практике из-за неточности сдвига и перепадов яркости даже при небольшом движении камеры нулевых областей почти не было. Этот факт обязательно нужно учитывать при проектировании приложения.
  2. Всё нужно делать в нативе.
    Первая версия была написана на чистой Java. Но, хоть сама библиотека и нативная, это работало очень медленно из-за множества лишних перебрасываний больших объемов данных и частого вызова сборщика мусора. После выноса всех вычислений в натив производительность увеличилась в несколько раз.
  3. Отладка.
    Дебаг на устройстве занимает довольно много времени, а эмулятор для наших целей – не вариант (слишком медленный). Поэтому удобно иметь PC-версию приложения на С++, из которой определенный участок можно будет просто скопировать в нативный код для Android.
  4. Многопоточность.
    Обработка кадров занимает довольно много времени, а пользователю вряд ли будет приятно наблюдать задержки в смене изображения. Поэтому нужно сделать вполне естественную вещь: разделить вывод изображений и их обработку на два потока.
  5. Документация.
    В версии OpenCV под Android нас поразило отсутствие внятной документации. Конечно, в основном она такая же, как и версия для PC, но некоторые моменты всё же различаются.
Заключение

Обработка изображений требует серьезных вычислительных мощностей. Наше приложение работает хорошо даже на устройствах, сопоставимых по производительности с Acer Liquid (768 MHz). Для большинства же выпускаемых сейчас устройств вполне реально сделать и что-то более сложное.

Кроме того, как Вы видите, в компьютерном зрении нет ничего сложного, а в данный момент приложений с дополненной реальностью под Android практически нет, так что дерзайте!

P. S. Если интересно, результат можно посмотреть тут [7].

Автор: EmoCoder


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/android/10320

Ссылки в тексте:

[1] OpenCV: http://code.opencv.org/projects/opencv/wiki/OpenCV4Android

[2] пример: https://play.google.com/store/apps/details?id=com.agi.android.augmentedreality

[3] пример: https://play.google.com/store/apps/details?id=com.BeyondReality.AC130

[4] пример: https://play.google.com/store/apps/details?id=nl.tjerk.weapons3dpro

[5] Wiki разработчиков: http://code.opencv.org/projects/OpenCV/wiki/WikiStart

[6] Lucas-Kanade method: http://en.wikipedia.org/wiki/Lucas%E2%80%93Kanade_method

[7] тут: https://play.google.com/store/apps/details?id=com.fancysoftware.cvbombs.free