Не откладывая в долгий ящик, продолжаем обсуждение процессов, сопутствующих работе с камерой на Raspberry Pi. И, как и было анонсировано и запланировано, в данной статье рассмотрим некоторые базовые практические примеры использования модуля High Quality Camera совместно с Raspberry Pi 4 Model B. Таким образом, если первый пост можно признать физически-электрически-механическим (ссылка), то сегодня будет программная часть. Начнем…
Для взаимодействия с камерой есть два основных варианта:
- Устаревший, но длительное время активно использовавшийся, стек raspicam.
- И стек с открытым исходным кодом libcamera, который активно развивается, продвигается и используется на сегодняшний день.
Оба варианта имеют в своем составе ряд приложений, которые можно использовать “из коробки” для осуществления тех или иных манипуляций с камерой. К примеру, среди наиболее часто используемых:
raspicam | libcamera | |
---|---|---|
Работа с видео | raspivid | libcamera-vid |
Захват изображений | raspistill | libcamera-still |
Как видите, все сделано схожим образом, во имя облегчения процессов перехода на новый стек. Мы будем пользоваться вариантом, который нам предлагается официально – а именно новым стеком libcamera и соответствующими утилитами, именно он по умолчанию активен в актуальных версиях операционных систем. Тем не менее при желании или необходимости существует простой и безболезненный способ включить поддержку старого стека Raspicam. Для этого запускаем raspi-config
:
sudo <code>raspi-config</code>
Переходим в раздел “Interface options”:
И активируем “Legacy camera support”:
Для чего это может быть нужно? Я вижу несколько вариантов. Во-первых, насколько я помню, Raspicam показывает лучшие результаты в плане производительности при использовании на более старых версиях плат (Raspberry Pi 2, Raspberry Pi 3). И второй нюанс, по-прежнему актуальный на данный момент. Для использования python, в частности picamera
, необходимо откатиться к стеку Raspicam, поскольку libcamera пока банально не поддерживает интеграцию данного вида. Как раз в следующей части/статье будем разбирать работу с камерой на python, там и поговорим более детально.
Давайте внесем дополнительную наглядность:
raspicam | libcamera | |
---|---|---|
Формат видео | raw h.264 | raw h.264, MJPEG |
Формат изображений | JPEG, JPEG + RAW, YUV420, RGB888, GIF, BMP, PNG | JPEG, JPEG + DNG (raw), YUV420, RGB888, BMP, PNG |
Баланс белого | auto, cloudy, flash, fluorescent, horizon, incandescent, off, sun, shade, tungsten | auto, cloudy, customisable, daylight, fluorescent, incandescent, indoor, off, tungsten |
Режим выдержки | antishake, auto, backlight, beach, fireworks, fixedfps, night, nightpreview, snow, sports, spotlight, verylong | customisable, fixed fps, long, normal, short |
Режим замера | average, backlit, matrix, spot | average, centre-weighted, customisable, spot |
Дополнительные режимы | burst/timelapse, circular buffer, demo, live preview on 3D models, segmented video, video with motion vectors | circular buffer, many features through flexible post-processing, motion detection, segmented video, timelapse |
И на этом моменте можно переходить к практической деятельности и к рассмотрению основных команд и утилит для работы с камерой. Для максимальной структуризации пойдем прямо по пунктам, по паре-тройке примеров на каждый вариант.
libcamera-hello.
Своего рода “Hello World”, как и следует из названия, для Raspberry Pi и камеры. Эту команду мы уже использовали для диагностики в прошлый раз. Цель функционирования libcamera-hello
заключается в том, чтобы отобразить поток с камеры в превью-окно на 5 секунд (плюс-минус погрешность в разумных пределах). Удобно для диагностики и тестирования, никаких параметров, запустил, посмотрел, сделал вывод, пошел дальше. Использование:
libcamera-hello
Кроме того, дефолтный интервал в 5 секунд можно отрегулировать следующим образом:
libcamera-hello -t 3000
После -t
указывается желаемое время работы в миллисекундах. То есть здесь мы имеем 3000 мс, что равно 3-м секундам. Для бесконечной работы указываем 0:
libcamera-hello -t 0
Теперь превьюшка не будет закрыта (а команда завершена) автоматически, только вручную. Кроме того, можно изменить текст, выводимый в заголовке окна. Как вариант:
libcamera-hello --info-text "my awesome text"
Результат не заставляет себя ждать:
И более того, есть вариант вывести в этом заголовке какую-либо характеристику:
libcamera-hello --info-text "%focus"
Само собой, проверяем:
Настройка заголовка окна таким способом возможна и для других команд. Полный список возможных аргументов, параметров и т. д. можно найти на официальной странице с официальным же описанием – ссылка. Тем временем двигаемся дальше.
libcamera-jpeg.
Здесь у нас новый персонаж – libcamera-jpeg
- приложение для захвата статичных изображений с камеры. Базовый вариант использования:
libcamera-jpeg -o my_image.jpg
В результате получим, что абсолютно логично, файл my_image.jpg с изображением с камеры. Можно задать размеры генерируемого файла:
libcamera-jpeg -o my_image.jpg --width 1280 --height 720
Опять же полный список параметров можно найти в официальном описании, либо задавайте вопросы в комментариях, всем помогу и подскажу, по мере возможности. А наша цель по-прежнему систематизированно пройтись по базовым примерам использования для основных приложений.
libcamera-still.
Данная команда является по сути расширенной версией libcamera-jpeg
. Изображение может быть захвачено полностью аналогично:
libcamera-still -o my_image.jpg
Но для libcamera-still
доступна большая гибкость в использовании и настройке. И, в первую очередь, нельзя не отметить возможность кодирования изображений не только в jpg, но также в png и bmp:
libcamera-still -e png -o my_image.png libcamera-still -e bmp -o my_image.bmp
Более того можно сделать дамп RGB или YUV пикселей без кодирования:
libcamera-still -e rgb -o my_image.data libcamera-still -e yuv420 -o my_image.data
Остановимся на еще одной опции и возможности, а именно на захвате raw-изображения, то есть сырых данных с сенсора камеры, без пост-обработки:
libcamera-still -r -o my_image.jpg
Данную возможность дарует нам ключ -r
, либо, что абсолютно идентично:
libcamera-still --raw -o my_image.jpg
libcamera-vid.
Моя любимая команда, ввиду того, что в 90% случаев мне требуется именно записать то или иное видео тем или иным способом. По умолчанию используется кодирование в H.264. Собственно, работу команды можно разбить на два этапа:
- отображение превью-окна с текущим потоком с камеры
- сохранение этого потока в видео-файл
libcamera-vid -t 5000 -o my_video.h264
Здесь у нас присутствуют:
-t 5000
– как и для других команд задает длительность функционирования, то есть в данном случае записи видео и отображения превью-o my_video.h264
– задает выходной файл, в который и будет сохранен видео-поток
Полученный файл доступен к просмотру, я, например, предпочитаю не vlc
проигрыватель, а mpv
, поэтому для просмотра:
mpv my_video.h264
При желании можно отключить окно предпросмотра (preview):
libcamera-vid --nopreview -t 5000 -o my_video.h264
Что тут еще можно выделить в качестве основных аргументов... Конечно же, параметры видео:
--width
– ширина--height
– высота--framerate
– fps
Получаем в итоге (для 1080p30):
libcamera-vid --width 1920 --height 1080 --framerate 30 -t 5000 -o my_video.h264
Таким образом мы задаем характеристики сохраняемого видео, отдельно можно регулировать размеры preview-окна при помощи ключа -p
, за которым последовательно следуют:
- координата x окна
- координата y окна
- ширина
- высота
Конечно же, пример, как без него:
libcamera-vid -p 0,0,640,480 -t 5000 -o my_video.h264
Размер превьюшки будет составлять 640*480 пикселей, и располагаться окно будет в левом верхнем углу экрана – координаты (0, 0). И, что касается libcamera-vid
, нельзя обойти стороной момент с сохранением временных меток кадров. То есть для каждого кадра можно зафиксировать и сохранить в файл временную метку, пример результирующего файла:
0.000 39.999 79.993 120.006 159.991 199.981 239.986 279.968 319.964 359.958 399.962 439.950 479.943 519.950 559.937 599.933 639.928 679.921 719.916 759.911 799.912 839.902 879.899 919.895 959.886 999.892
Данный файл я записал для частоты кадров 25 в секунду (--framerate 25
), соответственно, кадры следуют друг за другом с интервалом в 40 мс, что и обнаруживаем. Итак, для генерации файла данного вида используем:
libcamera-vid --nopreview --framerate 25 -t 5000 -o my_video.h264 --save-pts timestamp_values.txt
Зачем это нужно? Наиболее общий ответ на данный вопрос – для дальнейшего конвертирования, например в mkv:
mkvmerge -o my_video_converted.mkv --timecodes 0:timestamp_values.txt my_video.h264
В итоге из исходного my_video.h264 получаем my_video_converted.mkv, с этим все понятно. Резюмируем финальной командой вида:
libcamera-vid --width 1920 --height 1080 --framerate 25 -p 0,0,640,480 -t 5000 -o my_video.h264 \ --save-pts timestamp_values.txt; mkvmerge -o my_video_converted.mkv \ --timecodes 0:timestamp_values.txt my_video.h264
Здесь просто одним движением осуществляется все вышеобозначенное, никаких неожиданностей. И, несмотря на достаточное, казалось бы, время, уделенное libcamera-vid
, на этом нет возможности остановиться, поскольку есть полезнейший режим работы, о котором нельзя умолчать. Заключается этот режим в возможности сегментировать выходное видео, то есть разделить на куски определенной длительности. Смотрим пример, затем разберем:
libcamera-vid -t 25000 --segment 5000 --inline -o my_video_%02d.h264
Выполнив данную команду на выходе получим видео длительностью 25 секунд (-t 25000
), разбитое на сегменты/части по 5 секунд (--segment 5000
). То есть простыми словами получим 5 видео-файлов по 5 секунд каждый. Причем, указав в качестве имени файла my_video%02d.h264
, мы используем возможность задать разное имя для каждого из файлов. Наглядно смотрим на результат:
На этой ноте переходим к завершающей части статьи, в которой мы кратко обсудим еще одно приложение - libcamera-raw
.
libcamera-raw.
Название в данном случае максимально прозрачно намекает о функциональном назначении. Цель работы заключается в сохранении видео-потока в виде сырых данных прямиком с сенсора. Превью в данном случае недоступно:
libcamera-raw -t 5000 -o my_video.raw
Сырые кадры с сенсора камеры последовательно сохраняются в выходной файл. Поскольку размер файла в данном случае может быть достаточно велик, есть смысл аналогично предыдущему случаю сегментировать данные по нескольким файлам:
libcamera-raw -t 25000 --segment 5000 --inline -o my_video%02d.raw
Здесь все осуществляется полностью идентично, так что на сегодня на этом завершаем, до скорых встреч 🤝