Создание сверхдлинных плоских панорамных изображений из видео

aaaf1f556f37433fbf45896fdb8dff6e.jpg

Предыстория


Пару лет назад на Хабре была статья, посвящённая Адаму Мадьяру Камера Эйнштейна: как один фотограф изображает время. Мне она показалась очень интересной, но, если честно, то я так и не понял технологию для съёмки видео Stainless. Особенно меня восхитили его фотографии поезда метро. После чего я задался мыслью:, а могу ли я сам создать нечто подобное?

Постановка задачи


Недалеко от села, где живут мои родственники, проходит железная дорога и поехав однажды в гости, я прихватил с собой камеру и штатив. Суть задачи, которую я поставил перед собой сводилась к тому чтобы создать панорамное изображение поезда, достаточно длинное, чтобы его невозможно было снять просто собрав плоскую панораму. То есть, я собрался отснять видео и вырезав по центральной полоске с каждого кадра объединить их в надежде получить очень длинную и красивую панораму. Поскольку я являлся счастливым обладателем камеры Canon EOS 600D (технические характеристики) с максимальной частотой 60 FPS при разрешении видео 1280×720, то расчитывать на более высокую частоту не приходилось. С другой стороны панорама высотой 1280 пикселей превосходит вертикальное разрешение большинства мониторов. Поэтому, я полагал, качество результата должно меня устроить.

Примеры в сети Интернет


Прежде чем продолжить я хотел бы привести список ссылок на работы по данной тематике, которые мне удалось обнаружить.

Съёмка! Мотор! Поехали!


Итак, я установил штатив на расстоянии порядка 10 метров от рельсов (чем ближе к рельсам, тем сильнее тряска камеры) и установил камеру в вертикальном положении. Поскольку нам из всего видео кадра нужна лишь средняя полоска, то правильнее всего устанавливать камеру именно в вертикальном, а не горизонтальном положении, так как в этом случае разрешение панорамы будет выше. Например, при горизонтальная ориентация 1920×1080 даст нам панораму высотой 1080 пикселей, а вертикальная ориентация 1080×1920 даст нам панораму высотой 1920 пикселей.
dd484b686db24e258eab1b45892c186b.jpg
Съёмку видео лучше всего вести в ручном режиме, т. е. без участия автоматики. Когда объект попадает в кадр, то может сильно измениться освещенность сцены, что заставит камеру поменять выдержку или диафрагму, а это делать нежелательно. Иначе разные части, например, поезда могут быть различными по яркости. Частота кадров для выбранного разрешения естественно должна быть максимальной. Съёмку начинаем секунд за 5–10 до того момента как объект попадёт в кадр. Во-первых, на всякий случай, во-вторых, камера перестала шевелиться после нажатия на кнопку записи, и в-третьих чтобы можно было выбрать фоновый кадр (если освещение быстро меняется, например из-за облаков). Заканчиваем съёмку тоже не сразу, а спустя секунд 5. На своём личном опыте я убедился, что при съёмке желательно просчитать будет ли входить объект в кадр полностью и не будет ли лишнего пустого пространства. У меня на нескольких панорамах верхняя часть поездов немного обрезана. Ну и конечно, желательно выставить ручной фокус и заранее сфокусироваться на объекте (хоть это и трудно бывает сделать, ведь самого объекта пока ещё нет).

Программная часть


Мною была написана программа Trainz Pano (C++ Builder XE3). Приложение 64-разрядное, ОС — Windows 7/8/10. Она заточена именно на создании панорам из видео. Программа доступна как коммерческий продукт и легко гуглится.

Работа с приложением


Чтобы облегчить жизнь и себе и пользователям я разбил процесс создания панорамы на две части: собственно сборку и редактирование. Сделано это по причине того, что большой объём данных лучше сохранить на промежуточном этапе, чтобы их не потерять. Именно по этой причине приложение является 64-битным.

Открытие видео

092cfa2faf16447cb507a185486b2be8.jpg
Я не стал заморачиваться с декодированием видео самостоятельно, моё приложение использует FFMPEG и сначала получает из видео набор изображений, а потом уже с ними работает.

Настройка параметров фона

4d61aed52bcc4ba78202f22bc81915b0.jpg
На самом первом изображении Вы можете видеть повторяющийся узор в качестве фона. Связано это с тем, что из каждого кадра вырезается полоска шириной порядка нескольких десятков пикселей. Собственно они и повторяются, если не перекрываются объектом. Чтобы избавиться от такого фона и заменить его на монотонные линии в приложении есть возможность автоматизировать этот процесс. К сожалению, результат меня иногда немного разочаровывает, поэтому для получения качественного результата после процесса сборки можно перейти к ретушированию.Итак, настраиваем параметры фона.

Сборка панорамы


При съёмке видео камера, по отношению к объекту может быть расположена не прямо, а под некоторым углом. Кроме того, камера может быть расположена под углом к траектории движения объекта. Чтобы компенсировать их влияние в приложении имеются два элемента управления: Вращение и Перспектива. Они определяются путём подбора таким образом, чтобы получаемое изображение не имело зазубрин при стыковке отдельных участков. Ещё один параметр — это Ширина. Он нужен для указания ширины полосок, которые будут вырезаться из текущего кадра и добавляться в результирующую панораму. Все три параметра можно менять в процессе сборки панорамы. Однако чаще всего Вращение и Перспектива настраиваются на начальном этапе и в дальнейшем не меняются. А вот параметр Ширина может меняться, так как скорость движения объекта может быть непостоянной. В моём случае я много раз сталкивался с ускорением и замедлением движения поездов.
78ce747759e647e3ba31fa1157c5ae3c.jpg
Если мы снимаем видео в вертикальной ориентации, то нам понадобится указать в главном меню угол поворота кратный 90 градусам. Есть ещё один момент, который следует учитывать. Когда я писал программу, то исходил из того, что движение объекта осуществляется справа-налево. Что делать, если в действительности движение объекта осуществляется слева-направо? Для этого можно на этапе сборки использовать пункт отразить слева-направо, при этом все надписи мы получим в зеркальном отражении. А на этапе ретуширования воспользуемся командой Отражение панорамы слева-направо и всё встанет на свои места.

Ретуширование панорамы

0dc539b983b14edc940aaf44a266f818.jpg
Чтобы избавиться от повторяющегося фона (если программа не смогла сделать это сама) или восстановить изображение объекта, если он был неверно определён как фон загружаем наше изображение (точнее слои изображения, там их 3) в программу Trainz Pano Editor. Вот краткий список функций, который предоставляет программа:

  • Ретуширование
  • Добавление столбов
  • Удаление столбцов
  • Вертикальная заливка фоном
  • Добавление строк
  • Удаление строк
  • Горизонтальная заливка фоном
  • Градиентный переход
  • Ускоренное движение

Видео работы с программой


On-line справка находится здесь.

Просмотр панорам


При сохранении панорам выявилась одна неприятная деталь, а именно — формат JPEG имеет ограничение на размеры изображения. Для длины и ширины используются 2 байта, поэтому записать панораму длиной более 65535 пикселей не удастся. В то же время у меня были панорамы длиной по 200 000 пикселей и более. Сохранение в BMP и PNG проблем не создаёт, вот только изображения в этих форматах занимают много места на диске. При попытке открыть для просмотра большие панорамы тоже возникли некоторые проблемы. XnView и XnViewMP показывают месиво из пикселей, о чём я написал автору программы, надеюсь в ближайших версиях этот баг пофиксят. Встроенный просмотровщик Windows Фотографии открыл на ура, не подкачал и InfanView. В общем следует исходить из того, что не все вьюверы покажут нам длинные панорамы корректно.

Примеры моих работ


Ознакомиться с некоторыми примерами моих работ можно на сайте. Правда, там они значительно уменьшены в размерах.
4f066e9e23e8477e8970999586f7f5c4.jpg

Возможная область применения


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

Планы по улучшению приложения


  • Чтение кадров напрямую в приложение без необходимости промежуточного сохранения изображений на диск.
  • Улучшить скорость сборки панорам.
  • Написать новый алгоритм определения фона.
  • Написать JavaScript библиотеку с использованием HTML5 Canvas для отображения очень длинных панорам.

Выводы


  • В настоящее время на рынке нет приложений для создания панорамных изображений из видео файлов.
  • Те единичные примеры панорам, что доступны в сети, как правило, созданы с использованием домашних заготовок, не являющихся готовыми коммерческими продуктами.
  • Программа Trainz Pano в какой то мере решает озвученную выше задачу.
  • К сожалению, в программе Trainz Pano пока что реализована недостаточно качественная технология отделения объектов от фона, что (в общем случае) приводит к необходимости ретуширования панорамы в довольно большом объеме.
  • Вместе с тем, при грамотном использовании (выборе удачного места съёмки против монотонного фона) программа вполне может быть использована как профессионалами так и любителями цифрового фото.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

© Habrahabr.ru