На Хабре у меня уже было две статьи (1 и 2), обе они касались реализации быстрого сжатия изображений по алгоритму JPEG на CUDA. Теперь я бы хотел рассказать о другой, гораздо более масштабной задаче — как мы сделали конвертер и видео плеер для серий DNG изображений на CUDA. При этом мы получили очень высокую скорость работы, потому что вся обработка исходных данных в формате DNG теперь выполняется на видеокарте NVIDIA.
Исходное изображение в формате DNG взято с сайта blackmagicdesign.com
Несмотря на то, что в мире уже есть очень большое количество конвертеров RAW, которые работают с форматом DNG, мы решили сделать ещё один, но очень быстрый, который можно было бы использовать в том числе для отбраковки и сортировки. Видео плееры DNG тоже есть, но обычно они работают с уменьшенным разрешением, поэтому просмотреть только что отснятый в формате DNG материал на полном разрешении — это проблема. С помощью нашего конвертера мы сделали попытку обработать картинки настолько быстро, чтобы уметь просматривать серии DNG изображений в реальном времени и при полном разрешении. Естественно, что кроме скорости необходимо было получить приемлемое качество обработки и шумоподавления, и мне кажется, что нам это удалось.
На всякий случай напомню, что DNG — это предложенный компанией Adobe открытый формат RAW данных, снятых на видеокамеру или фотоаппарат. Мы будем рассматривать случай с видео, хотя для фотографий задача почти та же самая.
Условие задачи: на достаточно быстром SSD лежит серия изображений в формате DNG (все кадры сжаты) с разрешением до 4К или 4.6К (например, как у последних моделей видеокамер URSA или URSA mini от компании BlackMagic Design) и нужно в реальном времени их прочитать, декодировать, сделать всю необходимую обработку и плавно вывести видео на монитор с заданной частотой в диапазоне 24-30 кадров в секунду на полном разрешении (без использования proxies, т.е. уменьшенных копий).
Мы довольно давно занимаемся разработкой алгоритмов и программного обеспечения для обработки изображений и видео на CUDA, поэтому в нашем распоряжении был собственный быстрый SDK, в котором мы реализовали весь необходимый функционал для работы с RAW данными от видеокамер. В итоге вся схема обработки изображений в настоящее время выглядит примерно следующим образом:
1. Многопоточное чтение DNG файлов с SSD
2. Парсинг DNG файлов, получение тайлов
3. Многопоточное декодирование DNG изображений
4. Пересылка декодированных изображений в видеокарту
5. Кроп для DNG
6. Линеаризация исходных данных, приведение их к 16 битам
7. Применение уровней белого и чёрного
8. Баланс белого
9. Экспокоррекция
10. Шумодав до дебайера
11. Дебайер (демозаик)
12. Шумодав после дебайера
13. Цветовые преобразования, температура и тинт
14. Кривые и уровни в RGB
15. Кривые и уровни в HSV
16. Кроп и ресайз (для заданного зума)
17. Резкость
18. Наложение профиля монитора и гаммы
19. Преобразование данных к 8 битам на канал
20. Копирование данных из памяти CUDA в текстуру OpenGL с последующим выводом на монитор после получения V-Sync
21. Вычисление и вывод на монитор гистограмм и парадов для каждого кадра
Как видно из описания, внутренний формат представления данных — 16 бит на канал. Это не так плохо, как может показаться на первый взгляд. Все участки кода, где очень важна точность, считаются во float (шумодав, ресайз, шарп), а финальный результат обработки каждой стадии сохраняется в 16 битах. Многие дебайеры представляют из себя целочисленные алгоритмы, поэтому для них 16 бит в самый раз, но некоторые стадии всё равно приходится делать во float. Также иногда мы объединяем соседние стадии обработки, например, баланс белого и экспокоррекцию, что уменьшает количество промежуточных округлений. Мы визуально сравнивали результаты с 32-битной реализацией и существенной разницы не обнаружили. Нам кажется, что это вызвано относительно небольшим количеством промежуточных стадий обработки в нашем софте.
Несколько слов хотелось бы сказать и о дебайерах, т. е. об алгоритмах демозаики. Очень часто в конвертерах для уменьшения времени вычислений используют билинейный алгоритм или его аналоги, ведь это один из самых быстрых вариантов. Действительно, на CPU это так, но если посмотреть на качество восстановленной картинки с точки зрения пикового отношения сигнал-шум (PSNR), то для стандартного набора изображений Кодака, используемого для тестирования дебайеров, у билинейного алгоритма получается менее 31 дБ. Алгоритмы дебайеров HQLI и DFPD из нашей программы дают 36 дБ и 39 дБ на этом же наборе кадров. Поскольку производительность дебайера на GPU во много раз выше, чем на CPU, то нет необходимости в билинейном дебайере и можно использовать более качественные алгоритмы. Когда мы делали кодек JPEG на видеокарте, мы измеряли PSNR в зависимости от коэффициента качества для разных дебайеров и получили интересный результат: низкий PSNR финальной картинки определяется именно билинейным дебайером, а не артефактами джипега при качестве не менее 75%. Резюме простое: если требуется качество, то билинейный дебайер лучше не использовать. Понятно, что метрика PSNR (как SSIM и остальные) достаточно условна, но это объективный критерий, который работает в большинстве случаев, хоть и не всегда.
Мы в ближайшее время должны завершить разработку нового алгоритма дебайера для GPU, который даёт PSNR 40.7 дБ на наборе Кодака. Версия на CPU уже готова и тестовое приложение с командной строкой лежит в открытом доступе. С его помощью можно протестировать все наши алгоритмы дебайеров и сравнить их.
Новый алгоритм дебайера называется MG (multiple gradients), он сделан нами, в других RAW конвертерах его нет.
Реализация такой общей схемы обработки для 10/12/14-битных исходных данных в формате DNG в реальном времени с частотой кадров в диапазоне 24-30 к/с для разрешений от 2К до 4К, требует тщательной оптимизации каждого алгоритма. При этом необходимо добиться максимально возможной скорости работы SSD, CPU и GPU. Если производительность одного из этих трёх компонент железа будет недостаточной, то реального времени не получится. Для разрешений 4К-4.6К мы достигли скорости обработки быстрее реального времени при использовании видеокарт NVIDIA GeForce GTX 980 и 1080.
На хорошем железе наш плеер DNG работает плавно, изображение можно масштабировать на весь экран. Аппаратный ресайз в OpenGL отключен, потому что в нём по умолчанию стоит билинейный алгоритм ресайза, который даёт значительные артефакты, особенно при уменьшении. Для решения этой проблемы мы всегда делаем ресайз на CUDA по алгоритму Ланцоша и передаём в OpenGL уже готовую картинку, размеры которой совпадают с размером окна. При этом мы получаем дополнительную задержку по времени, но качество картинки улучшается.
Изображение в формате DNG взято с этого сайта, оператор Джо Броули, тестовые снимки BlackMagic Ursa Mini 4.6K.
Для сохранения результатов в произвольный контейнер, можно использовать внешний FFmpeg, который пользователь должен установить самостоятельно, и его можно запустить из нашей программы с заданной командной строкой. Таким образом, например, с помощью внешнего FFmpeg можно сжать выходные данные в 10-битный 444 ProRes и сохранить их в контейнер MOV. Без помощи FFmpeg программа сама может сохранять обработанные кадры в виде серии 16-битных изображений в формате TIFF или 8/12-битных JPEG, а цветовой профиль встраивается в заголовок каждого кадра.
Таким же образом можно обрабатывать и фотографии. Но поскольку в фото есть очень много разных закрытых форматов, то для полноценной работы нужно будет подключить libraw, а пока есть только варианты с предварительной конвертацией исходных данных в DNG с помощью Adobe DNG Converter. Наша программа изначально не была ориентирована на фото, поэтому многих важных фич не хватает. В нашем SDK, на базе которого сделан софт, часть нужного функционала уже реализована, так что, возможно, быстрый конвертер для фото мы тоже сделаем. В этом случае пакетная обработка фотографий должна получиться очень быстрой, ведь и в джипег мы сжимаем на видеокарте. На хорошей карточке время обработки одной 50-МПикс картинки получается меньше, чем время загрузки изображения с SSD. Но для работы с такими большими файлами нужен GPU с памятью не менее 8 ГБайт.
Приведенная выше схема обработки изображений не является достаточно полной, так как пока отсутствует модуль подавления хроматических аберраций, ещё нельзя подключить 3D LUT, межкадровый шумодав не готов, монтажный кодек пока внешний, да много чего ещё не хватает. Всё это скоро будет сделано. Однако уже сейчас хорошо видно, что реализация всей схемы обработки серий DNG изображений на CUDA возможна даже на одной видеокарте, причём в реальном времени и при максимальном разрешении.
Мы знаем о существовании Adobe Premiere Pro 2015, BlackMagic DaVinci Resolve 12 и о многих других универсальных профессиональных решениях из этой области, в том числе и на видеокартах. Нашей задачей было не создание конкурента программам для файл-менеджмента, нелинейного монтажа, грейдинга и компрессии с помощью монтажных кодеков — в этих областях существующие решения и так неплохо справляются с имеющимися задачами, хотя и тут есть простор для ускорения и улучшения. Мы сделали решение для очень быстрой и достаточно качественной обработки данных на видеокарте и пользователи могут оценить, что у нас получилось.
Хотел бы отметить важный момент: в нашем подходе речь не идёт об ускорении на GPU отдельных алгоритмов при обработке изображений, как это часто бывает во многих приложениях. В нашей программе вся обработка серий DNG изображений выполняется на видеокарте, а это и есть принципиальное отличие от всех известных нам решений в данной области. С нашей точки зрения это оптимальный подход для повышения скорости работы и интересная возможность для улучшения качества в реалтайм приложениях.
Чтобы пользователь мог получить информацию о времени выполнения каждой стадии общей схемы обработки изображений, мы сделали специальный модуль, который измеряет и показывает время работы на видеокарте каждого алгоритма для данного изображения. Если активировать модуль Benchmarks, на экран будут выведены основные данные об используемой памяти, параметрах изображения и список задействованных алгоритмов обработки вместе с временем их выполнения.
Для решения задачи быстрого предварительного просмотра DNG серий мы сделали отдельный режим работы. Эту фичу очень просили те пользователи, которые занимаются отбраковкой и сортировкой материалов в формате DNG. Теперь можно из Проводника через контекстное меню запустить программу и в плеере просмотреть видео из серии DNG изображений, лежащих в данной папке.
Перспективным вариантом для развития этого направления является создание плагинов к Adobe Premiere Pro и After Effects. В этом случае можно будет совместить нашу скорость и качество обработки с возможностью сохранения результатов с помощью разнообразных монтажных кодеков без использования FFmpeg. Такие плагины можно будет использовать и вместо монтажного кодека, чтобы в реальном времени делать из DNG готовые обработанные кадры с разрешением 16 бит на канал и передавать их напрямую в After Effects, тогда стадия декодирования из ProRes не потребуется.
Мы также работаем над ещё одним интересным аспектом этого проекта — делаем быстрый кодек JPEG2000 на видеокарте, чтобы использовать его в качестве монтажного кодека. Такой кодек сможет работать с 16-битными данными в реальном времени, что обеспечит более высокое качество по сравнению с другими монтажными кодеками. Даже сжатие 10/12-битных данных может быть сделано с лучшим качеством, чем это делается сейчас. Такой кодек JPEG2000 сможет работать в реальном времени и даст более высокое качество по сравнению с широко используемыми ProRes, DNxHD, DNxHR. В настоящее время такой кодек JPEG2000 на CPU уже есть в составе Adobe Premiere Pro, но он очень медленный, поэтому в практическом плане от него пользы мало. Быстрый кодек JPEG2000 всё кардинально изменит и позволит улучшить качество промежуточных материалов для последующего монтажа.
Мы продолжаем работу над улучшением качества обработки изображений, и в ближайшее время ожидается релиз нового дебайера MG, который должен быть не хуже, чем у Adobe Camera Raw (с нашей точки зрения дебайер из ACR очень хорош). А наш дебайер DFPD в текущем релизе явно лучше, чем у Adobe Premiere Pro 2015. В нашей бесплатной версии есть шумодавы до дебайера и после дебайера, но этого нет в бесплатной версии DaVinci Resolve, а у Premiere Pro собственного шумодава в реальном времени нет даже в платной версии. У каждой программы есть свои плюсы и минусы, так что сравнивать можно много и долго, но в итоге всё равно каждый находит для себя инструмент, отвечающий собственным потребностям и задачам.
Бесплатную демо-версию программы для Windows-7/8/10 (64 бит) можно загрузить отсюда, а тестовую серию CinemaDNG изображений можно взять здесь. Также программа может работать с видео от Canon 5D Mark III с альтернативной прошивкой Magic Latern после конвертации MLV в DNG.
Буду признателен за замечания по качеству и скорости представленного решения. Ещё раз хочу напомнить, что программа работает только с видеокартами NVIDIA, причём для работы с 4К изображениями формата DNG желательно иметь не менее 2 ГБайт памяти на GPU. К сожалению, на видеокартах AMD и Intel программа работать не будет. И если почти вся память видеокарты NVIDIA занята другими приложениями, то тоже увы. Для достижения высокой скорости обработки нужны быстрые SSD, CPU и GPU.
Автор: fyodorser