Старый фотик + bash = таймлапс

в 9:00, , рубрики: Canon, diy или сделай сам, ffmpeg, gphoto2, ruvds_статьи, Блог компании RUVDS.com, видеотехника, Разработка под Linux, таймлапс, Фототехника

Старый фотик + bash=таймлапс - 1


Думаю у многих из нас, в шкафу пылился старый зеркальный фотоаппарат, типа Canon EOS 400D. Он как чемодан без ручки: выбросить жалко, продать смысла нет, и использовать вряд ли будешь. Достал его так одним вечером, и подумал: вещь хорошая и вполне годная для всяких опытов. И сразу загорелся применить его во всяких своих самоделках. А что, весьма хорошо фотографирует из коробки, достаточно широкий спектр всяких регулировок, осталось только научиться с ним работать. Всего-то подружить его с компьютером, да Linux, и дело в шляпе! В результате у нас получается просто непаханое поле для фотографических экспериментов и применения в своих придумках. Давайте же поглядим, как это можно сделать и что получилось из таких экспериментов.

▍ Исходники

Как я уже сказал, у меня достаточно давно лежит в шкафу фотоаппарат Canon EOS 400D, для своего времени неплохой фотик для семейного фотоальбома, но с появлением хороших телефонов, практически не используется. Когда в очередной раз я его достал, то понял, что из него нужно сотворить что-то прикольное. Для того чтобы отвязать фотоаппарат от аккумулятора, и чтобы он работал «вечно», ему нужен источник питания от сети. Для этого пришлось приобрести адаптер ACK-DC20. Умышленно даю марку, потому что поиск для конкретной модели фотоаппарата оказался тем ещё квестом. Но оказалось, что можно вполне купить «здесь и сейчас», а не ждать с Китая. Всё это можно провернуть и с другими фотоаппаратами, только надо подобрать подходящий блок питания.
Также рекомендую обзавестись штативом, стоит более-менее вменяемый штатив недорого (мой стоил всего 1500 рублей в известном интернет-магазине), зато позволяет делать хорошие фото.
В качестве ЭВМ для работы с фотоаппаратом можно использовать подходящий одноплатник, лично я использовал какой-то древний портативный ноутбук, который зависает при открытии браузера, но вполне сносно справился с задачей снимать фотографии.

Старый фотик + bash=таймлапс - 2
Всё готово к экспериментам: фотоаппарат, источник питания, штатив и ЭВМ.

▍ Настройка ПО

На ноутбуке установлен Linux Mint 19, и я буду рассказывать об особенностях настройки именно этой системы. Всё, что далее будет описано, может подойти к Ubuntu. В качестве основного источника информации, я использовал статью "How to Use Your DSLR Camera as a Webcam in Linux". Мой фотоаппарат не умеет снимать видео, и в качестве вебкамеры выступать отказался, но в ней изложены основные нюансы настройки, которые я и применил.
Для начала поставим все необходимые пакеты.

sudo apt-get install gphoto2 v4l2loopback-utils v4l2loopback-dkms ffmpeg

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

В принципе, если вы хотите просто попробовать, работает ли у вас фотоаппарат, то можно модуль загрузить вручную.

sudo modprobe v4l2loopback exclusive_caps=1 max_buffers=2

Но после каждой перезагрузки, вспоминать, что надо загрузить модуль, мне было лень. Поэтому давайте это всё пропишем в системе/
Добавим в файл /etc/modules строку dslr-webcam:

$ sudo vi /etc/modules

  # /etc/modules: kernel modules to load at boot time.
  #
  # This file contains the names of kernel modules that should be loaded
  # at boot time, one per line. Lines beginning with "#" are ignored.

  dslr-webcam

Создадим новый файл /etc/modprobe.d/dslr-webcam.conf и запишем в него следующие строки:

alias dslr-webcam v4l2loopback
options v4l2loopback exclusive_caps=1 max_buffers=2

После всех проделанных манипуляций перезагружаемся. Подключаем камеру с помощью microUSB, и включаем её. В результате dmesg должно показать следующий выхлоп:

[474969.683623] usb 2-1.7.2: new full-speed USB device number 14 using ehci-pci
[474969.797751] usb 2-1.7.2: not running at top speed; connect to a high speed hub
[474969.820004] usb 2-1.7.2: New USB device found, idVendor=04a9, idProduct=3110
[474969.820008] usb 2-1.7.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[474969.820009] usb 2-1.7.2: Product: Canon Digital Camera
[474969.820011] usb 2-1.7.2: Manufacturer: Canon Inc.

Проверяем, что камера успешно определилась:

gphoto2 --auto-detect
Модель                   Порт                                                  
----------------------------------------------------------
Canon EOS 400D (PTP mode)      usb:002,014    

Радостно пытаемся сделать фото:

gphoto2 --capture-image-and-download

И вероятнее всего у вас на этом моменте (или ещё на этапе подключения камеры) вылезет окошко системы и спросит, что делать с фотографиями на камере. А в консоли выпадет следующая или аналогичная ошибка:

gphoto2 --capture-image-and-download
                                                                               
