Нейронные сети уже везде. И фильтры в фотошопе, и подделка лиц в видео. Но многое пока ещё невозможно. Магические слова "сделай мне видео по моей любимой книжке" пока не работают. Хоть потихоньку мы и движемся к этому. В этой статье я попробую рассказать что сейчас делается в этом направлении и где проходит современный технический прогресс.
В прошлой своей статье я рассказывал про современные генеративные сетки, в первую очередь про StyleGan. Эмбединги и GAN - это красивая математика. Но на практике применений у них пока мало.
Сегодня я немного расскажу о чуть более прикладных подходах и проектах, которые помогают генерировать видео. Тут GANы тоже встречаются, но зачастую как малая часть системы, и куда больше значит логика и схема работ.
О чем будем говорить
Сейчас нейронные сети развиваются в область создания и манипулирования контентом. Началось все с каких-то простых фильтров для фотошопа и подходов для манипуляции лиц.
Это время прошло, и инструментов для видео появляется все больше и больше. Может быть многие помнят этот пример от Nvidia:
Тут, конечно, нейронная сеть была использована лишь для правки изображений ( https://github.com/NVIDIA/vid2vid )
В целом, говоря про улучшение видео, можно поговорить про подходы для улучшения изображений на нейронных сетях, варианты вырезания фона, замену лиц, тела, и.т.д.
Но я хочу сосредоточиться на одной теме: “как нарисовать произвольного человека в видео”. Сюда будут входить как и подходы для полного рендера, про которые говорит Nvidia, так и принципиально другие вещи, например “анимация человека видео напрямую”.
Общая логика
Давайте попробуем сформулировать задачи которые существуют, а дальше классифицировать на типы решения, разобрав каждый из них.
На сегодня существуют сотни работ на тематику “трансфер позы/трансфер движения”. И многие из них опираются на свою постановку задачи. Рассматривая все это многообразие для себя я выработал классификацию по наличию априорной информации (доступных для генерации данных) + по типу первичной генерации данных. Сначала про априорную информацию:
Есть предварительное изображение человека сгенерированное некоторым 3D движком:
Есть предварительная скелетная анимация человека, сгенерированная каким-нибудь подходом (про подходы поговорим позже)
Есть предварительная скелетная анимация человека + дополнительная карта тела (Сегментационные области тела/частей тела)
Есть предварительная скелетная анимация человека + дополнительная карта тела (Карта нормалей)
Есть только видео на которое надо перенести другого человека, нет никакой разметки
Есть только текстовое описание:
Теперь несколько способов на основе чего генерировать анимацию (их можно комбинировать!). Более подробно будут описаны ниже:
Полноценно сгенерированный человек при помощи 3D движка (способ 1)
Скелетная анимация через какой-нибудь MoCap костюм (способ 2)
Скелетная анимация/сегментация, снятая с другого человека (способ 3)
Скелетная анимация полученная из нейронной сети на основе какого-нибудь генератора (способ 4)
Теперь пройдем подробнее по каждому типу генерации: где его применяют и зачем.
Нейронки для улучшения рендеренга
В целом, улучшение рендеринга, это сравни тем “улучшалкам”, про которые я особо не хотел говорить в этой статье. Но в контексте анимации не могу не упомянуть про них. По сути это что-то среднее между “style transfer”/”поправить текстуру”/”поправить освещение”. Самые популярные работы в этом направлении у Nvidia. В первую очередь vid2vid. Именно её, как они уверяют, они использовали для создания видео с Дженсеном, приведенное выше (вот тут более полная версия рассказа + блогпост).
Процесс тут состоял из нескольких частей:
Полноценный 3д скан человека (использовался многокамерный подход), создание его 3д модели (способ 1)
Генерация жестов нейронной сетью (+ аналогичная сеть Audio2Face для анимации лица)(способ 4)
После чего через движок делают видео 3д модели
И обрабатывают это видео нейронной сетью которая, по сути, делает трансфер стиля “чтобы было похоже на реального Хуанга”.
При этом можно использовать принципиально другие подходы к рендерингу/нейронные сети могут помочь в других его проявлениях. Например вот тут:
ребята используют нейронную сеть чтобы сгладить/улучшить облако точек/починить проблемы 3д камер.
Примерно для таких же целей "улучшения" есть сетки по типу GanCraft, на которую вы могли наткнуться:
Нейронки для генерации по 2D-скелету
Сетка выше требует предварительно сгенерированного человека. Что не всегда просто. Посмотрим как задача решается в ситуации когда мы хотим сгенерировать изображение когда у нас есть только скелет.
Есть несколько вариантов входных данных/вариаций алгоритмов. Рассмотрим базовый. На мой взгляд это https://github.com/menyifang/ADGAN . С ним все сравниваются. Его реально запустить. У него наиболее понятный и очевидный подход. Официальные примеры на сайте очень даже убедительны!
На вход нужно подать человека которого мы моделируем. Плюс несколько дополнительных параметров для него:
Скелет
Сегментационную карту частей тела
И, вуаля, можно отрендерить. На практике, когда я решил поэкспериментировать, у меня не получилось такого качества как показывают авторы:
Что-то узнается, но, если честно, сильно хуже чем в примере авторов. Даже жалко нескольких потраченных вечеров (вечер запустить, ещё вечер обучить сетку детекции частей тела и ещё вечер - подобрать скелетную сетку чтобы собрать 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/
С такими результатами:
С сорсами тоже есть одна сетка. Но там:
Сильно более важно 3D, так как по сути текстурируется болванка предварительно выделенного тела
Качество сильно хуже.
У ребят есть рабочий колаб. Я запихнул себя на зеленом фоне - в принципе работает, но проблемы видны неподготовленным взглядом (текстура на стене отражается с передней части).
Пару слов про видео
Поговорим про трансфер текстура-текстура для видео. Эти подходы больше всего разрабатываются в Snap. И самые лучшие статьи по этой теме у них. Вы могли наталкиваться на First Order Motion Model из 2019 года или на более свежую Motion Representation for Articular Animation из 2021:
Идея и тут и там близка к тем что было выше в скелетах/расширенных скелетах, только завернуто с другой стороны и оптимизировано под видео:
В качестве опоры для восстановления используется скелет(FOMM)/сегментационная карта(MRAA) (только в данных работах они получаются из видео, а в тех что мы смотрели выше их можно получить и из других источников)
Используется различный Optical Flow для оценки ситуации в видео
Используется различный набор трансформаций для оценки того как изменилось положение человека.
Но нужно понимать ряд ограничений данного подхода:
Он сложнее вычислительно
Его сложнее обучать
Если захочется сделать генерацию видео не по текстуре, а по 3d модели - он потеряет часть данных, которые могут использовать подходы выше.
При этом нельзя отметить, что out-of-the-box результата такие сетки дают неплохое качество:
Про слова
Из свежего. Уже появились сетки которые могут как-то генерить изображение по тексту (NUWA). По сути метод основан на VQGAN. На базе которого Сбер недавно выпустил свою сетку. Да и в целом, как я и говорил в прошлой своей статье - очень перспективная работа, которая действительно определила развитие на следующие пол года.
Сорсов пока нет, анонс был две недели назад. Картинки выложенные авоторами подробнее можно посмотреть тут:
А прелесть VQGAN’а в том что можно создать любой Conditional Stream с априорными данными. Например авторы предлагают вот так:
Небольшое отступление по VQGAN
Раз мы упомянули про VQGAN, то сделаю небольшое отступление на его тему. Мне кажется что в следующие пару лет оно может упростить сегодняшние подходы.
Даже небольших вычислительных мощностей хватает чтобы сделать следующее (во второй половине этого видео я подробнее рассказываю как я потратил пару вечеров чтобы запустить это хозяйство):
Про основу для генерации
Теперь нужно вернуться и поговорить что используется в качестве основы для генератора. Я не буду глубоко рассказывать как это все делать, лишь обозначу возможные варианты.
Как вы заметили, самый простой подход - использовать в качестве основы другое видео. И использовать можно несколькими способами:
Напрямую передавая в алгоритм. Конечно, тут нужно понимать что многие алгоритмы не явно/полуявно используют те же скелетные/сегментационные модели при обучении. Но все же, при таком подходе - достаточно только текстуры.
Детектируя на его основе скелетную модель. Подборка сеток которая так умеет есть тут - 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”:
Для варианта Audio2Face у Nvidia есть даже открытый пример в их Omniverse - https://www.nvidia.com/ru-ru/omniverse/apps/audio2face/ (но с его помощью анимируется не картинка, а 3D модель). Для анимации изображения лица по аудио есть например Wav2lip или LipGan.
Есть подходы где анимация генерируется по вектору движения и по 3д местности:
Но в реальности, генерация действий человека, это отдельная тема которая заслуживает отдельной статьи. А если не забывать говорить про генерацию анимации для лица/генерацию артикуляции - там ещё сотни подходов:)
Заключение
Мне кажется, нельзя быть экспертом во всех тех областях, про которые я упомянул. Да и мы касались лишь каких-нибудь отдельных тематик из представленных. Но мне кажется, что такие обзоры помогают неплохо понять что сейчас происходит, зафиксировать текущий момент. Про вещи которые мне чаще попадаются в проде, когда нет достаточного объема для Хабра я пишу/рассказываю на своём канале - https://t.me/CVML_team (youtube, vk). На Ютубе даже есть видео версия этой статьи: