По сути, я собираюсь показать вам видео ниже и объяснить, как это было сделано. Итак, вот видео:

Входы

Единственным важным входом, который команда Punch-To-Face (PTF) получила для создания этого видео, были 2 видеозаписи боя с разных точек зрения: основная камера, и мы также использовали другую камеру для части, начинающейся в 01:18. Мы также собрали небольшой набор данных примерно из 300 кадров из видеороликов MMA на YouTube для обучения моделей семантической сегментации. Помимо этого, я также арендовал сервер Hetzner с графическим процессором GTX1080, чтобы быстрее обучать алгоритмы глубокого обучения.

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

  • на нашем изображении холст менее яркий;
  • логотипы могут не везде идеально совпадать;
  • тени не настоящие, а «перенесенные» из сырого видео в наше.

Алгоритм

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

  1. Нарезайте видео на кадры с помощью ffmpeg

Затем для каждого кадра делаем следующее:

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

3. Найдите положение каждой камеры
- по перемещению ориентиров (логотипов и т. Д.) На сегментированном холсте мы можем определить, в какую сторону движется камера.

4. Рендеринг холста и дополнительных эффектов в Blende r
- Узнав положение камеры, мы можем визуализировать анимацию холста и 3D-анимацию в Blender из соответствующий ракурс камеры

5. Оценивайте тени и применяйте их для рендеринга
. Мы используем наш собственный алгоритм, основанный на глубоком обучении, для наложения теней.

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

После этого последний шаг:

7. Сделать финальное видео из папки с обработанными кадрами
- Каждый обработанный кадр мы сохраняем в папке, которая затем конвертируется в окончательное видео с помощью ffmpeg

Теперь давайте рассмотрим каждый шаг более подробно.

Нарезка видео на кадры и обратное преобразование кадров в видео

Здесь особо не о чем говорить, потому что все, что нужно сделать, это загрузить ffmpeg, а затем запомнить две консольные команды.

Чтобы разрезать видео на кадры:

ffmpeg -i $ VIDEO_NAME% 04d.jpg

Перейдя в папку с кадрами, можно запустить команду ниже, чтобы создать видео:

ffmpeg -pattern_type glob -i * .jpg -c: v libx264 -vf fps = 25 -vf scale = 1280: -2 -pix_fmt yuv420p $ VIDEO_NAME

Семантическая сегментация

Для обучения модели семантической сегментации я использовал следующие библиотеки с открытым исходным кодом для упрощения работы: PyTorch, pytorch-toolbelt, albumentations, segmentation-models-pytorch, pytorch-lightning. Чтобы получить общее представление о том, как работает семантическая сегментация с использованием архитектур нейронных сетей UNet, ознакомьтесь с этой лекцией от fast.ai

Pytorch-ligtning помогает структурировать проект. Как отметил Джереми Ховард, в обучении нейронной сети есть 3 основных элемента: данные, модель и потери. Используемая модель была UNet с классификатором se_resnext50_32x4d, принадлежащим ImageNet, используемым в качестве кодировщика. Я сам знаю только в общих чертах, как это работает, однако он работает волшебно и является архитектурой сегментации по умолчанию, используемой в соревнованиях Kaggle. В настоящее время происходит переход к использованию EfficientNets, однако для проектов с достаточной доступностью данных se_resnext50_32x4d обеспечивает очень хороший компромисс между качеством и временем обучения. Реализация в segmentation-models-pytorch очень хорошая, поэтому я импортировал архитектуру и предварительно обученные веса из этого репозитория.

Что касается проигрыша, то после анализа соревнований Kaggle и чтения сообщений в сообществе OpenDataScience, как правило, наилучшие результаты дает комбинация различных проигрышей (например, проигрышей Dice, Focal и CrossEntropy). К счастью, такая совместная потеря уже реализована в pytorch-toolbelt, который я использовал в своем конвейере.

Данные - самый сложный элемент, который сильно различается от проекта к проекту. Я использовал стандартные torch.Dataset и torch.DataLoader для управления выборкой данных. Используемый набор данных, как я упоминал ранее, включал 300 изображений с YouTube различных боев ММА. Мы также использовали технику активного обучения, чтобы улучшить качество сегментации. При запуске нашей обученной нейронной сети для наших видео мы выбирали кадры с плохими сегментами, помечали их и повторно обучили модель. Это одна из форм переобучения, которая является полулегальной :)

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

Что касается расписания тренировок, нет единого мнения о том, как тренировать нейронные сети, и я думаю, что у каждого свой «стиль». Я использовал MultiStepLR, начиная с относительно низкой начальной скорости обучения. По моему опыту, с достаточно большим набором данных и описанной выше настройкой при разумной скорости обучения можно в конечном итоге прийти к разумному результату.

Калибровка и отслеживание камеры

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

Для определения местоположения, поворота и поля зрения камеры существует три типа алгоритмов:

  1. Безмаркерные сенсоры с использованием GPS, гироскопов и другого оборудования
    Такие методы требуют дорогостоящего высокоточного оборудования и, таким образом, исключены в качестве опции для Punch- Проект To-Face. Утверждается, что некоторые методы не содержат маркеров, если в среду не вставлен фактический маркер. Но очень часто в таких методах используются некоторые сведения о сцене, например, с использованием «людей в качестве маркеров» для самокалибровки. В моей классификации такие методы попадают в следующую категорию.
  2. На основе обнаружения и сопоставления ключевых точек на маркерах
    Вы знаете, что в нашем случае есть некий маркер, холст, и поэтому вы найдете ключевые точки с известные координаты (или неизвестные, но у вас есть способ узнать их приблизительно). Затем, используя какой-либо метод оптимизации, вы минимизируете ошибку повторного проецирования этих ключевых точек.
  3. На основе выравнивания изображения
    Мы знаем, как маркер выглядит в кадре, и находим параметры, которые выравнивают нашу модель маркера с фактическим маркером в видео.

