Как нейронные сети заменяют рендеринг +17



​Нейронные сети уже везде. И фильтры в фотошопе, и подделка лиц в видео. Но многое пока ещё невозможно. Магические слова "сделай мне видео по моей любимой книжке" пока не работают. Хоть потихоньку мы и движемся к этому. В этой статье я попробую рассказать что сейчас делается в этом направлении и где проходит современный технический прогресс.
В прошлой своей статье я рассказывал про современные генеративные сетки, в первую очередь про StyleGan. Эмбединги и GAN - это красивая математика. Но на практике применений у них пока мало.
Сегодня я немного расскажу о чуть более прикладных подходах и проектах, которые помогают генерировать видео. Тут GANы тоже встречаются, но зачастую как малая часть системы, и куда больше значит логика и схема работ.

О чем будем говорить

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

Это время прошло, и инструментов для видео появляется все больше и больше. Может быть многие помнят этот пример от Nvidia:

Тут, конечно, нейронная сеть была использована лишь для правки изображений ( https://github.com/NVIDIA/vid2vid )

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

Но я хочу сосредоточиться на одной теме: “как нарисовать произвольного человека в видео”. Сюда будут входить как и подходы для полного рендера, про которые говорит Nvidia, так и принципиально другие вещи, например “анимация человека видео напрямую”.

Общая логика

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

На сегодня существуют сотни работ на тематику “трансфер позы/трансфер движения”. И многие из них опираются на свою постановку задачи. Рассматривая все это многообразие для себя я выработал классификацию по наличию априорной информации (доступных для генерации данных) + по типу первичной генерации данных. Сначала про априорную информацию:

  • Есть предварительное изображение человека сгенерированное некоторым 3D движком:

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

С анимацией - https://github.com/menyifang/ADGAN/raw/master/gif/pose.gif
С анимацией - https://github.com/menyifang/ADGAN/raw/master/gif/pose.gif
  • Есть предварительная скелетная анимация человека + дополнительная карта тела (Сегментационные области тела/частей тела)

  • Есть предварительная скелетная анимация человека + дополнительная карта тела (Карта нормалей)

  • Есть только видео на которое надо перенести другого человека, нет никакой разметки

  • Есть только текстовое описание:

Теперь несколько способов на основе чего генерировать анимацию (их можно комбинировать!). Более подробно будут описаны ниже:

  • Полноценно сгенерированный человек при помощи 3D движка (способ 1)

  • Скелетная анимация через какой-нибудь MoCap костюм (способ 2)

  • Скелетная анимация/сегментация, снятая с другого человека (способ 3)

  • Скелетная анимация полученная из нейронной сети на основе какого-нибудь генератора  (способ 4)

Теперь пройдем подробнее по каждому типу генерации: где его применяют и зачем.

Нейронки для улучшения рендеренга

В целом, улучшение рендеринга, это сравни тем “улучшалкам”, про которые я особо не хотел говорить в этой статье. Но в контексте анимации не могу не упомянуть про них. По сути это что-то среднее между “style transfer”/”поправить текстуру”/”поправить освещение”. Самые популярные работы в этом направлении у Nvidia. В первую очередь vid2vid. Именно её, как они уверяют, они использовали для создания видео с Дженсеном, приведенное выше (вот тут более полная версия рассказа + блогпост).

Процесс тут состоял из нескольких частей:

  • Полноценный 3д скан человека (использовался многокамерный подход), создание его 3д модели (способ 1)

  • Генерация жестов нейронной сетью (+ аналогичная сеть Audio2Face для анимации лица)(способ 4)

  • После чего через движок делают видео 3д модели

  • И обрабатывают это видео нейронной сетью которая, по сути, делает трансфер стиля “чтобы было похоже на реального Хуанга”.

При этом можно использовать принципиально другие подходы к рендерингу/нейронные сети могут помочь в других его проявлениях. Например вот тут:

ребята используют нейронную сеть чтобы сгладить/улучшить облако точек/починить проблемы 3д камер.

Примерно для таких же целей "улучшения" есть сетки по типу GanCraft, на которую вы могли наткнуться:

Нейронки для генерации по 2D-скелету

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

Есть несколько вариантов входных данных/вариаций алгоритмов. Рассмотрим базовый. На мой взгляд это https://github.com/menyifang/ADGAN . С ним все сравниваются. Его реально запустить. У него наиболее понятный и очевидный подход. Официальные примеры на сайте очень даже убедительны!

На вход нужно подать человека которого мы моделируем. Плюс несколько дополнительных параметров для него:

  1. Скелет

  2. Сегментационную карту частей тела

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

Что-то узнается, но, если честно, сильно хуже чем в примере авторов. Даже жалко нескольких потраченных вечеров (вечер запустить, ещё вечер обучить сетку детекции частей тела и ещё вечер - подобрать скелетную сетку чтобы собрать realtime). Конечно, можно получше модельку для скелетов использовать. Можно подобрать более аккуратно входные картинки. Это даст прирост качества. Но до идеального далеко. С другой стороны - и статья двухлетняя.  Аналогов такой работы много. Но их не тестил/не запускал:

https://github.com/siyuhuang/PoseStylizer
https://github.com/Ha0Tang/XingGAN
https://github.com/rocketappslab/SCA-GAN

Забафанная сеть по скелетам

Плюс приведенных проектов - синтез идет только по скелету. А скелет достаточно просто нарисовать/отснять или синтезировать. Но, если дать чуть больше информации чем дает скелет - можно сделать сильно больше. Посмотрим какие есть варианты.

Первый подход

Первый вариант заслуживающий внимания - забафанный ADGAN - PISE (почти то же самое а PINet_PG):

Здесь генерация идет не только по скелету. К скелету добавляется сегментационная карта человека. Такую карту обычно не сложно создать  из генератора, либо заснять с реального человека. А в случае с PINet авторы даже пробуют сами синтезировать её:

Второй подход

Если чуть-чуть добавить данных, то все будет сильно проще для нейронки:)

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

