Это исходный код и предварительно обученная модель для демонстрации веб-камеры pix2pix, которую я недавно опубликовал в Twitter и Vimeo. Он использует глубокое обучение или, если добавить несколько модных словечек: глубокий сверточный условный генеративный состязательный сетевой автокодировщик .
видео 1
видео 2
Код в этом конкретном репозитории на самом деле не имеет ничего общего с pix2pix, GAN или даже с глубоким обучением. Он просто загружает любую предварительно обученную модель тензорного потока (при условии, что она соответствует некоторым ограничениям), передает ей обработанные входные данные веб-камеры и отображает выходные данные модели. Так уж получилось, что я обучил и использовал модель pix2pix (подробности ниже).
Т.е. шаги можно резюмировать следующим образом:
Я собрал коллекции произведений искусства со всего мира из проекта Google Art Project на Викимедиа. Многие изображения представляют собой классические портреты богатых белых парней, поэтому я использовал всего около 150 коллекций, стараясь сохранить данные как можно более географически и культурно разнообразными (полный список, который я использовал, находится здесь). Но данные по-прежнему очень евроцентричны, поскольку из одного европейского музея могут быть сотни или тысячи сканов, а из арабского музея - только 8.
Я загрузил версии изображений размером 300 пикселей и запустил пакетную обработку:
Я также запустил пакетный процесс, чтобы несколько раз обрезать изображения (вместо неравномерного изменения размера), но я еще не тренировался в этом. Вместо хитрого обнаружения границ я также начал изучать гораздо лучшее «Целостное обнаружение вложенных краев» (также известное как HED) Се и Ту (как оно использовалось в оригинальной статье pix2pix), но еще не обучался этому.
Это делается с помощью сценария preprocess.py (извините, нет аргументов командной строки, отредактируйте сценарий, чтобы изменить пути и настройки, это должно быть совершенно очевидно).
Небольшой образец обучающих данных, включая прогнозы обученной модели, можно увидеть здесь. Самый правый столбец — это исходное изображение, крайний левый столбец — предварительно обработанная версия. Эти два изображения передаются в сеть pix2pix как «пара» для обучения. Средний столбец — это то, что модель учится производить , учитывая только самый левый столбец . (На изображениях показана каждая итерация обучения — т. е. число слева, которое варьируется от 20 000 до 58 000, поэтому оно постепенно становится лучше по мере продвижения вниз по странице).
Я также обучил безусловный GAN (т. е. обычный DCGAN на тех же данных обучения. Пример его выходных данных можно увидеть ниже. (Это генерирует «полностью случайные» изображения, напоминающие обучающие данные).
Обучение и архитектура аналогичны « Переводу изображений в изображения с помощью условных состязательных сетей » Исолы и др. (также известных как pix2pix). Я тренировался с портом tensorflow от @affinelayer (Кристофер Гессе), который также лежит в основе этой демоверсии «набросок для кошки», которая недавно стала вирусной. Он также написал хороший урок о том, как работает pix2pix. Бесконечная благодарность авторам (и всем, на кого они опирались) за то, что они сделали свой код открытым!
Я внес только одно бесконечно маленькое изменение в обучающий код tensorflow-pix2pix, а именно: добавил tf.Identity к входам и выходам генератора с удобочитаемым именем, чтобы я мог легко подавать и извлекать тензоры. Поэтому, если вы хотите использовать в этом приложении свои собственные модели, вам придется сделать то же самое . (Или запишите имена тензоров ввода/вывода и соответствующим образом измените json, подробнее об этом ниже).
Вы можете скачать мою предварительно обученную модель на вкладке «Релизы».
Что делает это конкретное приложение, так это загружает предварительно обученную модель, выполняет предварительную обработку данных с веб-камеры в реальном времени и передает их в модель. Я выполняю предварительную обработку с помощью старомодного базового компьютерного зрения, используя opencv. Это действительно очень минимально и просто. Вы можете увидеть графический интерфейс ниже (графический интерфейс использует pyqtgraph).
Разные сцены требуют разных настроек.
Например, для «живого действия» я нашел способ обеспечить лучшие (ИМХО) результаты, и это то, что я использовал в первом видео вверху. Пороги (canny_t1, canny_t2) зависят от сцены, количества деталей и желаемого вида.
Если на вашем изображении много шума, вы можете добавить немного pre_blur или pre_median . Или поиграйте с ними для достижения «художественного эффекта». Например, в первом видео, в районе 1:05–1:40, я добавляю массу медианы (значения около 30–50).
Для рисования сцен (например, второго видео) я обнаружил, что адаптивный порог дает более интересные результаты, чем canny (т. е. отключить canny и включить адаптивный порог), хотя вы можете с этим не согласиться.
Для полностью статических входных данных (т. е. если вы заморозите захват, отключив обновление камеры) выходные данные, скорее всего, будут очень незначительно мерцать, поскольку модель делает разные прогнозы для одного и того же входных данных — хотя обычно это довольно незаметно. Однако при прямой трансляции с камеры шум на входе может привести к сильному мерцанию на выходе, особенно из-за высокой восприимчивости к шуму в режиме Canny или адаптивного порога, поэтому некоторое временное размытие может помочь.
accum_w1 и accum_w2 предназначены для временного размытия входных данных перед переходом в модель: new_image = old_image * w1 + new_image * w2 (поэтому в идеале они должны составлять единицу или близко к ней).
Prediction.pre_time_lerp и post_time_lerp также выполняют временное сглаживание: new_image = old_image * xxx_lerp + new_image * (1 — xxx_lerp) pre_time_lerp — перед входом в модель, а post_time_lerp — после выхода из модели.
Ноль для любого временного размытия отключает их. Их значения зависят от вашего вкуса. Для обоих видео выше я установил все размытия pre_model (т.е. accum_w1, accum_w2 и pre_time_lerp) на ноль и играл с различными настройками post_time_lerp в диапазоне от 0,0 (очень мерцающий и мигающий) до 0,9 (очень медленный, тусклый и «мечтательный»). ). Обычно мой любимый диапазон — 0,5–0,8.
Если вы хотите использовать другую модель, вам необходимо настроить файл JSON, аналогичный приведенному ниже. Мотивация здесь в том, что у меня на самом деле есть куча JSON в папке приложения/модели, которую я могу динамически сканировать и перезагружать, а данные модели хранятся в другом месте на других дисках, а приложение может загружать и переключаться между моделями во время выполнения и масштабирования. входы/выходы и т. д. автоматически.
{
"name" : "gart_canny_256", # name of the model (for GUI)
"ckpt_path" : "./models/gart_canny_256", # path to saved model (meta + checkpoints). Loads latest if points to a folder, otherwise loads specific checkpoint
"input" : { # info for input tensor
"shape" : [256, 256, 3], # expected shape (height, width, channels) EXCLUDING batch (assumes additional axis==0 will contain batch)
"range" : [-1.0, 1.0], # expected range of values
"opname" : "generator/generator_inputs" # name of tensor (':0' is appended in code)
},
"output" : { # info for output tensor
"shape" : [256, 256, 3], # shape that is output (height, width, channels) EXCLUDING batch (assumes additional axis==0 will contain batch)
"range" : [-1.0, 1.0], # value range that is output
"opname" : "generator/generator_outputs" # name of tensor (':0' is appended in code)
}
}
Протестировано только на Ubuntu 16.04, но должно работать и на других платформах.
Я использую дистрибутив Python Anaconda, в котором есть почти все, что вам нужно, тогда это (надеюсь) так же просто:
Загрузите и установите анаконду с https://www.continuum.io/downloads.
Установите tensorflow https://www.tensorflow.org/install/ (что, если у вас есть anaconda, часто довольно просто, поскольку включено большинство зависимостей)
Установите opencv и pyqtgraph
установка conda -c menpo opencv3 установка conda pyqtgraph
Бесконечное спасибо еще раз