Костюм для захвата движения своими руками

Motion Capture – своими руками

Всем привет, меня зовут Серго, живу я в городе Чебяркуля, катаюсь на байке, работаю в небольшом продакшене.

Хочу рассказать о реализации motion-capture без участия студии и прочего дорогостоящего оборудования. Данный способ получения движений занимает какоето время, но если всё грамотно один раз настроить, чтобы можно было потом быстро использовать в какихнибудь проектах, эта техника найдёт своё применение.

Рассмотрим пример лицевой анимации персонажа, что нам понадобится:

  1. Камеры, — будет очень неплохо, если у Вас под рукой 2 или более камеры, но в этом примере мы обойдёмся одной, я использовал встроенную веб-камеру в ноутбук;
  2. Зеркала, 2шт – они и заменят нам недостающие камеры;
  3. Маркеры — можно использовать кусочки липкой ленты, но они бликует на свете и плохо отлипают от кожи или, же наоборот хорошо прилипают не туда куда надо (проверено автором :), будем использовать синий фломастер (маркер), синий потому, что его будет хорошо видно на коже;
  4. Свет, — важно осветить актёра равномерно со всех сторон съёмки, будем использовать настольную лампу;
  5. Актёр — я снимал сам-себя почти без посторонней помощи (;
  6. И наконец программа, без которой нам не обойтись — PFTrack

И так начнём!

Организовываем съёмочную площадку — установим камеру на небольшом расстоянии от лица актёра, далее установим зеркала так, чтобы в видоискателе было хорошо видно лицо актёра и его отражения, примерно вот так:

Вид сверху нашей студии будет выглядеть так:

Небольшое отступление, важно чтобы соблюдалось равенство: Z = A + B = X + Y, где Z — фокусное расстояние нашей одинокой камеры, а A+B и X+Y — фэйковые фокусные расстояния двух других камер соответственно. Но на самом деле равенство выполнятся не будет, Z будет всегда меньше, что приведёт к небольшой погрешности в виде немного углублённой формы лица в бедующем, но это нестрашно (: вот такая вот геометрия.

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

Мотор!

Произносим заранее подготовленную речь, ну или что-нибудь в духе «Превед, я креведко!», стоп. Смотрим чего у нас там отснялось, если всё нормально, все точки отчетливо видны и не уходят за пределы видоискателя идём дальше.

Загружаем отснятый материал в какой-нибудь композер, я использовал After Effects, режим кадр на три части, и сохраняем каждую в отдельную секвенцию предварительно отцентровав и флипнувпо горизонтали видео из зеркал, можно ещё немного поиграть с шарпеном и цветом. Для удобства назовём их center.avi, left.avi и right.avi

Переходим в PFTrack.

PFTrack — позволяет реализовывать различные задачи по трэкингу и нахождению движения камеры, мы же в данном уроке коснёмся только задач связанных с motion capture.

Создаём новый проект File — New Project, смотрим, что тут есть интересного.

Интерфейс программы интуитивно понятен, я разобрался со всем с первого раза непребегая к help

Жмём кнопку Import Footage, в появившемся окне выбираем наши центральную камеру center.avi, жмём load. Видим, что имя камеры автоматически поменялось на center, далее заходим в свойства нашей камеры — Camera — Camera Parameters или «ctrl+p» на клавиатуре.

Меняем тип камеры на Motion Capture, а также указываем, что фокусное расстояние мо время съёмки неменялось и нам неизвестно.

Жмём close. Обратим внимание, что ранее неактивная кнопка Import Footage, снова стала активной. Добавляем оставшиеся сиквенции left.avi и right.avi.

Теперь нужно синхронизировать все наши сиквенции, на самом деле нам этого делать ненужно, потому что снимали всё одной камерой, просто проверим, что все камеры стоят на начале и нажмём кнопку Sync

можно сильно упростить себе жизнь, если выставить окошки камер так, чтобы можно было всё сразу отслеживать, воспользуемся кнопками меню New Window и Tile Window Layout.

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

Смотрим на нашу центральную камеру, начнём с неё, потому-что на ней отчётливо видны все маркеры на протяжении всего видео. В PFtracke существует два типа 2d трэкеров: автоматические — Auto Features и пользовательские — User Features, мы воспользуемся вторыми, они позволяют точнее контролировать нужные нам области. И так, нажмём ctrl-F3 или выберем в меню Tracking — New User Features и выберем наш центральный маркер на лбу, раздвинем области трэкера как показано на рисунке, назовём его lob_c

Читайте также:  Оригинальный журнальный столик своими руками

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

В процессе трэкинга программа может выдавать ошибки, это нестрашно. Они могут быть вызваны несколькими причинами, восновном неправильно настроенной выдержкой из-за плохой освещённости, как это было с моей веб камерой. Решить эту проблему можно покрутив параметры в меню Trackig — Tracking parameters. либо использовать больше света при съёмках и более лучшую камеру, надеюсь, что у Вас таких проблем невозникнет (:

Далее нужно повторить все эти действия с каждым маркером, т.е. встаём на начало видео, заново нажимаем ctrl-F3 выбираем следующий маркер, двигаем ограничители трэкера, жмём Track Forwards. Советую называть трэкеры так чтобы было понятно чему она соответствует, например я следовал такому принципу: eye_L, eye — в переводе Глаз, _L — слева, всё это пригодится в дальнейшем.

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

Итак мы имеем 2д координаты всех трэкеров со всех камер, теперь нам нужно преобразовать их в трёхмерные координаты, сделать это очень просто, основная работа позади (:

Чуть не забыл, для ускорения и точности дальнейшего просчёта необходимо указать неподвижные участки лица, выделяем точки носа и лба о которых было сказано выше, жмём Tracking — Constraints, в появившемся окне сначала нажимаем New потом выделяем наши точки справа, потом кнопку » 766 0 850 130

Источник

Как я делал костюм захвата движений

Предисловие

В своем небольшом городе я занимаюсь решением нетривиальных технических задач. Так и в этот раз, организаторы одного шоу, в котором должна была выступить гимнастка со своей программой, решили добавить в ее представление некоторую «изюминку». А именно, выводить на экраны силуэт гимнастки, который бы повторял ее движения и как-то взаимодействовал с прочими эффектами, да так, чтобы все было интерактивно. Решить задачу «в лоб» не удалось. Kinect явно не справлялся со своей задачей и не был способен произвести захват движений человека, который удален от него на расстояние минимум 10 метров, к тому же в темноте. Так было принято решение сделать что-то «свое». Забегая вперед, скажу что выступление так и не состоялось, однако я настолько загорелся идеей, что продолжил свои эксперименты в качестве отдельного проекта, который впоследствии получил название impulse.

Начало работы

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

  • Arduino UNO — всем известный контроллер-конструктор, который позволяет за короткое время разработать прототип.
  • HC-06 — bluetooth модуль, послужит как средство беспроводной коммуникации. Модуль очень простой, имеет UART-интерфейс.
  • MPU-6050 — единственные доступные для меня инерционные датчики на тот момент. Приобрел сразу 2, чтобы проверить как они работают в паре, ведь в будущем необходимо использовать до 15 датчиков в одной системе. Этот сенсор сочетает в себе акселерометр и гироскоп, а так же датчик температуры для корректировки выходных данных.

Получив все из этого списка мне уже не терпелось увидеть mpu в действии. На официальном форуме Arduino присутствовали несколько примеров использования этих датчиков, один из них я и использовал. Для подключения сенсоров используется 5 пинов (контактов):

  • VCC, GND — тут все понятно, питание и земля. Стоит отметить что рабочее напряжение сенсора 3.3v, но и на 5v он чувствует себя неплохо. Потребляемая мощность меньше 0.05Ah
  • SCL, SDA — собственно пины, по которым происходит «общение» с сенсором. Эти пины отвечает за интерфейс i2c. Этот интерфейс реализует коммутацию между устройствами на одной шине, другими словами шина — это улица, а дома на ней — устройства.
  • INT — пин для прерываний. Как только данные на сенсоре готовы, главный контролер забирает их по прерыванию.
Читайте также:  Комбикорм для бройлеров своими руками таблица расчета

Однако этот пример выводил в терминал только «сырые» значения с акселерометра, и для преобразования в привычные углы был написан код, а далее и реализован Фильтр Калмана, и все это вместе занимало уже порядка 70% ресурсов Arduino UNO. Тем не менее, в терминал уже приходили довольно плавные значения углов, устройство довольно шустро ориентировалось в пространстве, правда всего пару минут, после чего FIFO буфер переполнялся. Но Оно работало!

Стабилизируем!

Постепенно радость от рабочего датчика омрачалась продолжительностью работы всей системы. Сколько я не боролся с FIFO-буфером, он переполнялся. Тут стоит отметить что информации на то время о данных сенсорах и вообще подобных системах было мало, и ее приходилось собирать буквально по крупицам. Решив, что проблема кроется в реализации интерфейса i2c начал гуглить в этом направлении и нашел пользовательскую библиотеку I2Cdev, призванную заменить стандартную библиотеку wire для arduino. Приятным сюрпризом оказались вложенные примеры использования этой библиотеки в связке с mpu-6050. Перестроив проект на этой библиотеке, я так же получал сырые данные и преобразовывал их в углы своим кодом, но никаких переполнений уже не было. Эта была маленькая победа. В дальнейшем, изучая внутренности библиотеки я обнаружил много полезного. Так например, теперь используются данные с обоих сенсоров — и акселерометра и гироскопа. Дело в том, что акселерометр позволяет определять точные углы наклона прибора только в состоянии покоя, пока на него не действуют внешние силы, а компенсировать эти самые силы призван гироскоп. Очевидным стало использование данных с обоих сенсоров, и тут нашел применение комплементарный фильтр. Однако появилась проблема нулевого дрейфа, но об этом позже.

Больше сенсоров!

И вновь подводный камень. На этот раз проблема, которая предстала передо мной, заключалась в использовании второго датчика mpu-6050. Я уже приводил аналогию i2c интерфейса в этой статье, где шина — это улица, а устройства — дома. Представим что пакет данных, которые должны добраться до определенного устройства — это почтальон. Почтальону необходимо 2 вещи — посылка и адрес, и у каждого дома есть свой уникальный адрес, так и у устройств должны быть свои адреса. Проблема заключается именно в адресе датчика mpu-6050, он один на все такие датчики — 0x68. Этот адрес прошивается в контроллер датчика еще на заводе, а найти прошивку и изменить адрес для каждого датчика не представляется возможным. Забугорные форумы выдали один вариант решения — подключение сенсоров друг за другом, одна нога первого сенсора подключается к пину AD0 второго, и становится доступным по адресу 0x69, но такой способ предполагает использование не более 2 mpu и я сразу его отбросил.

Решением стали транзисторы. Идея заключалась в том, чтобы перед каждым датчиком поставить по паре транзисторов на пины i2c и открывать их поочередно. Алгоритм простой — необходимо считать данные с 5-го датчика, закрываем все гейты кроме 5-го (или открываем его при необходимости) и производим считывание, дальше подобным образом получаем данные с остальных. Результат видно на первом фото в этой статье, и он вполне себе работоспособный. Подобным образом мне удалось подключить 4 датчика, это не лучшим образом повлияло на стабильность, а когда у меня закончились транзисторы я решил использовать более компактные и стабильные микросхемы.

Единственное сохранившееся фото с той стадии (извиняюсь за качество):

Гейт-контроллер

Устройство, которое будет сочетать в себе эти микросхемы и позволять общаться с множеством датчиков mpu, я назвал гейт-контроллер. Его мне помог изготовить хороший знакомый, который уже имел опыт с травлением плат, а мне нужно было качество, которым мои предыдущие попытки в травлении не обладали. Из-за множества перекрещивающихся дорожек требовалась двухслойная плата, но в качестве прототипа сгодилась и многоуровневая. Результатом этой работы стала вот такая необычная плата:

Теперь остается проверить устройство в действии. Подключив сразу 10 датчиков, в мониторе появилось ровно столько же приятных сообщений об успешной инициализации — устройство работает!

Гимбл лок, кватернионы, визуализация

Гимбл лок, по-русски шарнирный замок или же складывание рамок — неприятное явление в области гироскопов и в некоторых случаях ориентирования в пространстве. Без долгого объяснения этого явления (есть хорошо объясняющие и наглядные видео на эту тему) я лишь скажу, что этот самый шарнирный замок не позволяет вертеть сенсором на все 360. Оси X Z (отклонения от горизонтальной плоскости) ограниченны примерно от -45 до 45 градусов, и не определяются корректно за этими пределами. Подробнее изучив эту тему, оказалось что решение находится у меня под носом. MPU-6050 это шестиосевые датчики, и на борту у них присутствует dmp. Dmp (DIgital Motion Processor) занимается всем тем, что я так долго писал в основном коде для прошивки главного контроллера, и даже фильтрует значения. К тому же, dmp может выводить данные в виде кватернионов, что позволяет обойти шарнирный замок, а так же это позволяет уменьшить размер пересылаемых пакетов. На этом моменте продолжилось мое знакомство с кватернионами, ранее я работал с ними в Unity3D и имел какое-то представление. Говоря простым языком, кватернион — это система чисел (4 числа) которая описывает поворот чего-либо в пространстве. Как раз вспомнив про Unity, я попробовал изобразить нечто такое:

Читайте также:  Кухонные столы под старину своими руками

Контроллер

Arduino и гейт-контроллер себя вполне оправдали, но их использование в финальном варианте не предполагалось. Пришло время сделать контроллер, специфичный и заточенный под конкретную задачу. К тому моменту я изрядно модифицировал прошивку для будущего контроллера, сконфигурировал dmp оптимальным образом, что позволило отказаться от использования прерываний. Таким образом каждый сенсор подключался по четырем пинам, а не пяти, как прежде. Так же отпала необходимость в двух из шести микросхем в гейт-контроллере. Все эти улучшения привели к тому, что плата для будущего устройства была спроектирована в 2 стороны, и никаких «надуровней» больше не требовалось.

Корпус

Устройство постепенно обретало свой финальный вид, и следующим шагом было логично сделать корпус. Очевидное решение — это заказать или обратиться к услугам 3D-печати. Но это все просто и неинтересно, поэтому на пару c другом приобрели свой собственный 3D-принтер. Ввиду отсутствия любой инструкции собирали его на интуитивном уровне, но все получилось. Вообще сборка, настройка, и сама подготовка к печати заслуживают отдельной статьи, но сейчас не об этом. Использовав весь пробный материал, оставалось только ждать пока придет ABS-пластик.

Для моделирования была выбрана программа 123D-Design. Программа интуитивно понятна, и любой, кто хоть немного имеет опыт работы в редакторах трехмерной графики быстро ее освоит.

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

Ввиду некоторых обстоятельств, я отложил Unity3D «на потом», сроки поджимали и нужно было быстро написать программу для визуализации. Я уже давно работаю с графическим движком Xors3D (Может кто знает такой) и на этот раз он меня не подвел. Однако после того как он себя оправдал, я не вернулся к Unity, а продолжил разработку визуальной среды для костюма именно на этом движке.

Список текущих возможностей:

  • Визуализация — в программе отображается модель человека, которая в реальном времени повторяет все движения за человеком в костюме
  • Авто-калибровка — позволяет в любое время моментально калибровать костюм
  • Позиционирование — модель так же перемещается в пространстве как и человек, может приседать, ходить и т.п.
  • Запись/воспроизведение — все движения можно записывать и воспроизводить
  • Режим взгляда от первого лица — предусмотрен вывод изображения для oculus rift и других шлемов виртуальной реальности.
  • Интерактивность — человек носящий костюм может воздействовать на виртуальный мир. Пинать мячи, открывать двери, крутить карусель и т.д. (физический движек)

Заключение

На данный момент проект имеет 1 полностью рабочий, автономный, носимый и беспроводной прототип и все необходимое программное обеспечение. На разработку этого костюма ушло 8 месяцев (2 из которых я отдыхал, итого 6), но для меня это целая эпоха. За время проекта я прокачал свои навыки, попробовал и сделал много того, в чем раньше слабо разбирался, смог немного заработать.

Когда я начинал, был только интерес «а как это работает?» и о существовании подобных костюмов я еще не знал. Однако за время разработки как минимум 3 подобных проекта вышли на краудфандинговые площадки, и мне захотелось как-то развить impulse в качестве коммерческого проекта, но крайне тяжело заявить о себе сидя в Забайкальском крае. Сейчас не хватает мотивации сесть за второй прототип, уже беспроводной и на базе 9-ти осевых сенсоров, так что скорее всего этот проект останется для меня просто огромным и полезным опытом. В этой статье я хотел резюмировать всю проведенную работу, правда тут не отображено и 20% от нее. Не всем будут интересны тонны кода и часы пайки, 3d-печати, множество проб и ошибок, куча израсходованного материала, однако я постараюсь ответить на подобные вопросы в комментариях.

Источник

Оцените статью
Своими руками