*** Ошибка ***              
An error occurred in the io-library ('Could not claim the USB device'): Could not claim interface 0 (Устройство или ресурс занято). Make sure no other program (gvfs-gphoto2-volume-monitor) or kernel module (such as sdc2xx, stv680, spca50x) is using the device and you have read/write access to the device.
ОШИБКА: Невозможно сделать снимок.
ОШИБКА: Невозможно сделать снимок.
*** Ошибка (-53: «Could not claim the USB device») ***       

Для получения отладочных сообщений воспользуйтесь параметром --debug.
Отладочные сообщения могут помочь найти решение вашей проблемы.
Если вы хотите какие-либо сообщения gphoto, список рассылки авторов
программы <gphoto-devel@lists.sourceforge.net>, то запускайте
gphoto2 со следующими параметрами:

    env LANG=C gphoto2 --debug --debug-logfile=my-logfile.txt --capture-image-and-download

Проверьте, что аргументы надёжно экранированы.

Честно говоря долго не мог понять, что с этим делать. У меня она прекрасно воспроизводилась на двух разных машинах с разными версиями linux mint, и заключалась она в том, что в системе работает демон gvfsd-metadata, который следит за тем, что подключается медиаустройство. И он после этого уже запускает собственные клиенты работы с фотоаппаратом. Это можно увидеть следующей командой:

ps ax | grep photo
16478 ?        Sl     0:00 /usr/lib/gvfs/gvfs-gphoto2-volume-monitor
21405 ?        Sl     0:00 /usr/lib/gvfs/gvfsd-gphoto2 --spawner :1.31 /org/gtk/gvfs/exec_spaw/7

Первое, что нужно сделать — это поубивать эти процессы. После этого, либо грубо выкорчевать из системы демона gvfsd-metadata:

systemctl --user mask gvfs-metadata.service

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

systemctl --user unmask gvfs-metadata.service

Если вы хотите разово отключить сервис, то выполните:

systemctl --user stop gvfs-metadata.service

После этого всё это должно корректно заработать.

gphoto2 --capture-image-and-download
Новый файл находится в фотоаппарате в /capt0000.jpg                            
Файл сохраняется с именем capt0000.jpg
Удаляется файл /capt0000.jpg в фотоаппарате

Могу сказать сразу, что в разных системах этот демон может быть разным (у меня он отличается), и именно это может мешать корректно делать снимки.
На ноуте у меня всё корректно работало только под root, и пришлось все скрипты запускать только под sudo. Под обычным пользователем работало через раз, linux way, да-да. Так и не победил.

Скажу сразу, что на этом проблемы не заканчиваются, часто бывает, что возникает внутренняя ошибка фотоаппарата, которая решается только жёсткой перезагрузкой, со съёмкой аккумулятора. Например:

*** Ошибка ***              
Canon EOS Capture failed (0x02ff: PTP I/O Error)
ОШИБКА: Невозможно сделать снимок.
ОШИБКА: Невозможно сделать снимок.

Притом на фотоаппарате висит Busy, и он ни на что не реагирует. Как её победить, я так и не понял.

Из дополнительных опций, хорошо управлять всем этим добром удалённо. Скрипты запускать в tmux, а папку с фотографиями монтировать по ssh. И для этих целей ноутбук оказался очень идеальным решением, потому что на нём есть wifi, и всю настройку и контроль делал удалённо. Папку с фотографиями монтировал следующей командой:

sudo sshfs -o allow_other,default_permissions user@ip:/home/user/canon ~/canon

▍ Настройки фотоаппарата

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

Старый фотик + bash=таймлапс - 3
Убираем опцию «Автоотключение».

Следующая настройка — не такая очевидная. Для видео не требуется такого хорошего качества, даже самое низкое качество съёмки будет давать Full HD (1920x1080 точек). Поэтому снижаем качество съёмки.

Старый фотик + bash=таймлапс - 4
Ставим самое «плохое» качество съёмки.

В результате будет кадр 1936х1288 пикселов, что тоже очень даже хорошо. Причина уменьшения качества съёмки банальна — это скорость передачи через USB. Если поставить больше, фотоаппарат просто не будет успевать передать полученную фотографию. Это тоже было выяснено эмпирическим путём.

▍ Немного программирования на bash

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

sudo apt install libgphoto2-dev
sudo pip3 install -v gphoto2

Но библиотека пайтона gphoto2 упорно не хотела вставать на мою систему, убив минут 40, в попытке разрулить ситуацию с установкой модуля, принял решение писать на баше. Мы люди не гордые, сделаем на том, что работает. Да, и код на python, даже в примере был слишком монструозен, чем моя реализация на bash. Тем более что в нашем блоге есть шикарная серия статей по программированию на bash.
В результате мозгового штурма (я тот ещё «программист» на bash), родился следующий код.

#!/bin/bash
END=600
SLEEPTIME=10
for i in `seq -w 0 $END`
do
  gphoto2 --capture-image-and-download --filename  "$i.jpg"
  sleep $SLEEPTIME
done

