Не помню что и почему я искал в интернете несколько дней назад, но я наткнулся на интересную статью с необычными фотографиями. А позже на еще одну статью, где описывалась реализация алгоритма создания таких фотографий на python. После прочтения меня заинтересовала эта тема и я решил провести вечера майских праздников с пользой для себя, а именно реализовать алгоритм «конвертирования» видео в щелевое фото. Правда, не на питоне, но подручными средствами на bash'е. Но обо всем по порядку.
Вид фотографии, на которой запечатлено не одно событие в один конкретный момент времени, а несколько событий. Это достигается за счет того, что щелевая камера снимает кадры шириной в один пиксель (это и есть «щель») и «склеивает» их в одно фото. Немного запутанно звучит и пока сложно представить, что это такое и как выглядит. Самым доходчивым объяснением для меня был комментарий к одной из вышеупомянутых статей от пользователя Stdit:
![image](https://habrastorage.org/r/w1560/getpro/habr/post_images/c20/9d6/830/c209d6830fc48aab73f300655a9ba462.png)
После этого все становится понятным.
Пример для наглядности:
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/c67/4b8/1e5/c674b81e5f4d35a08e78a12761f75525.jpg)
Звучит нестрашно и просто.
Первое и самое простое, что приходит на ум, это написать bash скрипт, который будет обрабатывать видео и фото в соответствии с описанными шагами алгоритма. Для реализации задуманного мне понадобился ffmpeg и imagemagick. В упрощенном виде на псевдо bash скрипт выглядит так:
За пару вечеров был написан скрипт, которому на вход подаем видео файл, а на выходе получаем фотографию. В теории на вход можно подавать видео в любом формате, который поддерживает ffmpeg. Выходной файл можно получить в тех форматах, которые поддерживает imagemagick.
Пользоваться скриптом очень просто:
где input — видео файл для обработки, output — название результирующего файла, slit-shift — смещение щели по горизонтали.
Первым делом для быстрого тестирования я не стал снимать видео на камеру, а скачал первое попавшееся видео с youtube и «скормил» его скрипту. Вот что из этого вышло:
![](https://habrastorage.org/r/w780q1/files/fbc/be6/1bf/fbcbe61bfabc44368c634b9c8d62d4af.jpg)
На следующий день с собой на прогулку я взял свою Xiaomi Yi и снял несколько видео. Вот что из этого вышло:
![](https://habrastorage.org/r/w780q1/files/db9/43d/a3b/db943da3bf614bb38a2e8c43dda3a937.jpg)
Родное Азовское море (фото сделано из видео разрешением в 1920x1080 пикселей и продолжительностью в 31 секунду, 60к/с)
![](https://habrastorage.org/r/w780q1/files/40f/a97/da9/40fa97da9a0a463bbe6a394cca5fd50c.jpg)
![](https://habrastorage.org/r/w780q1/files/a73/092/122/a7309212214648b4aaed18bf92a1527a.jpg)
А эти фото собраны из видео разрешением в 1280x720 пикселей и продолжительностью в 16 секунд, 120к/с. Обратите внимание на фон второго фото. Он не статичен. На фоне было движущееся колесо обозрения.
Посмотреть и скачать скрипт можно в моем репозитории на GitHub. Предложения, критика и пулреквесты только приветствуются.
Что такое щелевое фото
Вид фотографии, на которой запечатлено не одно событие в один конкретный момент времени, а несколько событий. Это достигается за счет того, что щелевая камера снимает кадры шириной в один пиксель (это и есть «щель») и «склеивает» их в одно фото. Немного запутанно звучит и пока сложно представить, что это такое и как выглядит. Самым доходчивым объяснением для меня был комментарий к одной из вышеупомянутых статей от пользователя Stdit:
![image](https://habrastorage.org/getpro/habr/post_images/c20/9d6/830/c209d6830fc48aab73f300655a9ba462.png)
После этого все становится понятным.
Пример для наглядности:
![image](https://habrastorage.org/getpro/habr/post_images/c67/4b8/1e5/c674b81e5f4d35a08e78a12761f75525.jpg)
Алгоритм построения щелевой фотографии
- Разложить видео на множество изображений.
- Обрезать каждое полученное изображение по ширине в один пиксель с заданным смещением (щелью).
- Собрать полученное множество изображений в одно.
Звучит нестрашно и просто.
Дано
- Камера Xiaomi Yi
- Желание разобраться и сделать несколько необычных фото
- Пару вечеров свободного времени
Решение
Первое и самое простое, что приходит на ум, это написать bash скрипт, который будет обрабатывать видео и фото в соответствии с описанными шагами алгоритма. Для реализации задуманного мне понадобился ffmpeg и imagemagick. В упрощенном виде на псевдо bash скрипт выглядит так:
ffmpeg -i videoFile frame-%d.png
for ((i = 1; i <= framesCount; i++));
do
convert -crop 1xframeHeight+slitShift+0 frame-$i.png slit-$i.png
done
montage slit-%d.png[1-framesCount] -tile framesCountx1 -geometry +0+0 outputImage
Разберемся что здесь происходит
- Во-первых, с помощью утилиты ffmpeg разбиваем видео на множество изображений вида frame-0.png...frame-n.png.
- Во-вторых, с помощью утилиты convert из пакета imagemagick обрезаем каждое полученное изображение (ключ -crop) следующим образом: ширина == 1px, высота == высоте изображения. Так же указываем смещение щели по горизонтали. Сохраняем в файлы вида slit-0.png...slit-n.png.
- В-третьих, с помощью утилиты montage из пакета imagemagick собираем полученные изображения в одно фото. Ключ -tile указывает на то, что все фото нужно собрать в одно по шаблону «framesCount по горизонтали и 1 по вертикали», то есть собрать множество изображений в один ряд.
Результат
За пару вечеров был написан скрипт, которому на вход подаем видео файл, а на выходе получаем фотографию. В теории на вход можно подавать видео в любом формате, который поддерживает ffmpeg. Выходной файл можно получить в тех форматах, которые поддерживает imagemagick.
Пользоваться скриптом очень просто:
./slitcamera.sh --input=test.avi --output=test.png --slit-shift=100
где input — видео файл для обработки, output — название результирующего файла, slit-shift — смещение щели по горизонтали.
Первым делом для быстрого тестирования я не стал снимать видео на камеру, а скачал первое попавшееся видео с youtube и «скормил» его скрипту. Вот что из этого вышло:
![](https://habrastorage.org/files/fbc/be6/1bf/fbcbe61bfabc44368c634b9c8d62d4af.jpg)
На следующий день с собой на прогулку я взял свою Xiaomi Yi и снял несколько видео. Вот что из этого вышло:
![](https://habrastorage.org/files/db9/43d/a3b/db943da3bf614bb38a2e8c43dda3a937.jpg)
Родное Азовское море (фото сделано из видео разрешением в 1920x1080 пикселей и продолжительностью в 31 секунду, 60к/с)
![](https://habrastorage.org/files/40f/a97/da9/40fa97da9a0a463bbe6a394cca5fd50c.jpg)
![](https://habrastorage.org/files/a73/092/122/a7309212214648b4aaed18bf92a1527a.jpg)
А эти фото собраны из видео разрешением в 1280x720 пикселей и продолжительностью в 16 секунд, 120к/с. Обратите внимание на фон второго фото. Он не статичен. На фоне было движущееся колесо обозрения.
Посмотреть и скачать скрипт можно в моем репозитории на GitHub. Предложения, критика и пулреквесты только приветствуются.