e-con Systems e-CAM20_CURB — это 2,3-мегапиксельная цветная камера с глобальным затвором и фиксированным фокусом, разработанная для Raspberry Pi 4, и компания прислала нам образец для оценки и обзора. Мы начнем с предоставления спецификаций, прежде чем проверять содержимое упаковки, подключать камеру к Raspberry Pi 4 с помощью крепления LEGO DIY, показывать, как получить доступ к ресурсам для камеры, и пробовать инструменты, предоставляемые в ОС Raspberry Pi или Yocto Linux.
Технические характеристики e-CAM20_CURB
Камера состоит из двух плат со следующими характеристиками:
- eCAM217_CUMI0234_MOD цветная камера Full HD с 4-полосным интерфейсом MIPI CSI-2
- ON Semiconductor AR0234CS CMOS с оптическим форм-фактором 1/2,6″
- Глобальный затвор
- Встроенный датчик ISPimage от ON Semiconductor
- Потоковая передача UYVY без сжатия
- HD (1280 x 720) до 120 кадров в секунду
- Full HD (1920 x 1080) до 65 кадров в секунду
- 2,3 МП (1920 x 1200) до 60 кадров в секунду
- Вход внешнего аппаратного триггера
- Плата адаптера ACC-XVRNX-MIPICAMERA с 15-контактным разъемом FFC для подключения к Raspberry Pi
- Размеры — 30 х 30 мм (высота зависит от объектива и регулировки фокусного расстояния)
- Температурный диапазон – от -30°C до 70°C
- Соответствие — FCC и RoHS
Компания предоставляет 32-битные образы Yocto и Raspbian/Raspberry Pi OS с драйвером камеры V4L2 Linux и инструментами Gstreamer.
Распаковка камеры e-CAM20_CURB
Сначала мы подумали, что получили не ту посылку, поскольку вместо нее нам прислали камеру See3CAM USB 3.0.
Но не беспокойтесь, e-con Systems просто использовала стандартную упаковку с наклейкой «e-CAM20_CURB_H01R1», подтверждающую, что нам прислали правильную модель камеры.
Мы найдем камеру в антистатическом пакете и 15-сантиметровый кабель FPC для подключения к Raspberry Pi. Мы также найдем красную бумагу, прикрепленную к верхней части, с номером SO (заказ на продажу), который нам понадобится для доступа к документации и образам ОС.
Объектив защищен крышкой, которую мы сняли для того, чтобы сделать фотографию, представленную ниже.
Подключение Raspberry Pi и крепление LEGO своими руками
Подключение очень простое, и единственное, с чем вам нужно быть осторожным, — это ориентация кабеля FPC. Осторожно вытащив черный пластиковый зажим из разъемов на Raspberry Pi и камере e-CAM20_CURB, вам нужно будет вставить кабель таким образом, чтобы синяя сторона кабеля была обращена к черному пластиковому зажиму. Когда закончите, верните пластиковый зажим на место.
Другими словами, синяя (непроводящая) сторона кабеля будет обращена к порту Ethernet платы Raspberry Pi, а проводящая сторона (с текстом) будет обращена к порту HDMI.
Поскольку камера была бы слишком низкой, если бы она была размещена на столе, и держать камеру было бы неудобно для тестирования, нам пришлось соорудить решение для монтажа своими руками. Получается, что расстояние между проставками на камере идеально подходит для коннекторов LEGO, поэтому легко создать собственное крепление, и камера прочно крепится к своему основанию. Например, если мы поднимем камеру, как показано выше, набор LEGO соберется вместе.
Мы также должны были найти несколько красочных предметов с большим количеством LEGO и мусоровозом…
Доступ к документации e-CAM20_CURB, ОС Raspberry Pi и изображениям Yocto.
Все ресурсы для начала работы с камерой доступны на веб-сайте разработчика. Сначала вам нужно зарегистрироваться и войти в систему, используя свой адрес электронной почты.
На этом этапе нам нужно будет ввести ваш SO#, найденный внутри пакета, как указано в части распаковки,
и продукт будет официально зарегистрирован на веб-сайте e-Con Systems.
Нам будет предоставлена FTP-ссылка с учетными данными (имя пользователя и пароль). Сначала мы попытались перейти на FTP-сервер непосредственно в Firefox, но нас не попросили ввести учетные данные, и все, что мы получили, было пустой страницей, поэтому вместо этого мы использовали Filezilla для загрузки файлов.
Нам сообщили о некоторых проблемах с SSL-сертификатом, но без проблем мы смогли скачать все файлы для камеры:
Компания предоставила предварительно созданные двоичные файлы с изображениями Yocto и Raspbian, наборы исправлений и мета-уровень на случай, если вы захотите создать изображения самостоятельно, а также документацию, включающую таблицы данных для камеры и основных компонентов, руководство по началу работы и руководство разработчика, объясняющее, как собрать код из исходного кода и настроить изображения.
Тестирование камеры e-CAM20_CURB на Raspberry Pi 4 с Yocto
В дальнейшем мы будем в основном использовать информацию из Руководства по началу работы. Мы изначально решили использовать образ «Raspbian» и сохранили его с помощью USBImager. Но загрузка сработала не совсем так, как ожидалось, из-за паники ядра.
Пробовал еще раз прошить образ ОС, но во второй раз получили только черный экран. Компания не предоставляет контрольные суммы MD5 для изображений, поэтому мы не могли легко проверить, была ли проблема во время загрузки или это проблемы с нашей картой microSD (опять же). Поэтому вместо этого мы выбрали меньший образ Yocto, который отлично работает и поставляется со всеми теми же инструментами, что и образ Raspbian.
На приборной панели есть пять значков с приложением для калибровки сенсорного экрана, файловый менеджер, текстовый редактор L3afpad, кнопка выключения и терминал, где мы будем запускать все команды.
Верхний правый значок позволяет вам получить доступ к окну настроек, которое в основном полезно для настройки WiFi, если вы не используете Ethernet с DHCP.
Небольшой совет: вы можете делать скриншоты, как показано выше, на Yocto следующим образом:
1 |
gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw ,width=1920,height=1080 ! videoconvert ! fpsdisplaysink video-sink=autovideosink text-overlay=false sync=false -v |
В корневом каталоге вы найдете два скрипта:
- gst_1080_stream.sh используется для отображения вывода камеры с разрешением 1920×1080 на дисплей, подключенный к Raspberry Pi.
- gst_1080_record.sh используется для записи видео в формате Full HD на карту microSD.
Для обоих используется команда Gstreamers. Содержимое gst_1080_stream.sh :
1 |
gst-launch-1.0 --gst-debug-level=3 -v v4l2src device=/dev/video0 ! capsfilter caps="video/x-raw, width=1920,height=1080,framerate=30/1" ! queue ! v4l2convert ! videorate ! queue ! v4l2h264enc ! queue ! avimux ! filesink location = 1080p_recording.h264 |
и gst_1080_record.sh :
1 |
gst-launch-1.0 --gst-debug-level=3 -v v4l2src device=/dev/video0 ! capsfilter caps="video/x-raw, width=1920,height=1080,framerate=30/1" ! queue ! v4l2convert ! videorate ! queue ! v4l2h264enc ! queue ! avimux ! filesink location = 1080p_recording.h264 |
Сначала запустим gst_1080_stream.sh.
Выход камеры почти сразу же появился на нашем дисплее HDMI. Нам просто пришлось вручную настроить фокус, чтобы получить более четкое изображение.
Обратите внимание, что в документации указано:
Вышеупомянутое выполнение конвейера GStreamer должно выполняться с терминала в графическом интерфейсе Raspberry pi, а не с терминала UART (picocom или minicom) хост-компьютера.
Поэтому мы сделали большую часть обзора с терминала на дисплее, подключенном к Raspberry Pi, но в конце концов поняли, что можно запускать все программы с терминала SSH, просто сначала экспортировав дисплей:
1 |
export DISPLAY=:0 |
Вывод из скрипта для справки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Setting pipeline to PAUSED ... Pipeline is live and does not need PREROLL ... /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0/GstAutoVideoSink:autovideosink0/GstXvImageSink:autovideosink0-actual-sink-xvimage: sync = false Setting pipeline to PLAYING ... New clock: GstSystemClock /GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, format=(string)UYVY, colorimetry=(string)bt709, interlace-mode=(string)progressive /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, format=(string)UYVY, colorimetry=(string)bt709, interlace-mode=(string)progressive /GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:src: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, interlace-mode=(string)progressive, format=(string)YV12 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0.GstGhostPad:sink.GstProxyPad:proxypad0: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, interlace-mode=(string)progressive, format=(string)YV12 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0/GstAutoVideoSink:autovideosink0.GstGhostPad:sink.GstProxyPad:proxypad1: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, interlace-mode=(string)progressive, format=(string)YV12 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0/GstAutoVideoSink:autovideosink0/GstXvImageSink:autovideosink0-actual-sink-xvimage.GstPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, interlace-mode=(string)progressive, format=(string)YV12 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0/GstAutoVideoSink:autovideosink0.GstGhostPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, interlace-mode=(string)progressive, format=(string)YV12 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0.GstGhostPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, interlace-mode=(string)progressive, format=(string)YV12 /GstPipeline:pipeline0/GstVideoConvert:videoconvert0.GstPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, format=(string)UYVY, colorimetry=(string)bt709, interlace-mode=(string)progressive /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)120/1, format=(string)UYVY, colorimetry=(string)bt709, interlace-mode=(string)progressive /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0/GstAutoVideoSink:autovideosink0/GstXvImageSink:autovideosink0-actual-sink-xvimage: sync = false /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 15, dropped: 0, current: 28.41, average: 28.41 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 33, dropped: 0, current: 34.53, average: 31.45 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 51, dropped: 0, current: 34.38, average: 32.42 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 69, dropped: 0, current: 34.51, average: 32.94 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 87, dropped: 0, current: 34.42, average: 33.24 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 105, dropped: 0, current: 34.47, average: 33.44 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 119, dropped: 0, current: 27.69, average: 32.65 /GstPipeline:pipeline0/GstFPSDisplaySink:fpsdisplaysink0: last-message = rendered: 135, dropped: 0, current: 31.24, average: 32.47 .... |
Мы можем просто нажать Control+C, чтобы остановить приложение в терминале. Проделаем то же самое со скриптом «запись». На этот раз вывод камеры не отображается на дисплее, и все, что мы получаем, это информация в терминале:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
sh-5.0# ./gst_1080_record.sh Setting pipeline to PAUSED ... 0:00:00.150419981 877 0x90e300 WARN v4l2 gstv4l2object.c:4209:gst_v4l2_object_probe_caps:<v4l2h264enc0:src> Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: Invalid argument Pipeline is live and does not need PREROLL ... Setting pipeline to PLAYING ... New clock: GstSystemClock /GstPipeline:pipeline0/GstV4l2Src:v4l2src0.GstPad:src: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, format=(string)UYVY, interlace-mode=(string)progressive, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, format=(string)UYVY, interlace-mode=(string)progressive, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstQueue:queue0.GstPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, format=(string)UYVY, interlace-mode=(string)progressive, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, format=(string)UYVY, interlace-mode=(string)progressive, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstQueue:queue0.GstPad:src: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, format=(string)UYVY, interlace-mode=(string)progressive, colorimetry=(string)bt709 /GstPipeline:pipeline0/v4l2convert:v4l2convert0.GstPad:src: caps = video/x-raw, framerate=(fraction)30/1, interlace-mode=(string)progressive, format=(string)YUY2, width=(int)1920, height=(int)1080, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstVideoRate:videorate0.GstPad:src: caps = video/x-raw, framerate=(fraction)30/1, interlace-mode=(string)progressive, format=(string)YUY2, width=(int)1920, height=(int)1080, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstQueue:queue1.GstPad:sink: caps = video/x-raw, framerate=(fraction)30/1, interlace-mode=(string)progressive, format=(string)YUY2, width=(int)1920, height=(int)1080, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstQueue:queue1.GstPad:src: caps = video/x-raw, framerate=(fraction)30/1, interlace-mode=(string)progressive, format=(string)YUY2, width=(int)1920, height=(int)1080, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstQueue:queue1.GstPad:src: caps = video/x-raw, framerate=(fraction)30/1, interlace-mode=(string)progressive, format=(string)YUY2, width=(int)1920, height=(int)1080, colorimetry=(string)bt709 /GstPipeline:pipeline0/v4l2h264enc:v4l2h264enc0.GstPad:src: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, profile=(string)high, level=(string)4, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstQueue:queue2.GstPad:sink: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, profile=(string)high, level=(string)4, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstQueue:queue2.GstPad:src: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, profile=(string)high, level=(string)4, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt709 /GstPipeline:pipeline0/GstAviMux:avimux0.GstPad:video_0: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, profile=(string)high, level=(string)4, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30/1, interlace-mode=(string)progressive, colorimetry=(string)bt709 Redistribute latency... /GstPipeline:pipeline0/v4l2h264enc:v4l2h264enc0.GstPad:sink: caps = video/x-raw, framerate=(fraction)30/1, interlace-mode=(string)progressive, format=(string)YUY2, width=(int)1920, height=(int)1080, colorimetry=(string)bt709 /GstPipeline:pipeline0/v4l2convert:v4l2convert0.GstPad:sink: caps = video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, format=(string)UYVY, interlace-mode=(string)progressive, colorimetry=(string)bt709 0:00:00.349330444 877 0x925c90 WARN v4l2bufferpool gstv4l2bufferpool.c:1278:gst_v4l2_buffer_pool_dqbuf:<v4l2convert0:pool:src> Driver should never set v4l2_buffer.field to ANY 0:00:00.375340000 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 1 - ts: 0:00:00.197980673 0:00:00.404324815 877 0x925c60 WARN v4l2bufferpool gstv4l2bufferpool.c:809:gst_v4l2_buffer_pool_start:<v4l2h264enc0:pool:src> Uncertain or not enough buffers, enabling copy threshold 0:00:00.448002981 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 1 - ts: 0:00:00.259520155 0:00:00.476415111 877 0xb4a02d50 WARN v4l2bufferpool gstv4l2bufferpool.c:1278:gst_v4l2_buffer_pool_dqbuf:<v4l2h264enc0:pool:src> Driver should never set v4l2_buffer.field to ANY 0:00:00.478420518 877 0x925c30 FIXME basesink gstbasesink.c:3246:gst_base_sink_default_event:<filesink0> stream-start event without group-id. Consider implementing group-id handling in the upstream elements /GstPipeline:pipeline0/GstAviMux:avimux0.GstPad:src: caps = video/x-msvideo /GstPipeline:pipeline0/GstFileSink:filesink0.GstPad:sink: caps = video/x-msvideo 0:00:00.547811481 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 4 - ts: 0:00:00.351835691 0:00:00.603347092 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 2 - ts: 0:00:00.397979932 0:00:00.647031518 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 3 - ts: 0:00:00.459522340 .... 0:00:04.943636775 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 2 - ts: 0:00:04.705614006 0:00:04.981039497 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 3 - ts: 0:00:04.767162043 0:00:05.046930127 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 3 - ts: 0:00:04.828688765 0:00:05.113381867 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 2 - ts: 0:00:04.874841950 0:00:05.151058627 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 3 - ts: 0:00:04.936382932 0:00:05.219209497 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 3 - ts: 0:00:04.997920784 ^Chandling interrupt. Interrupt: Stopping pipeline ... Execution ended after 0:00:05.086424645 Setting pipeline to NULL ... 0:00:05.285227515 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 2 - ts: 0:00:05.044071080 0:00:05.329868941 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 3 - ts: 0:00:05.105612154 .... 0:00:07.765494532 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 3 - ts: 0:00:07.520962284 0:00:07.832332643 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 4 - ts: 0:00:07.597885506 0:00:07.869181273 877 0x925c90 WARN v4l2allocator gstv4l2allocator.c:559:gst_v4l2_allocator_create_buf:<v4l2convert0:pool:src:allocator> error creating a new buffer: No buffer space available 0:00:07.869370347 877 0x925c90 ERROR v4l2bufferpool gstv4l2bufferpool.c:479:gst_v4l2_buffer_pool_alloc_buffer:<v4l2convert0:pool:src> failed to allocate buffer 0:00:07.869481421 877 0x925c90 WARN bufferpool gstbufferpool.c:305:do_alloc_buffer:<v4l2convert0:pool:src> alloc function failed 0:00:07.869961421 877 0x925cc0 WARN v4l2src gstv4l2src.c:978:gst_v4l2src_create:<v4l2src0> lost frames detected: count = 3 - ts: 0:00:07.659424987 0:00:08.471311773 877 0x925c90 WARN basetransform gstbasetransform.c:2167:default_generate_output:<v4l2convert0> could not get buffer from pool: flushing Freeing pipeline ... |
Мы нажали Control + C, чтобы остановить запись, и получили файл 1080p_recording.h264, который мы передали на наш компьютер через SSH, чтобы подтвердить, что это файл AVI с видео 1920 × 1080 @ 30 кадров в секунду, закодированным с помощью H.264:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
mediainfo 1080p_recording.h264 General Complete name : 1080p_recording.h264 Format : AVI Format/Info : Audio Video Interleave File size : 8.94 MiB FileExtension_Invalid : avi Video ID : 0 Format : AVC Format/Info : Advanced Video Codec Codec ID : H264 Width : 1 920 pixels Height : 1 080 pixels Display aspect ratio : 16:9 Frame rate : 30.000 FPS Color space : YUV Chroma subsampling : 4:2:0 |
Мы загрузили образец на YouTube для справки:
Видео плавное, но зернистое, потому что оно было снято ночью.
Делать это в дневное время намного лучше, но освещение на видео выше не идеальное, поэтому мы попробовали еще раз с солнечным светом.
Инструмент gst-launch-1.0 довольно мощный и универсальный, но, если вы спросите меня, параметры командной строки не совсем интуитивно понятны, и требуется некоторое обучение, прежде чем полностью понять их все, и должен быть файл с именем «CAM20_CURB_GStreamer_Usage_Guide_<VER>». .pdf» с подробным объяснением этого, которого нет на FTP-сервере, но его можно запросить у e-Con Systems. Но, к счастью, изображения Yocto и Raspbian также поставляются с другим инструментом Gstreamer — gst-capture — который позволит вам проверить длинный список параметров камеры. Сначала нам нужно выбрать устройство video0:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
root@raspberrypi4:~# gst-capture APPVERSION - 1.2 SETTING DEFAULT RESOLUTION ==================== Video devices detected ==================== [1]:video14 [2]:video12 [3]:video1 [4]:video10 [5]:video13 [6]:video11 [7]:video0 [8]:v4l-subdev0 ================================================================ Select the video streaming device = 7 open device name = /dev/video0 open device name = /dev/video0 Streaming successful! +==================================================================================+ | V4L2 command line application - 1.2 | +==================================================================================+ [1] Still Capture Mode [2] Streaming Mode [3] Features [4] Exit from application |
После чего мы сможем переключаться между режимами фотосъемки или потоковой передачи (видео) и, что более важно, получить доступ к длинному списку функций для детального управления камерой:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
+==================================================================================+ | V4L2 command line application - 1.2 | +==================================================================================+ [1] Still Capture Mode [2] Streaming Mode [3] Features [4] Exit from application Enter the option: 3 [1] -- User Controls [2] -- Brightness [3] -- Contrast [4] -- Saturation [5] -- Gamma [6] -- Gain [7] -- Horizontal Flip [8] -- Vertical Flip [9] -- White Balance Temperature [10] -- Sharpness [11] -- Camera Controls [12] -- Exposure Auto [13] -- ROI Window Size [14] -- ROI Exposure [15] -- Denoise [16] -- Exposure Compensation [17] -- Image Processing Controls [18] -- Link Frequency [19] -- Pixel Rate [20] -- Frame rate message [21] -- Exit from Features Menu |
Мы сами успешно пробовали некоторые из них, но изучение всего этого выходит за рамки этого обзора/руководства по началу работы, поэтому мы просто покажем, как настроить яркость в качестве примера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Enter the option: 2 =============================================================== Brightness Menu -- Range -15 to 15, Step Size = 1, Default Value = 0 =============================================================== [1] Choose Brightness level [2] Exit from Brightness menu Note: Current Brightness Value is 0 ======================================================== Please choose the option :1 Please enter the Brightness Value : 10 =============================================================== Brightness Menu -- Range -15 to 15, Step Size = 1, Default Value = 0 =============================================================== [1] Choose Brightness level [2] Exit from Brightness menu Note: Current Brightness Value is 10 ======================================================== Please choose the option : |
Если вы смотрели видео, то заметили, что после изменения значений нам приходилось переключаться между терминалом и программой. Это не очень удобно, поэтому мы бы очень рекомендовали либо подключить второй экран, либо использовать ноутбук с SSH и экспортировать дисплей перед запуском команд:
1 |
export DISPLAY:=0 |
К сожалению, мы вспомнили об этом только в конце нашего обзора. Вероятно, его следует добавить в документацию e-Con Systems…
Помимо нескольких проблем, которые у нас были в начале с изображением ОС, у нас был довольно хороший опыт работы с камерой, которая хорошо работает с высокой частотой кадров в любых условиях освещения благодаря глобальному затвору. Камера также довольно проста в использовании с приличной документацией, а исходный код доступен для тех, кто хочет настроить ОС. Нам хотелось бы поблагодарить e-Con Systems за отправку камеры с глобальным затвором e-CAM20_CURB для Raspberry Pi 4 для обзора. Если вам интересно, компания продает его за 99 долларов плюс доставка .
Выражаем свою благодарность источнику с которого взята и переведена статья, сайту cnx-software.com.
Оригинал статьи вы можете прочитать здесь.