Где переменная END — это суммарное количество снимков, которое сделает фотоаппарат. SLEEPTIME — время между снимками. Опытным путём установлено, что время менее 10 секунд может приводить к ошибкам, особенно если снимать в ночное время в автоматическом режиме (когда выбирается автоматом время экспозиции).
Количество кадров, равное 2880 взято тоже не с потолка. Прикинул, что если сводить 24 кадра в секунду, сделать минутный ролик, то это получится 1440 кадров. Это как раз съёмка в течение 4-х часов, каждые 10 секунд. Если снимать 8 часов, то как раз значение будет больше. Но, увы, 8 часов мне снять так и не удалось, фотоаппарат зависал.
Полученные кадры необходимо свести в видео, чтобы можно было смотреть. Для этого воспользуемся ffmpeg.

ffmpeg -framerate 24 -i %04d.jpg -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p output.mp4

Не буду детально разбирать данную команду, обращу внимания на два момента:

  • framerate 24 — это количество кадров в секунду, я выбрал 24, и мне кажется этого маловато. Можно выбрать 60, и будет абсолютная гладкость.
  • %04d.jpg тип входящего файла, число после нуля будет показывать сколько чисел в имени файла (оно будет у вас разное, подбирайте под конкретную задачу).

Если хочется потом наложить аудиодорожку на видео, то можно воспользоваться следующей командой:

ffmpeg -i output.mp4 -i audio.wav -map 0:v -map 1:a -c:v copy -shortest output_audio.mp4

Где соответственно:

  • output.mp4 — входной видеофайл
  • audio.wav — входной аудиофайл (любой формат)
  • output_audio.mp4 — выходной видеофайл

Выходной файл получится длинной, того файла кто короче по воспроизведению видео или аудио (опция -shortest).

▍ Даёшь съёмку и результаты!

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

Первый опыт был просто в комнате, самое сложное было — это не включать свет, и не мелькать в окне, чтобы не было бликов на фотоаппарате. Но вроде всё получилось.

Старый фотик + bash=таймлапс - 5
В процессе фотосъёмки.

Могу честно признаться, я тот ещё фотограф. Снимал просто в режиме «без вспышки», поэтому баланс белого, выдержка, ISO, диафрагма выбиралось автоматически каждый раз. Каждый кадр сделан с интервалом в 5 секунд. От этого получилась такая «ламповость», но, как по мне, для первого раза потрясающий результат:

Больше мы не выдержали, потому что сидеть впотьмах (свет включать нельзя) и «не дышать» (не ходить, чтобы не было бликов) просто невозможно, и съёмку было решено прервать, тут не спасли даже хорошие дружеские разговоры.

«Дефекты плёнки» на видео — это пролетающие птицы. Есть много вопросов к видео: мерцание, неестественные цвета и т.п. Есть куда расти и работать, но даже с этого можно отталкиваться.
Думаю, что если не полениться и настроить нормально фотоаппарат, и поставить на ночь, можно снять очень крутые перемигивания окнами.

Следующую съёмку было решено проводить на балконе, чтобы заснять рассвет.

Старый фотик + bash=таймлапс - 6
Съёмочный стенд.

Но тут я совершил несколько роковых ошибок: не настроил фотоаппарат, пока было светло, при этом съёмку вёл в полностью мануальном режиме. В результате все фото получились размытыми. Другая ошибка чуть не стоила мне фотоаппарата: я забыл про Солнце. И фотоаппарат был направлен прямо точно по траектории нашего светила. Пока мы спали, фотоаппарат чудом не расплавился — его спасла дымка и то, что утром солнечные лучи не такие горячие. Поэтому, когда снимаете такие таймлапсы, обязательно помните про главное наше светило!

Поскольку восход не вышел, принято было волевое решение перед отъездом снять закат, и вот он уже получился. Дождался, когда солнечный диск уйдёт из объектива камеры (примерно 2 часа дня), и запустил съёмку. На первых кадрах ещё видны солнечные засветы линзы. Лично меня результат просто потряс, при совершенно незначительных трудозатратах.

Потрясающе: треки от самолётов, огни домов, закат, прямо-таки виден пульс засыпающего города. Мне после этого захотелось по всему городу расставить таких камер и снимать, снимать, снимать.

▍ Выводы

Не претендую, что открыл Америку, современные фотоаппараты умеют делать такое прямо из коробки, без всяких скриптов. Но, найти применение старой хорошей вещи — почему бы и нет? Например, можно поставить камеру во время какого-то действия, и сделать вот такой таймлапс. Кроме таймлапсов, можно использовать камеру, например, в фотоловушках. В общем, идей море, главное — успевать их реализовывать! Gphoto2 позволяют полностью управлять фотоаппаратом: балансом белого, выставлять диафрагму и т.д., что даёт просто неограниченные возможности. Главный плюс — это возможность вести удалённую фотосъёмку.

Выражаю благодарность своему другу Алексею, который двое выходных терпел меня, мои эксперименты, помогал и советовал, как лучше всё сделать.

▍ Полезные ссылки

Автор: Сергей

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js