Для нашего демонстрационного видео мы реконструировали модель холста и использовали методы на основе выравнивания изображений и ключевых точек для использования этого маркера. Для алгоритмов на основе ключевых точек мы использовали готовые детекторы признаков из библиотеки OpenCV, такие как AKAZE и SIFT. Наилучшие результаты показал SIFT, однако недавно он был удален из библиотеки OpenCV по патентным причинам. После того, как мы нашли ключевые точки, мы использовали методы оптимизации черного ящика, такие как Differential Evolution и Nelder-Mead из scipy.optimize, чтобы найти параметры камеры.

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

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

Визуализация в Blender

В то время как в консоли Blender python отсутствует документация, ее классы и объекты хорошо организованы, консоль можно взломать. Сообщество Blender также очень полезно, и много раз я мог найти несколько сообщений на StackOverflow, которые решали мою проблему, хотя иногда мне приходилось тратить много времени на поиск. Особенно проблематичным было преобразование параметров камеры OpenCV в Blender, однако, прочитав достаточно, мне удалось придумать этот код.

Вот список полезных уловок:

  1. Если масштаб сцены отличается от масштаба, который вы использовали при оценке параметров камеры, поворот и фокусное расстояние не изменяются вместе с масштабом, а перемещение изменяется пропорционально.
  2. То же самое применимо, если ваша сцена центрирована по-другому. Просто подставьте смещения от векторов местоположения объектов
  3. Используйте излучающее освещение. Настроить освещение немного сложно, и я обнаружил, что изменение испускаемого освещения материала - это более простой способ добиться желаемого градиента и яркости. Иногда сочетание простой лампы и излучающего освещения дает потрясающие результаты.
  4. Переключайте видимость различных объектов, если хотите сэкономить время рендеринга
  5. Используйте скрипты Blender и фоновый режим. С их помощью вы можете автоматизировать весь конвейер, что сэкономит много времени и нервов.

Оценка и применение теней

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

Тени, которые вы видите на видео, были созданы нейронной сетью, обученной на чисто синтетическом наборе данных, то есть при обучении нейронной сети мы не использовали никаких реальных изображений. Следовательно, результаты могут быть не идеальными, особенно на изображении ниже, которое не вошло в окончательное видео:

Я использовал предполагаемое положение камеры и сгенерировал набор данных из 3000 случайных изображений в Blender, который выглядит следующим образом:

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

Объединение визуализации и реального видео

Процесс прост, по сути, это копирование-вставка. Мы копируем из визуализированного изображения и вставляем в реальное видео. Чтобы определить область копирования, мы используем результат шага 2 + любые дополнительные маски, используемые Blender.

Например, давайте посмотрим, как был сделан кадр в 00:33.

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

Эффекты

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

  1. 2D-анимация на холсте
    Примеры включают взрыв в 00:17 и обратный отсчет, начинающийся в 00:19. Мы использовали видео, сделанное командой Punch-To-Face, и добавили его в качестве видеотекстуры в Blender.
  2. Круги вокруг ног бойца в 00: 27–00: 31
    Мы использовали выходные данные детектора позы AlphaPose, чтобы определить, где ноги находятся в кадре, затем перепроецировали положение ног из кадра на текстуру и нарисовали анимированные круги вокруг этого места. .
  3. Анимация 3D-объекта в 00: 32–00: 34
    Принцип, лежащий в основе этого эффекта, объясняется в разделе «Объединение визуализации и реального видео».
  4. Ссылки на социальные сети 00: 37–00: 40
    Мы просто указали координаты, в которых должна отображаться анимация, и использовали альфа-канал, чтобы вырезать соответствующую часть
  5. Трехмерная инфографика (например, пончик-бар-чат) 00: 44–00: 51
    Принцип, лежащий в основе этого эффекта, объясняется в разделе «Объединение визуализации и реального видео». Наш дизайнер предоставил нам анимацию, мы отрендерили объект и маску, а затем скопировали их в настоящее видео.
  6. Визуализация скелета 00: 57–01: 04
    Мы использовали вывод AlphaPose плюс дополнительную эвристику и удаление выбросов для сглаживания анимации.
  7. Передача вида через трехмерный мир 1: 13–1: 18
    Мы полуручно (результаты, полученные с помощью нейронных сетей были недостаточно хороши и позже были уточнены дизайнерами) перестроили сцену в Blender, а затем использовали оценочные данные. начальное и конечное положения камеры для анимации камеры

Заключительные замечания

Большое спасибо за чтение статьи. Надеюсь, теперь у вас есть общее представление о том, что нужно для создания собственного проекта в пространстве дополненной реальности, используя только инструменты с открытым исходным кодом. Пожалуйста, также проверьте другой мой блог по теме здесь и сайт проекта Punch-To-Face.

Удачи в ваших собственных проектах и ​​увидимся позже!