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

в 11:34, , рубрики: android, Augmented reality, computer vision, opencv, дополненная реальность, метки: , , ,
Для кого эта статья?

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

Предисловие

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

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

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

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

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

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

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

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

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

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

Реализация

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

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

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

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

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

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

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

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

Автор: EmoCoder

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js