Есть две хороших статьи текущего года которые так умеют (и обе без сорсов, так что нет уверенности что все работает!):

Pose with Style https://pose-with-style.github.io/ :

Который дает такие результаты:

И StylePoseGan https://vcai.mpi-inf.mpg.de/projects/Styleposegan/

С такими результатами:

С сорсами тоже есть одна сетка. Но там:

  1. Сильно более важно 3D, так как по сути текстурируется болванка предварительно выделенного тела

  2. Качество сильно хуже. 

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

Пару слов про видео

Поговорим про трансфер текстура-текстура для видео. Эти подходы больше всего разрабатываются в Snap. И самые лучшие статьи по этой теме у них. Вы могли наталкиваться на First Order Motion Model из 2019 года или на более свежую Motion Representation for Articular Animation из 2021:

First Order Motion Model
First Order Motion Model
Motion Representation for Articular Animation
Motion Representation for Articular Animation

Идея и тут и там близка к тем что было выше в скелетах/расширенных скелетах, только завернуто с другой стороны и оптимизировано под видео:

  • В качестве опоры для восстановления используется скелет(FOMM)/сегментационная карта(MRAA) (только в данных работах они получаются из видео, а в тех что мы смотрели выше их можно получить и из других источников)

  • Используется различный Optical Flow для оценки ситуации в видео

  • Используется различный набор трансформаций для оценки того как изменилось положение человека.

Но нужно понимать ряд ограничений данного подхода:

  • Он сложнее вычислительно

  • Его сложнее обучать

  • Если захочется сделать генерацию видео не по текстуре, а по 3d модели - он потеряет часть данных, которые могут использовать подходы выше.

При этом нельзя отметить, что out-of-the-box результата такие сетки дают неплохое качество:

Про слова

Из свежего. Уже появились сетки которые могут как-то генерить изображение по тексту (NUWA). По сути метод основан на VQGAN. На базе которого Сбер недавно выпустил свою сетку. Да и в целом, как я и говорил в прошлой своей статье - очень перспективная работа, которая действительно определила развитие на следующие пол года. 
Сорсов пока нет, анонс был две недели назад. Картинки выложенные авоторами подробнее можно посмотреть тут:

