Top.Mail.Ru

Работа с камерой на Raspberry Pi посредством стека libcamera.

Не откладывая в долгий ящик, продолжаем обсуждение процессов, сопутствующих работе с камерой на 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”:

raspi-config

И активируем “Legacy camera support”:

Raspicam stack
Настройки камеры Raspberry Pi

Для чего это может быть нужно? Я вижу несколько вариантов. Во-первых, насколько я помню, 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

И более того, есть вариант вывести в этом заголовке какую-либо характеристику:

libcamera-hello --info-text "%focus"

Само собой, проверяем:

libcamera-hello заголовок окна

Настройка заголовка окна таким способом возможна и для других команд. Полный список возможных аргументов, параметров и т. д. можно найти на официальной странице с официальным же описанием – ссылка. Тем временем двигаемся дальше.

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-vid

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

libcamera-raw.

Название в данном случае максимально прозрачно намекает о функциональном назначении. Цель работы заключается в сохранении видео-потока в виде сырых данных прямиком с сенсора. Превью в данном случае недоступно:

libcamera-raw -t 5000 -o my_video.raw

Сырые кадры с сенсора камеры последовательно сохраняются в выходной файл. Поскольку размер файла в данном случае может быть достаточно велик, есть смысл аналогично предыдущему случаю сегментировать данные по нескольким файлам:

libcamera-raw -t 25000 --segment 5000 --inline -o my_video%02d.raw

Здесь все осуществляется полностью идентично, так что на сегодня на этом завершаем, до скорых встреч 🤝

Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x