Щелевая съёмка: реализация на bash (ffmpeg + imagemagick)

    Не помню что и почему я искал в интернете несколько дней назад, но я наткнулся на интересную статью с необычными фотографиями. А позже на еще одну статью, где описывалась реализация алгоритма создания таких фотографий на python. После прочтения меня заинтересовала эта тема и я решил провести вечера майских праздников с пользой для себя, а именно реализовать алгоритм «конвертирования» видео в щелевое фото. Правда, не на питоне, но подручными средствами на bash'е. Но обо всем по порядку.

    Что такое щелевое фото

    Вид фотографии, на которой запечатлено не одно событие в один конкретный момент времени, а несколько событий. Это достигается за счет того, что щелевая камера снимает кадры шириной в один пиксель (это и есть «щель») и «склеивает» их в одно фото. Немного запутанно звучит и пока сложно представить, что это такое и как выглядит. Самым доходчивым объяснением для меня был комментарий к одной из вышеупомянутых статей от пользователя Stdit:
    image
    После этого все становится понятным.

    Пример для наглядности:
    image

    Алгоритм построения щелевой фотографии

    1. Разложить видео на множество изображений.
    2. Обрезать каждое полученное изображение по ширине в один пиксель с заданным смещением (щелью).
    3. Собрать полученное множество изображений в одно.

    Звучит нестрашно и просто.

    Дано

    • Камера 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 и «скормил» его скрипту. Вот что из этого вышло:


    На следующий день с собой на прогулку я взял свою Xiaomi Yi и снял несколько видео. Вот что из этого вышло:

    Родное Азовское море (фото сделано из видео разрешением в 1920x1080 пикселей и продолжительностью в 31 секунду, 60к/с)




    А эти фото собраны из видео разрешением в 1280x720 пикселей и продолжительностью в 16 секунд, 120к/с. Обратите внимание на фон второго фото. Он не статичен. На фоне было движущееся колесо обозрения.

    Посмотреть и скачать скрипт можно в моем репозитории на GitHub. Предложения, критика и пулреквесты только приветствуются.
    Поделиться публикацией
    Комментарии 56
      +1
      Классно! А-ля футурисчическая живопись. Запилите плагин в Gimp.
        +2
        GIMP — это ведь редактор изображений. А в статье речь о том, что фото получается из видео файла. Или Вы о том, чтобы гимпу давать пачку фото на обработку? Но эту пачку фото сначала из видео нужно достать. Получается не очень автоматизированный процесс и в плагине к гимпу не так много смысла в данном случае.
          0
          gif вам чем не угодил в данном случае?
            0
            Например, тем, что он абсолютно не подходит для полноцветных изображений?
              –2
              А требуется полноцветность? Статья о том как делать фото из видеофайла. В интернетах довольно давно начали фрагменты видеофайлов хранить в gif, не обращая внимания на размеры и ухудшение качества. На представленных примерах я полноцветность как-то и не замечаю. Всё выглядит вполне ок с этим форматом.
                –1
                То есть сначала конвертировать видео в gif, а потом плагином сделать фото. Смысл в этом промежуточном шаге? Плагин ради плагина.
                  –1
                  Зачем конвертировать видео в gif, если оно уже есть в gif? Нарезанных фрагментов из видео мне больше встречается в gif, чем в mpg, несмотря на новую практику конвертировать всё обратно.
                    –1
                    У Вас камера/телефон видео в gif снимает?) Смысл не в том, чтобы из каких-то гифок в интернете делать фото. А в том, чтобы из своих видео делать фото.
                      –2
                      А из своих обязательно?
                        –1
                        У Вас есть фотоаппарат? Зачем? Вам свои фото обязательно? Скачайте в интернете, там много.
                          –2
                          Я так обычно и делаю
                            –1
                            Если вас интересуют ответы и на первых 3 вопроса, то они такие: Есть. Без него подходящие мне телефоны не делают. Зависит от ситуации.
                              0
                              Клинический случай…
                                –2
                                Случай чего?
                                  0
                                  Случай человеческой тупости. Тут обсуждается технический приём для получения фотографий. Как правило, люди делают фото сами, а не ищут их в интернете. Вы же оказались уникумом. Сначала проявили псевдозаинтересованность в теме (то есть в создании подобных фотографий). А потом диалог скатился к вашему «я и так качаю картинки в интернете». Тогда какой смысл пробовать делать щелевую фотографию из скачанных чужих гифок или видео? качайте сразу готовые из интернета и не пишите тут чушь. Фотография — это творчество. Если Вам интересно качать чужое, а своё Вы делать не умеете — зачем включаться в разговор и выносить людям мозг тупыми вопросами? Фото своих детей, родителей, животных, и т.п., например, тоже будете искать и качать в интернете?
                                    0
                                    Я увидел здесь приём создания забавных картинок из других движущихся картинок. Тут же пришла в голову мысль взять тоже какое-нибудь море, парк и т.п. и посмотреть что из него выйдет. Я должен брать видеокамеру и нестись на море или в парк? Не думаю что это логичный вариант. Значит стоит задуматься о том, где взять подходящее видео. Самый простой вариант — нагуглить в интернетах. И тут есть вариант взять длинное видео и отрезать из него кусок, либо взять готовый отрезанный кусок. Готовый отрезанный кусок видео с нужным моментом — это и есть гифка, очень популярная в интернете вещь. Ну да, качество у неё обычно похуже оригинала, но оно мне не очень критично в данной ситуации.
                                    Последний ваш вопрос, конечно, более логичен чем первый, но и в этом случае вынужден ответить «да». После какого-нибудь веселья с друзьями я обычно ищу в каком-нибудь вконтактике фотки и понравившиеся забираю себе.Сейчас камера в каждом утюге и лично моя не всегда даёт лучшую картинку, а тем более интересную лично мне.
                                  –2
                                  Вы могли вставить в пост собственную иллюстрацию, но предпочли взять картинку из комментария пользователя Stdit. Для чего вам в компьютере графический редактор?
                                    0
                                    Прочитайте внимательно. Я сказал, что это лучшее объяснение, которое я встречал. Поэтому я ссылаюсь на автора этой иллюстрации. То есть я не претендую на авторство. Как Вам ещё объяснить?
                                      0
                                      Именно по этой причине я и предпочитаю в таких ситуациях фотографии из интернета, а не свои. Они лучше, либо их получить проще. Я нисколько не требовал от вас авторства, возможно стоило написать чуть иначе.
              0
              Вот так вот…
              +1
              Вы эту еще пропустили https://habrahabr.ru/post/282265/
                0
                Еще нашел: https://habrahabr.ru/post/208820/
                +1
                А есть ли какое-то практическое применение этому?
                  +1
                  Есть. Например, делать фото очень длинных движущихся объектов. Как описано в этой статье https://habrahabr.ru/post/282265/
                    0
                    я думаю можно попробовать в художественной съёмке что то придумать с этим
                  • НЛО прилетело и опубликовало эту надпись здесь
                      +1
                      Не работал до этого ни с одной ни с другой. Выбрал ту, что более популярна, как мне показалось. По крайней мере о ImageMagick я слышал больше, чем о GM
                      • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          Чего?))) Вы даете сссылку на страницу где черным по белому написаны преимущества форка Имеджика:

                          GM is more efficient so it gets the job done faster using fewer resources.
                          GM is much smaller and lighter (3-5X smaller installation footprint).
                          • НЛО прилетело и опубликовало эту надпись здесь
                      –12
                      Круто конечно, на на opencv + python эта задача бы решилась в пару строчек.
                        +26
                        И ваш комментарий был бы действительно крутым, если бы содержал эту пару строчек.
                          +1
                          Под рукой только плюсы оказались, но в python почти также, только доступ к строкам матрицы (numpy) явно по диапазону:

                          cv::VideoCapture capture(«horse.mp4»);
                          cv::Mat frame;
                          std::vector vector;

                          while (capture.read(frame)) {
                          cv::transpose(frame,frame);
                          unsigned char *bytes = &frame.data[frame.cols*frame.rows/2*frame.channels()];
                          vector.insert(vector.end(), bytes, bytes+frame.cols*frame.channels());
                          }
                          cv::Mat output = cv::Mat(vector.size()/frame.cols/frame.channels(),frame.cols, frame.type(), (unsigned char*)vector.data());
                          cv::transpose(output,output);

                          cv::imshow(«output», output);
                          cv::waitKey(1);
                            +3
                            Разве получилось проще чем у ТС?
                              +1
                              не сложнее, во всяком случае, а время заняла — не два дня, а 20 минут.
                                +3
                                Не два дня, а два вечера выходных. Если бы я был знаком с ffmpeg и imagemagick получше, то, думаю, за пару часов бы и написал. К чему Вы это все говорите? «Мое конг-фу лучше твоего»?
                                  +2
                                  Ну вообще, да. Я считаю это решение элегантней вашего. Я показал альтернативу интересующимся и высказал свое мнение, не нужно на меня нападать.
                        +2
                        По-моему фотофиниш делается на этом же принципе.
                        0
                        Спасибо за статью! Даже в голову не приходило, что так можно получать по-настоящему футуристические изображения, когда в картинке зашифрована динамика сюжета.
                          0
                          test
                            +6
                            0 failed
                            1 success
                            Test passed
                              0
                              Хабр такой хабр. Кто-то не поленился и слил человеку карму за слово «test».
                                +1
                                Странно. Попробовал поднять карму, но «Нельзя голосовать за пользователей, у которых нет размещённых публикаций». То есть если нет публикаций, то сливать можно, но поднимать нет?
                                  0
                                  «Нет радости более светлой, чем пожар в доме соседа»…

                                  А уж если есть возможность ещё и бензинчика плеснуть —…
                                    0
                                    Уже очень давно
                                    0
                                    Скорее интересно, почему хабр внезапно стал давать возможность комменирования аккаунтам в статусе read-only? (как мой, например)
                                      0
                                      Я тоже в read-only и что?))
                                      Добавлено: хммм, старнно, был в read-only по крайней мере…
                                        0
                                        Вопрос в том, что мой всегда был read-only, и этот статус никогда не менялся :) и сейчас не изменился. Думаю, что комментарий от alexws54tk таки верен.
                                        Про пред.комментарий писало, что он должен пройти модерацию. Когда написал этот — даже этого не было.
                                        +1
                                        Скорее для привлечения к диалогам, конструктивным и не очень, «свежую кровь».
                                        В одной из прошлых публикаций о нововведениях в обсуждениях народ просил подобное. Видать созрели.
                                  +1
                                  Глядя на первую картинку-объяснение появилась идея — поменять местами оси (x на t или y на t). Т.е. первый кадр — собранная картинка из первого ряда(строки) пикселей, второй кадр — из второго ряда(строки).
                                  Понятно, что нужно брать достаточно короткие видеофрагменты (1280/1920 кадров), что-бы картинка вписывалась в формат кадра. И на выходе получить опять видео (в стиле Сальвадора Дали?).
                                    0
                                    Забавная идея. Получится необычный «шум» на таком видео
                                      0
                                      Будет эффект rolling shutter, если я Вас правильно понял. Я делал такую штуку, прикольно выходит, особенно если снимать видео slow motion.
                                      Видео внутри

                                        0
                                        Кстати, на связке ffmpeg и imagemagick тоже вполне можно такой эффект сделать.
                                      0
                                      Мне кажется, у некоторых финальных изображений можно поменять пропорции — лучше смотрелось бы. Понятно, что идела не добиться, если скорость движения объектов в кадре разная, но где-то можно улучшить, сжав или растянув изображение.
                                        +1
                                        Люблю щелевую съёмку, делал реализацию на ObjC, чтобы можно было с телефона сразу такие фотки делать. =)

                                        Но предполагал, что на ffmpeg + imagemagick будет проще.

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

                                        Самое читаемое