Не помню что и почему я искал в интернете несколько дней назад, но я наткнулся на интересную статью с необычными фотографиями. А позже на еще одну статью, где описывалась реализация алгоритма создания таких фотографий на 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. HeaTTheatR
    08.05.2016 01:34
    +1

    Классно! А-ля футурисчическая живопись. Запилите плагин в Gimp.


    1. FluffyMan
      08.05.2016 02:02
      +2

      GIMP — это ведь редактор изображений. А в статье речь о том, что фото получается из видео файла. Или Вы о том, чтобы гимпу давать пачку фото на обработку? Но эту пачку фото сначала из видео нужно достать. Получается не очень автоматизированный процесс и в плагине к гимпу не так много смысла в данном случае.


      1. Denai
        09.05.2016 13:14

        gif вам чем не угодил в данном случае?


        1. ZimM
          09.05.2016 23:53

          Например, тем, что он абсолютно не подходит для полноцветных изображений?


          1. Denai
            10.05.2016 09:22
            -2

            А требуется полноцветность? Статья о том как делать фото из видеофайла. В интернетах довольно давно начали фрагменты видеофайлов хранить в gif, не обращая внимания на размеры и ухудшение качества. На представленных примерах я полноцветность как-то и не замечаю. Всё выглядит вполне ок с этим форматом.


            1. FluffyMan
              10.05.2016 09:58
              -1

              То есть сначала конвертировать видео в gif, а потом плагином сделать фото. Смысл в этом промежуточном шаге? Плагин ради плагина.


              1. Denai
                10.05.2016 10:04
                -1

                Зачем конвертировать видео в gif, если оно уже есть в gif? Нарезанных фрагментов из видео мне больше встречается в gif, чем в mpg, несмотря на новую практику конвертировать всё обратно.


                1. FluffyMan
                  10.05.2016 11:14
                  -1

                  У Вас камера/телефон видео в gif снимает?) Смысл не в том, чтобы из каких-то гифок в интернете делать фото. А в том, чтобы из своих видео делать фото.


                  1. Denai
                    10.05.2016 11:19
                    -2

                    А из своих обязательно?


                    1. FluffyMan
                      10.05.2016 11:22
                      -1

                      У Вас есть фотоаппарат? Зачем? Вам свои фото обязательно? Скачайте в интернете, там много.


                      1. Denai
                        10.05.2016 11:38
                        -2

                        Я так обычно и делаю


                        1. Denai
                          10.05.2016 11:42
                          -1

                          Если вас интересуют ответы и на первых 3 вопроса, то они такие: Есть. Без него подходящие мне телефоны не делают. Зависит от ситуации.


                        1. Itachi261092
                          10.05.2016 12:01

                          Клинический случай…


                          1. Denai
                            10.05.2016 12:12
                            -2

                            Случай чего?


                            1. Itachi261092
                              10.05.2016 12:34

                              Случай человеческой тупости. Тут обсуждается технический приём для получения фотографий. Как правило, люди делают фото сами, а не ищут их в интернете. Вы же оказались уникумом. Сначала проявили псевдозаинтересованность в теме (то есть в создании подобных фотографий). А потом диалог скатился к вашему «я и так качаю картинки в интернете». Тогда какой смысл пробовать делать щелевую фотографию из скачанных чужих гифок или видео? качайте сразу готовые из интернета и не пишите тут чушь. Фотография — это творчество. Если Вам интересно качать чужое, а своё Вы делать не умеете — зачем включаться в разговор и выносить людям мозг тупыми вопросами? Фото своих детей, родителей, животных, и т.п., например, тоже будете искать и качать в интернете?


                              1. Denai
                                10.05.2016 12:47

                                Я увидел здесь приём создания забавных картинок из других движущихся картинок. Тут же пришла в голову мысль взять тоже какое-нибудь море, парк и т.п. и посмотреть что из него выйдет. Я должен брать видеокамеру и нестись на море или в парк? Не думаю что это логичный вариант. Значит стоит задуматься о том, где взять подходящее видео. Самый простой вариант — нагуглить в интернетах. И тут есть вариант взять длинное видео и отрезать из него кусок, либо взять готовый отрезанный кусок. Готовый отрезанный кусок видео с нужным моментом — это и есть гифка, очень популярная в интернете вещь. Ну да, качество у неё обычно похуже оригинала, но оно мне не очень критично в данной ситуации.
                                Последний ваш вопрос, конечно, более логичен чем первый, но и в этом случае вынужден ответить «да». После какого-нибудь веселья с друзьями я обычно ищу в каком-нибудь вконтактике фотки и понравившиеся забираю себе.Сейчас камера в каждом утюге и лично моя не всегда даёт лучшую картинку, а тем более интересную лично мне.


                          1. Denai
                            10.05.2016 12:17
                            -2

                            Вы могли вставить в пост собственную иллюстрацию, но предпочли взять картинку из комментария пользователя Stdit. Для чего вам в компьютере графический редактор?


                            1. FluffyMan
                              10.05.2016 12:35

                              Прочитайте внимательно. Я сказал, что это лучшее объяснение, которое я встречал. Поэтому я ссылаюсь на автора этой иллюстрации. То есть я не претендую на авторство. Как Вам ещё объяснить?


                              1. Denai
                                10.05.2016 13:01

                                Именно по этой причине я и предпочитаю в таких ситуациях фотографии из интернета, а не свои. Они лучше, либо их получить проще. Я нисколько не требовал от вас авторства, возможно стоило написать чуть иначе.


    1. greathun
      09.05.2016 11:32

      Вот так вот…


  1. Alexufo
    08.05.2016 02:07
    +1

    Вы эту еще пропустили https://habrahabr.ru/post/282265/


    1. FluffyMan
      08.05.2016 02:40

      Еще нашел: https://habrahabr.ru/post/208820/


  1. igorch96
    08.05.2016 08:59
    +1

    А есть ли какое-то практическое применение этому?


    1. FluffyMan
      08.05.2016 09:00
      +1

      Есть. Например, делать фото очень длинных движущихся объектов. Как описано в этой статье https://habrahabr.ru/post/282265/


    1. Itachi261092
      10.05.2016 12:02

      я думаю можно попробовать в художественной съёмке что то придумать с этим


  1. scrutari
    08.05.2016 09:54
    +1

    Если не секрет, почему ImageMagic, а не GraphicsMagic?


    1. FluffyMan
      08.05.2016 10:04
      +1

      Не работал до этого ни с одной ни с другой. Выбрал ту, что более популярна, как мне показалось. По крайней мере о ImageMagick я слышал больше, чем о GM


      1. scrutari
        08.05.2016 14:43

        Разница по большому счету в лицензии.


        1. Alexufo
          09.05.2016 02:36

          Чего?))) Вы даете сссылку на страницу где черным по белому написаны преимущества форка Имеджика:

          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).


          1. scrutari
            09.05.2016 09:53
            +4

            И все-таки разница в основном в лицензии :) IM еще может стать быстрее ии меньше, но свободнее уже нет :)


  1. darkAlert
    08.05.2016 16:47
    -12

    Круто конечно, на на opencv + python эта задача бы решилась в пару строчек.


    1. AllexIn
      08.05.2016 18:42
      +26

      И ваш комментарий был бы действительно крутым, если бы содержал эту пару строчек.


      1. darkAlert
        09.05.2016 04:04
        +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);


        1. AllexIn
          09.05.2016 08:46
          +3

          Разве получилось проще чем у ТС?


          1. darkAlert
            09.05.2016 22:03
            +1

            не сложнее, во всяком случае, а время заняла — не два дня, а 20 минут.


            1. FluffyMan
              09.05.2016 22:49
              +3

              Не два дня, а два вечера выходных. Если бы я был знаком с ffmpeg и imagemagick получше, то, думаю, за пару часов бы и написал. К чему Вы это все говорите? «Мое конг-фу лучше твоего»?


              1. darkAlert
                09.05.2016 23:05
                +2

                Ну вообще, да. Я считаю это решение элегантней вашего. Я показал альтернативу интересующимся и высказал свое мнение, не нужно на меня нападать.


  1. MichaelBorisov
    08.05.2016 17:15
    +2

    По-моему фотофиниш делается на этом же принципе.


    1. FluffyMan
      08.05.2016 19:18
      +1

      Именно


  1. Alex_Maz
    08.05.2016 20:52

    Спасибо за статью! Даже в голову не приходило, что так можно получать по-настоящему футуристические изображения, когда в картинке зашифрована динамика сюжета.


  1. DumkinDV
    08.05.2016 21:48

    test


    1. FluffyMan
      08.05.2016 21:49
      +6

      0 failed
      1 success
      Test passed


      1. Ununtrium
        09.05.2016 11:48

        Хабр такой хабр. Кто-то не поленился и слил человеку карму за слово «test».


        1. FluffyMan
          09.05.2016 12:00
          +1

          Странно. Попробовал поднять карму, но «Нельзя голосовать за пользователей, у которых нет размещённых публикаций». То есть если нет публикаций, то сливать можно, но поднимать нет?


          1. sav1812
            09.05.2016 17:57

            «Нет радости более светлой, чем пожар в доме соседа»…

            А уж если есть возможность ещё и бензинчика плеснуть —…


          1. WST
            10.05.2016 09:31

            Уже очень давно


        1. Crystal_HMR
          09.05.2016 18:38

          Скорее интересно, почему хабр внезапно стал давать возможность комменирования аккаунтам в статусе read-only? (как мой, например)


          1. jeka1202
            10.05.2016 07:58

            Я тоже в read-only и что?))
            Добавлено: хммм, старнно, был в read-only по крайней мере…


            1. Crystal_HMR
              11.05.2016 19:21

              Вопрос в том, что мой всегда был read-only, и этот статус никогда не менялся :) и сейчас не изменился. Думаю, что комментарий от alexws54tk таки верен.
              Про пред.комментарий писало, что он должен пройти модерацию. Когда написал этот — даже этого не было.


          1. alexws54tk
            10.05.2016 09:57
            +1

            Скорее для привлечения к диалогам, конструктивным и не очень, «свежую кровь».
            В одной из прошлых публикаций о нововведениях в обсуждениях народ просил подобное. Видать созрели.


  1. roach1967
    08.05.2016 21:52
    +1

    Глядя на первую картинку-объяснение появилась идея — поменять местами оси (x на t или y на t). Т.е. первый кадр — собранная картинка из первого ряда(строки) пикселей, второй кадр — из второго ряда(строки).
    Понятно, что нужно брать достаточно короткие видеофрагменты (1280/1920 кадров), что-бы картинка вписывалась в формат кадра. И на выходе получить опять видео (в стиле Сальвадора Дали?).


    1. FluffyMan
      08.05.2016 21:56

      Забавная идея. Получится необычный «шум» на таком видео


    1. silvansky
      11.05.2016 12:07

      Будет эффект rolling shutter, если я Вас правильно понял. Я делал такую штуку, прикольно выходит, особенно если снимать видео slow motion.

      Видео внутри


      1. silvansky
        11.05.2016 12:17

        Кстати, на связке ffmpeg и imagemagick тоже вполне можно такой эффект сделать.


  1. dm9
    09.05.2016 10:52

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


  1. silvansky
    11.05.2016 12:08
    +1

    Люблю щелевую съёмку, делал реализацию на ObjC, чтобы можно было с телефона сразу такие фотки делать. =)

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