Пользователь
0,0
рейтинг
18 февраля 2014 в 14:05

Разработка → Как я FOV измерил без циркуля и линейки

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

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

Стоп! А как привязать врагов к окружающей действительности?

Я сделал это очень просто.


Обработка изображения


Посмотрите на первую картинку видеозахвата.



Я пробегаю по всей ширине (480 пикселей) изображения и суммирую RGB компоненты точек, лежащих с текущей точкой на одной вертикальной прямой. Получаем массив из 480 элементов.
На верхней части рисунка изображена красно-белая (оле!) гистограмма найденной функции.

То же самое проделываем со следующим кадром из видеопотока. Посмотрите на рисунок 2.



Моя задача — совместить красно-белые гистограммы первого и второго кадра. Сдвигая графики друг относительно друга, я очень быстро нахожу оптимальное совпадение. Разница в сдвиге и есть искомое смещение реальности в моем iPhone в горизонтальном направлении.

Таким, образом виртуальный объект навсегда привязывается к реальному местоположению. В каждый момент времени мы знаем, насколько пикселов его сдвинуть в горизонтальной плоскости.
Хорошо ли работает алгоритм? Очень неплохо. Главное, не дергать телефон во время игры — данный подход не любит смещения более 40 пикселов за такт. А такт у камеры 20 кадров в секунду.
При резких движениях надо, видимо, использовать уже тяжелую артиллерию — гироскоп и акселерометр.

Что такое FOV


Каждое оптическое устройство имеет FOV (field of view). Будь то человеческий глаз или мыльница.
image
Что в FOV попадает — прибор видит. Прочее — нет, хоть убей. На картинке человек видит дерево, а машину не видит. Это может быть опасно.
FOV измеряется в градусах. У человека FOV около 120-ти градусов для каждого глаза. У зайца, например, 150. То есть двумя глазами заяц покрывает почти всю сферу видимости. Не видит заяц только ровно вперед 10 градусов и ровно назад 10 градусов. Косой…
Ладно, а какой FOV у моего iPhone?
Заглянул, разумеется, в интернет. Бог мой, чтобы вычислить FOV iOS устройства, необходима специальная лаборатория с лазерными измерителями.

У меня нет такой лаборатории. А зачем? Я просто запустил вышеописанную программу. Сел на любимое вращающееся кресло. И повернулся на 360 градусов. Программа выдала размер сферы вокруг меня.
image
Программа выдала размер сферы вокруг меня.
В пикселах — стабильно для iPod последнего поколения 3050-3060 пикселей.

Таким образом FOV моего iPod равен 480*360/3060 = 56-57 градусов.

А лазер намерял 55.7.

Неплохая точность у меня получилась, согласитесь.

Скрытая реклама моего приложения, использующего вышесказанный алгоритм, помещена в теги. Только это между нами, ок?
Вадим Башуров @PapaBubaDiop
карма
957,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (31)

  • +4
    ПапуБубу я узнал уже по гистограммам…
    А с гироскопом/акселерометром не пробовали? Может быть даже удобнее было бы?
    • +5
      Идеально было бы совместить оба подхода.
      Пусть кто-нибудь из молодых талантов это исследует, а мы его заплюсуем.
      • 0
        пробовал не с гироскопом, а с компасом, когда через камеру пытался показывать точки, привязанные географически
        его иногда клинит и он непонятным образом поворачивается. после нескольких дерганий возвращается на место
        есть мнение, что гироскоп/акселерометр будет качественно ловить динамичные движения, а на плавных будет косячить
        • 0
          Там в любом случае его надо калибровать прежде чем использовать, т.к. между показаниями гироскопа/акселерометра и показаниями с камеры будут расхождения(это не считая шумности показаний этих сенсторов)
        • +1
          Стандартный Apple пример для гироскопа с высокочастотным фильтром давал отличные результаты по крену, тангажу и рысканью для приложения из серии закати шарик в лунку.
    • +4
      Он узнается еще по первой картинке-скриншоту. Слишком уж почерк заметный.
      А так, если не ошибаюсь, на одном из топовых смартфонов Nokia, годах эдак в 2004-2007 было что-то подобное реализовано, только с пчелами, а не фашистами.
      • +5
        Про пчёл не знаю, но на Nokia 3230 по умолчанию была игра Agent V, где надо было вирусы убивать.
        • +1
          Я жене на диплом помогал клон этой игры тоже для симбиана делать :)
          Вполне сносно работало — отстреливали приведений.
          • 0
            Тут ведь просто поверх стрима рисуется картинка, без учета 3D составляющей сцены?
            • +2
              Ну тоесть глубина сцены не учитывается. Виедострим анализируется только на предмет смещения по вертикали, горизонтали.
              Хотя сами вирусы, как мне казалось, были на разном на разном удалении от икрана, но в этом вопросе ни как не взаимодействовали с бэком.
        • +4
          Владельцы Siemens SX1 могут вспомнить другую интересную игру под названием Mozzies. В ней тоже приходилось «брать ружье в руки» и отстреливать москитов с недовольными мордочками, которые весьма нагло вели себя в окружающем пространстве (через камеру смартфона, разумеется).

          image image image

          Mozzies, на мой взгляд, является родоначальником игр подобного типа. На выставке CeBIT 2003 был стенд, посвященный Siemens'у SX1: на нём постоянно была запущена эта игрушка и в Mozzies могли поиграть все желающие (по слухам, возле стенда даже были очереди). Несмотря на всю простоту реализации, тогда эта игра казалась весьма инновационной.
          • +1
            Mozzies — Mosquitoes помню из чуть ли не из всех гиковских журналов!
      • 0
        Siemens SX1
        и там были комары

        комментарии не читай, сразу пиши
  • +2
    Не нашел в сторе фашистов, тестовые исходники выложить не планируете?
    Гироскоп можно подключить для корректировки ошибок при резких движениях и однотонной картинке, но для постоянной привязки с его задержкой он не подходит.
    На айфоне круговая панорама входит в шесть с половиной экранов, значит FOV = 360 / 6.5 = 55.4. У меня точность выше! ;)
    • +3
      Ловко, но откуда Вы узнали про 6.5 экранов?

      Про фашистов Apple не пропустил приложение. Он и биатлон не хотел пропускать — говорит слишком реалистичная стрельба, поменяйте в Realistic Violence флажок с None на Frequent/Intense.
      Я поменял — в результате
      Due to local laws, this app will not be sold in the following territories: Brazil, Korea

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

    А щели, как я понимаю, края экрана? Или самое вкусное, а именно определение объемности видеопотока, остается на следующую статью?
    • +4
      Это задача не для моего слабого ума — я тупо вычисляю горизонтальные линии (по такой же схеме) и фашисты как-бы выползают из-за них. Это, на практике, подоконники, мониторы, столы, фальш-панели, двери.

      А если честно, я просто подхожу к окну -… и поле, наше технопарковское поле покрывается поверженными извергами. Картинки извергов взяты из вольфенштейна.
  • +1
    Я похожим способом (с гистограммами) делал читалку штрих-кодов.
    Можно кстати, добавить таким же образом измерение положения по вертикали.
    Еще можно вращение/наклон определить — например, считать 2 гистограммы — среднее значение 1/5 части кадра вверху и 1/5 внизу. Тогда если например, верхняя часть сдвинулась влево, а нижняя не сдвинулась — значит устройство наклонили влево.
    • 0
      Разумеется, вертикальное смещение считается аналогично. С поворотом на маленький угол можно хитрые трюки с этими двумя свертками делать.
      И даже не надо поворачивать видео — матрицу на углы и подбирать похожесть. Но научно-популярно это описать сложно, я не готов.
    • 0
      А можно считать оптический поток между кадрами…
    • +1
      Также для ускорения вычислений можно использовать свертку из библиотеки Accelerate framework (vDSP_conv() например) и другие полезные функции
  • +2
    А мне пришлось хардкодить все известные FOV iOS-устройств из-за того, что их невозможно более или менее точно и быстро вычислить прямо на устройстве — характеристики камер Эпл не публикует (в простейшем случае нужны только фокусное расстояние ƒ и геометрические размеры чипов d). Вот такая формула вполне подойдёт для iOS:

    Самая простая формула для вычисления FOV

    Кстати, в списке некоторые данные немного расходятся с вычисленными, если мне не изменяет память.
  • +1
    Весьма отличный метод — плюсанул.
    Но оптимальнее измерить FOV и потом использовать прошитое в константы значение.
    Меньше напряжения железу, меньше батареи будет кушать.

    А для реальной привязки не только поворота, но вообще к пространству есть SLAM — игра пользующая его:
    www.youtube.com/watch?v=WHGtvdxTVZk

    Правда игра уже недоступна в App Store
  • 0
    И еще нужно учитывать, что FOV отображаемой на экране части картинки не совпадает с FOV камеры.

    В зависимости от режима картинка будет обрезаться.

    Особенно актуально, если картинку нужно растянуть на весь экран.
  • +1
    Про зайца пример не понял…
    150 один глаз, 150 другой… Не видит 10 спереди и 10 сзади… Итого получаем 320 градусов.
    А как же остальные 40?
    • +1
      Мой косяк. С этими зайцами свяжешься…
  • +3
    Пара замечаний насчёт параллакса: при замере FOV методом вращающегося стула очень важно держать ваше устройство с камерой так, чтобы ось вращения совпадала с нодальной точкой объектива (центр ножки стула должен быть на одной вертикальной оси с передней линзой вашего смартфона).

    Держа устройство как обычно, впереди себя на вытянутой руке (нодальная точка впереди точки вращения), мы добьёмся того, что при вращении в одну сторону, объекты на светочувствительной матрице будут дополнительно смещаться в противоположную сторону. Такое смещение и называется параллаксом и может достигать многих градусов (полный круг вокруг вас, замеренный таким образом, будет уже не 360, а 355 или 350 градусов).

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

    Впрочем, параллакс можно использовать и в благих целях: можно находить по параллаксу близкие предметы, выступающие над фоном и если виртуальные объекты на экране появляются на разной глубине (например они разного размера), то смещая ближние с учётом параллакса относительно дальних, можно добиться намного более правдоподобного виртуального окружения.
    • +2
      Да. Вокруг шеста (прижимая iPhone к шесту) получились самые стабильные результаты. Последний абзац Вашего комментария звучит перспективно, но как это реализовать на практике — не понимаю.
  • 0
    А приложению не сносит крышу, если начать перемещаться в пространстве во время игры? наверняка есть забавные артефакты
    • 0
      Если перед объективном двигаются коллеги, то они уводят виртуальные объекты за собой. Тоже самое с автомобилями, попавшими в кадр. В эти минуты хочется автомат сменить на огнемет))

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