Headtracking или как увидеть трехмерный чайник на двухмерном мониторе

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

    Где глаза?


    Времени тогда у меня было немного, поэтому все делать совсем с нуля не хотелось. Не долго думая, я стянул, бесплатную для учебных целей, либу FaceAPI и принялся ее мучить. После недолгих мучений оказалось, что она может вполне неплохо определять положение головы, а также глаз и, что самое главное, она может сразу выдавать 3д позицию и ориентацию каждого глаза в системе координат веб-камеры.

    Что видят глаза?


    Итак, позиции глаз у нас есть, теперь надо узнать, что же они видят. Кстати предполагается, что пользователь будет циклопом с одним рабочим глазом как раз между двумя реальными. Первая попытка сделать все легко и просто, прикрутив виртуальную камеру в OpenGL к тому месту, где должен быть глаз пользователя не увенчалась успехом, так как было совсем не реалистично.На видео можно посмотреть как это выглядело:


    Чисто субъективно, плохо было то, что чайник сильно увеличивался при приближении. Стал я думать, что же тут не так и даже провел простенький эксперимент с подручными средствами:


    Обратить внимание надо на размеры телефона относительно размеров отверстия. Получается, что при приближении наш чайник должен не увеличиваться, а, наоборот, уменьшаться (для случая, когда он за «окном»). Вот так это примерно выглядит:


    Тут же кроется еще одна проблема, при взгляде сбоку, искажаются пропорции. Проблема заключается в том, что OpenGL рендерит нам картинку как-будто она перпендикулярна взгляду, но пользователь видит плоскость монитора под углом.


    В результате, изображение получается искаженным.


    Причем на картинке правильное изображение находится справа, а не слева. Если посмотреть на него справа от монитора (примерно там находилась голова пользователя), то оно будет правильным, а левое искаженным.

    Как исправить увиденное?


    Чтобы исправить обе проблемы одним махом, надо сделать так, чтобы пользователь видел на экране именно то, что он видел бы в реальном мире, если посмотрит через окно. Сделать это можно разными способами, но на тот момент мне пришел в голову вот такой: надо рендерить все как и раньше, но искать на отрендеренной картинке ту область, которая бы соответствовала области монитора в реальном мире. Для этого пришлось вооружиться линейкой, измерить дисплей и позицию каждого угла относительно камеры (к ней привязана наша СК) и таким вот образом получить его позицию в трехмерном пространстве нашей сцены, затем посчитать физическую позицию окна на мониторе. На картинке показана рамка, которая соответствует окну на мониторе в трехмерном пространстве.


    Теперь надо сделать так, чтобы содержимое этой области растянулось на все окно. Для этого мы проецируем точки, соответствующие углам реального окна на мониторе в 3д пространстве на плоскость дисплея, куда рендерит картинку OpenGL (фактически перемножаем координаты этих точек на матрицу проецирования), находим гомографию (гомография — это такая матрица, которая позволяет установить соответствие точек одного изображению точкам другого, найти ее можно с помощью OpenCV или написать все ручками) между получившимся четырехугольником и прямоугольником окна на реальном дисплее и мапим наше отрендеренное изображение к прямоугольнику окна реального дисплея (опять же OpenCV нам в помощь).

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

    Правда есть еще одна мелочь: если пользователь находится далеко от монитора, то с постоянным FOV получается, что полезная часть изображения (собственно то, что видно через монитор) получается довольно маленькой.


    и финальная картинка имеет низкое разрешение:


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


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

    Что получилось?


    Результаты всего этого можно наблюдать на видео:


    А теперь несколько комментариев, как оно работает с субъективной точки зрения и почему:

    1) Самая большая проблема — маленькие углы обзора веб-камеры на ноутбуке. Поэтому довольно легко выйти за пределы видимости и изображение останавливается. Не приспособлена она для такого. Но радует то, что все достаточно быстро и в плане скорости проблем нет. Есть в природе более широкоугольные, но надо такую раздобыть.

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

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

    4) Попробую в следующем семестре сделать тоже самое, но с поддержкой стерео 3д и отдельной картинкой для каждого глаза. Посмотрим, поверит ли тогда мозг.

    UPDATE:


    По просьбам трудящихся, выкладываю исходники и бинарники. В бинарники включил все дллки, поэтому получилось 24 метра в архиве.

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

    И еще одна особенность, там будет два окна с чайником, надо одно переместить на другое (просто перетянуть), чтобы было правильно мне так для отладки было удобней).

    Потерянная модель чайника может быть найдена тут и должен лежать тут: C:\_WORK\__3d_Models\
    Share post

    Comments 58

      +7
      Действительно хорошая работа мозгом проделана!
      Интересно, если подготавливать вывод не на монитор, а на очки с мониторам (очки виртуальной реальности, как они правильно называются?) — проще будет? Ну без учета ГРИП и центра внимания в плоскости глаз. Хотя без центра внимания мозг будет спотыкаться, да?
        +1
        Насколько мне известно, на очках стоят акселерометры, и там положение головы вычисляется с их помощью. Камера будет излишней.
          0
          Честно говоря, с такими очками никогда дела не имел. По идее, проще обманывать мозг, но вот как оно будет себя вести на тему фокуса и ГРИП — вопрос хороший. Насколько я знаю, далеко не все чувствуют себя в них комфортно.
            0
            Можно сделать скринсейвер, который будет смотреть в глаза пользователю :) с 3х-мерными шариками-глазами.
          +1
          Не останавливайтесь, очень интересно.
            +14
            Исходный код? :)
              +3
              Не, фильм не очень.
                +3
                Петросян вы, батенька.
                А фильм нормальный
                  0
                  Вполне себе очень.
                  +4
                  Я как вернусь с работы вечером, выложу исходники и ехе. Мне не жалко.
                  +4
                  Судя по видео, действительно великолепная работа. Жалко что нет возможности запустить демку у себя.
                    0
                    вечером будет;)
                    +3
                    Хорошая работа. Кстати, видел подобное уже www.youtube.com/watch?v=QgKCrGvShZs&feature=player_detailpage#t=187s
                      0
                      Я видео еще видел, где он в домашних условиях это все демонстрирует. Тоже отличная работа.
                      0
                      Работа супер, Вы молодец. А не как нельзя у себя эту игрушку посмотреть?
                        +1
                        Потрясающе! Не пришлось даже следовать вашему совету — визуализировать трехмерный чайник — на 10-20 секунде последнего видео в мозге «щелкнуло». Нет, действительно круто! Молодец!
                          +1
                          мой мозг тоже был обманут при просмотре видео :)

                          впечетляет
                            +2
                            На самом деле, на видео оно выглядит лучше, чем в жизне. В случае с видео, мозг знает, что перед ним монитор и плоское видео, а вот когда ему пытаются доказать, что там действительно чайник, тогда все становится сложнее…
                          –3
                          За этим будущее! Думаю в скором времени многие сайты будут так выглядеть!
                          Великолепная идея!!!
                            +2
                            Извиняюсь, что? Сайты? Это же, что там высматривать надо? Я вот о фильмах и играх подумал.
                              +9
                              Я понял:D Это чтобы контент за баннерами можно было разглядывать.
                              +3
                              Разве не лучше было написать нестандартную матрицу проекции которая проектирует все точно так, как надо?
                                0
                                Лучше, но на тот момент пришло первым в голову это решение, так и осталось.
                                +3
                                Я видел штуку наподобе, только размах был больше.
                                www.youtube.com/watch?v=iRvZEhLwXWE
                                Когда я смотрел на этот танк в очках, то просто афигевал, как так можно) Там был эффект, будто на самом деле этот робот ходил по столу, я серьёзно! Там ещё был замок и вроде ещё пару сцен.
                                  –1
                                  Действительно, очень суперская работа. Здесь нужно не только понимания, как такое реализовать, но и что реализовать. Видео, в котором мобильный телефон за листом бумаге поверг меня в смех))
                                    0
                                    Чего смешного? Что бы понять, как это будет выглядеть в реальной жизни, нужно взять пример из реальной жизни.
                                      0
                                      В этом-то и прикол, что примитивизм такого подхода даёт реальный успех!
                                    0
                                    www.youtube.com/watch?v=Jd3-eiid-Uw вот еще видео на эту тему

                                    А вообще кажется, что в этом мало практического значения: чтобы видеть какой-то эффект, нужно постоянно передвигаться, а если сидеть на месте, то голову особо не повертишь. Можно окружить себя несколькими мониторами и тогда было бы круто играть в автосимуляторы)) Повернул голову направо, а там видно, кто сбоку!
                                      +4
                                      Это можно использовать в 3d шутерах, например, все равно все пытаются заглянуть за угол постоянно.
                                        0
                                        Насколько я знаю, народ уже достаточно давно работает в области применения этого дела для игр, на ниндендо 3дс такое есть, есть всякие патчи для халвы, кризица и еще кучки шутеров. Где-то в инете мне попадалась страничка одного исследователя, который этим делом занимается, только вот уже не помню имени, тоже русский кстати. Так там как раз можно было из-за угла смотреть, приближать итд итп.
                                    • UFO just landed and posted this here
                                        0
                                        Следующим шагом будет стерео. У меня наконец собрались для него все компоненты кроме времени, но я надеюсь к концу семестра сделаю таки поддержку стерео 3д.
                                        +1
                                        johnnylee.net/projects/wii/ — четыре с лишним года назад придумано.
                                          0
                                          Как мне кажется, выглядит довольно неплохо)
                                            0
                                            Как вариант вместо веб камеры можно Кинект попробывать подключить.
                                            0
                                            Кстати говоря немного не то, но есть для Half-Life 2: www.moddb.com/mods/faceoff-paintball
                                            Очень прикольно, можно выглядывать головой из укрытия, головой целиться при приближении (ironsight) и т.д.
                                              0
                                              Отлично! На последнем видео на 8-10 секунде выглядит реально объемно!
                                                0
                                                Потрясающе! Буду ждать продолжения!
                                                  0
                                                  Удобнее было бы конечно планшет в руках вертеть, а не головой у монитора.
                                                  +1
                                                  запатентуйте и зарабатывайте.
                                                  или уже поздно.
                                                    0
                                                    Патентовать можно то, что сам придумал. А эту технологию придумал не он.
                                                    Смотри ролики выше.
                                                      0
                                                      «А какая хорошая идея...» — «Карты, деньги, два ствола»
                                                    0
                                                    Вот только вдвоем не получится посмотреть в такой монитор
                                                      0
                                                      Вдвоем нельзя… Для двоих есть специальные 3д мониторы (уже много лет как есть, кстати), которые показывают реальное 3д, только вот дорого это все слишком.
                                                      +1
                                                      > Получается, что при приближении наш чайник должен не увеличиваться, а, наоборот, уменьшаться (для случая, когда он за «окном»)

                                                      Это логично, если учесть, что приближая нос к окну, можно увидеть больше всякого разного за этим окном. А визуально чайник должен при этом стать больше, потому что будет виден под бОльшим телесным углом.
                                                        +1
                                                        Логично то оно логично, когда знаешь:) А когда не знаешь для меня лично было весьма нелогично.
                                                        0
                                                        Практическое применения для планшета, кстати, — это способ показать нечто большее чем способен отобразить экран. Эдакая интуитивная замена скроллингу. Впрочем… На знаю — это надо пробовать, чтоб сказать, что удобнее.
                                                        0
                                                        Как и обещал, выложил исходники и собранное приложение.
                                                        Ссылки и комменты в апдейте в конце поста.
                                                          0
                                                          При попытке запустить ECE877_Final.exe говорит что не найден ippcore-5.3.dll и усё.
                                                          Похоже что-то не хватает в системе или в архиве с демкой.
                                                          Нашёл вот такую инфу.
                                                            0
                                                            Кстати система: Win7 SP1 x64 Rus.
                                                              0
                                                              Вы нашли правильную инфу. Надо стянуть с сайта Интела и поставить Intel® Integrated Performance Primitives. Эта дллка должна жить в системе.
                                                                0
                                                                Что именно нужно скачать и установить то из этого списка:
                                                                software.intel.com/ru-ru/articles/intel-IPP/

                                                                А нельзя ли отдельно выложить набор требуемых библиотек или положить их рядом с демкой?
                                                                  0
                                                                  К сожалению, не могу выложить redist IPP (надо покупать лицензию для этого).
                                                                  Вам надо найти IPP redistributable. По идее Вы можете стянуть триал Intel® Integrated Performance Primitives (Intel® IPP) for Windows* отсюда и в нем оно будет.

                                                            Only users with full accounts can post comments. Log in, please.