А прелесть VQGAN’а в том что можно создать любой Conditional Stream с априорными данными. Например авторы предлагают вот так:

Небольшое отступление по VQGAN

Раз мы упомянули про VQGAN, то сделаю небольшое отступление на его тему. Мне кажется что в следующие пару лет оно может упростить сегодняшние подходы.

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

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

Про основу для генерации

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

Как вы заметили, самый простой подход - использовать в качестве основы другое видео. И использовать можно несколькими способами:

  • Напрямую передавая в алгоритм. Конечно, тут нужно понимать что многие алгоритмы не явно/полуявно используют те же скелетные/сегментационные модели при обучении. Но все же, при таком подходе - достаточно только текстуры.

  • Детектируя на его основе скелетную модель. Подборка сеток которая так умеет есть тут - https://paperswithcode.com/task/pose-estimation. Но сама по себе тема очень большая и всеобъемлющая, их того что есть на Хабре советую - https://habr.com/ru/post/555162/  https://habr.com/ru/company/JetBrains-education/blog/354850/ (не совсем позы а общие идеи https://habr.com/ru/company/ods/blog/522836/ )

  • Детектируя сегментацией части человека. Тут нет ничего сложного. Вот тут можно почитать основные постановки/идеи - https://paperswithcode.com/dataset/mhp По сути, это может быть натренированый UNET

  • Детектируя 3д модель человека. Задачка называется DensePose https://paperswithcode.com/paper/parsing-r-cnn-for-instance-level-human . Но очень часто используется какая-то кастомная версия (Pose with Style, iPER).

Можно использовать для генерации любой 3D движок, в котором можно отрисовать человека. При этом, есть следующие варианты:

  • Можно генерировать изображение человека целиком (как пример Nvidia). Для этого понадобиться сделать плюс-минус качественный скан.

  • Можно генерировать только скелет

  • Можно генерировать скелет и маску частей тела/маску 

  • Можно генерировать карту нормалей/depth изображение

Мы в нескольких проектах использовали Unity для генерации таких данных. Я знаю, что люди делали и что-то полусамописное. Кто-то для похожих задач использовал Unreal.

Кроме 3D, зачастую надо сделать анимацию. И тут, опять же, много вариантов. Для того же Unity есть много предварительно сгенеренных анимаций. Несложно записать MotionCaption для целевых действий. Например мы делали такое когда генерировали датасеты с активностями и падениями в CherryLabs:

Nvidia для анимации Дженсона использовала красивый подход “audio2gestures”:

embedding-код для действий, в который проецируется аудио. https://svito-zar.github.io/audio2gestures/
embedding-код для действий, в который проецируется аудио. https://svito-zar.github.io/audio2gestures/

Для варианта Audio2Face у Nvidia есть даже открытый пример в их Omniverse - https://www.nvidia.com/ru-ru/omniverse/apps/audio2face/ (но с его помощью анимируется не картинка, а 3D модель). Для анимации изображения лица по аудио есть например Wav2lip или LipGan.

Есть подходы где анимация генерируется по вектору движения и по 3д местности:

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

Заключение

Мне кажется, нельзя быть экспертом во всех тех областях, про которые я упомянул. Да и мы касались лишь каких-нибудь отдельных тематик из представленных. Но мне кажется, что такие обзоры помогают неплохо понять что сейчас происходит, зафиксировать текущий момент. Про вещи которые мне чаще попадаются в проде, когда нет достаточного объема для Хабра я пишу/рассказываю на своём канале - https://t.me/CVML_team (youtube, vk). На Ютубе даже есть видео версия этой статьи:




Комментарии (2):

  1. v1000
    /#23798205 / +2

    Графика напомнила этот шедевр 1997 года.

    Хотя даже тогда это выглядило криповато.

    Но зато неплохо вписывалось в сеттинг.

  2. Sadler
    /#23798865 / +1

    Я когда-то в 2018 году тоже развлекался pose transfer (GAN + OpenPose). Очень радует, как развивается индустрия, и в плане разрешения, и в плане временной стабильности.