🎨 Используем CycleGAN для применения стиля к видео, полученному с веб-камеры
Вы когда-нибудь задумывались, как выглядел бы ваш портрет работы Моне? Или легендарного Ван Гога? Современные технологии позволяют увидеть это своими глазами.
Замечание: эта статья подразумевает, что вы уже знаете, что такое GANы. Вот отличный ресурс, объясняющий, что это такое.
Чем больше я изучал CycleGAN, тем больше меня привлекала одна из областей его применения: передача стиля (style transfer). Цель передачи стиля – это изучение того, как поставить в соответствие изображениям из пространства A изображения из другого пространства B. Классический пример – одно из пространств является коллекцией фотографий, а второе – картины знаменитого художника, например, Клода Моне. Применение передачи стиля заставляет обычные фотографии выглядеть так, как если бы их рисовал Моне.
Этот процесс известен как перевод изображений, и традиционно он требует большого набора данных с парными изображениями – то есть, для обучения переводу вам нужны рисунки и фотографии одних и тех же мест, сделанные под одним и тем же углом, в одно и то же время дня и так далее. По очевидным причинам, получение таких парных данных нереалистично, а зачастую даже невозможно. Разве не было бы замечательно, если бы можно было переводить изображения в картины без парных примеров? Эта задача была исследована, и в результате появился эффективный беспарный метод перевода изображений в виде "циклически-согласованных соревновательных сетей" (CycleGAN), использующих архитектуры GAN для изучения необходимых соответствий и выполнения высококачественного перевода изображений. Меня заинтересовало, насколько эффективен CycleGAN при обработке видео, поэтому в этой краткой статье я приведу краткое описание принципов работы CycleGAN, а потом расскажу, как использовать официальную реализацию CycleGAN для применения художественных стилей Моне, Ван Гога и прочих к вашей собственной веб-камере.
Идеи, лежащие в основе CycleGAN
Понять всю архитектуру CycleGAN довольно сложно. Держа в уме цели CycleGAN и влияние этих целей на архитектуру, вы сильно упростите себе ее понимание. CycleGAN имеет следующие цели:
Научиться устанавливать соответствие и переводить изображения из пространства X в пространство Y (и наоборот)
Сохранять целостность изображений: изображение из пространства X, переведенное в пространство Y (и наоборот) должно выглядеть, как исходное изображение, но с применением необходимых стилистических изменений.
Здесь генератор G принимает изображение X и генерирует изображение G(X), выглядящее так, как могло бы выглядеть изображение из пространства Y. Дискриминатор DY пытается корректно отличить сгенерированные изображения от случайно выбранных изображений из пространства Y. G пытается минимизировать эту цель (генерируя реалистичные изображения), а DY пытается его максимизировать (верно различая сгенерированные и реальные изображения). Эта же цель может использоваться при установке соответствия и переводе из пространства Y в пространство X.
Одного этого недостаточно для достижения желаемой передачи стиля. Обучение с одними соревновательными потерями приведет к успешной генерации из пространства X в пространство Y, но не даст гарантий того, что сгенерированное изображение будет похожим на оригинал. Мы хотим, чтобы преобразование было "цикло-устойчивым", то есть изображение, переведенное в целевое пространство, а затем переведенное обратно, должно быть как можно ближе к исходному изображению: X -> G(X) -> F(G(X)) примерно эквивалентно X, где F – это генератор, переводящий изображения из пространства Y в пространство X.
Чтобы обеспечить этот принцип и достичь нашей второй цели, определим функцию потерь цикло-устойчивости, показанную ниже. Эта функция потерь стимулирует, чтобы X -> G(X) -> F(G(X)) было примерно эквивалентно X, а Y -> F(Y) -> G(F(Y)) было примерно эквивалентно Y.
Итак, у нас есть три функции потерь, которые мы используем для обновления весов CycleGAN в процессе обучения:
Соревновательные потери G против DY (X -> Y)
Соревновательные потери F против DX(Y -> X)
Потери цикло-устойчивости.
Этих функций потерь достаточно для обучения CycleGAN. Стоит упомянуть, что полезно добавить еще потери идентичности, которые помогают сохранять цвет и тон переводимых изображений.
Автор CycleGAN рекомендует присваивать этим функциям потерь разные веса с помощью переменной lambda. Если вас интересует, что это такое, или какие-либо другие аспекты архитектуры CycleGAN, (например, архитектура слоев), я советую вам обратиться к исходной статье. А теперь, имея некоторое представление о CycleGAN, давайте заставим ее работать с веб-камерами!
Применяем передачу стиля к вашей веб-камере
Чтобы применить стиль Моне, Ван Гога или какой-нибудь другой к вашей веб-камере, мы будем использовать предобученные модели CycleGAN, созданные авторами статьи. Начнем с клонирования репозитория и перейдем на корень в терминале или командной строке. Оттуда нужено запустить несколько bash-команд, предоставленных в папке ./scripts, чтобы загрузить необходимые модели.
Эти команды сохранят предобученные CycleGAN'ы в папке ./checkpoints.
Теперь мы создадим в корневой папке файл Python по имени webcam.py – измененную версию test.py, который вместо прогона набора данных через CycleGAN пропустит через нее поток данных с веб-камеры.
Когда вы создадите файл webcam.py, начните с импорта необходимых пакетов:
Затем скопируйте из test.py строки кода для разбора параметров из командной строки:
Мы собираемся изменить параметры webcam.py, отредактировав ./options/base_options.py иустановивтребуемое логическое значение --dataroot в False, поскольку при использовании веб-камеры нам не нужно указывать папку с данными.Теперь мы используем cv2 для настройки нашей веб-камеры и выдачи ошибки в случае неудачи:
Теперь мы добавим код, получающий фреймы с веб-камеры и выполняющий необходимые преобразования, чтобы наша загруженная модель могла читать и переводить их:
В конце концов, мы показываем стилизованные фреймы в новом окне. Если пользователь в любой момент нажмет клавишу "Esc", это окно закроется.
В данный момент вы уже можете запустить webcam.py с выбранной вами моделью CycleGAN, используя следующую команду из корневой папки:
Если это вас устраивает – прекрасно! Вы уже готовы использовать другие предобученные модели, изменяя параметр --name. В следующем разделе я покажу вам, как добавить чуть больше функциональности: переход с одного стиля к другому в реальном времени по нажатию клавиши.
Переход от одного стиля к другому
Вставить возможность переключения стилей вашей веб-камеры в реальном времени не так уж сложно. Начнем с создания списка имен моделей, между которыми вы хотите циклически переключаться и инициализации переменной, хранящей индекс в этом списке.
Мы также хотим вывести текст в верхнем левом углу окна, сообщающий о текущем применяемом стиле. Начнем с задания нескольких параметров для расположения надписи и ее шрифта.
Чтобы поместить текст в левом верхнем углу, мы используем функцию cv2.putText(), а для изменения стилей добавим условие, что при нажатии клавиши 'c' программа должна загрузить следующую модель из списка style_models. Полная итоговая реализация webcam.py приведена ниже:
Этот скрипт можно запустить той же командой bash:
Заключение
Вы можете заметить некоторое мерцание/шум на каждом стиле. Применение стиля к видео – сравнительно новая область разработки, в которой было сделано немало прекрасной, но дорогой в вычислительном смысле работы, чтобы передача между соседними фреймами была более гладкой.
Документация в репозитории StyleGAN научит вас, как обучать модели на собственных наборах данных и, таким образом, создавать собственные стили! Мне кажется, что коллекция комических книг позволила бы создать очень интересный стиль, который затем можно было бы применять к потоку видео.
Хотя уже есть программы, применяющие фильтры к потоку видео, вроде Photo Booth, передача стиля – это круто, поскольку модель, обученная глубокому пониманию и нюансам стиля, может применять его эффективно. Вы можете этого не заметить на потоке видео с низким разрешением, но на фотографиях с высоким разрешением вы увидите всю ее мощь:
Это было всего лишь одно из применений CycleGAN, и я рекомендую прочитать в Сети или в литературе о других замечательных возможностях, которыми она обладает.