Перейти до основного вмісту

Вхідний вузол камери.

Наведений нижче посібник libcamera описує типовий бекенд. Для сирих тензорів Metoak SIMOR у власній пам’яті дивіться розділ V4L2 нижче.

CameraInput — це вихідний вузол для MIPI-камер, доступ до яких здійснюється через libcamera та GStreamer libcamerasrc. Використовуйте його на початку графа, що належить джерелу, коли кадри повинні надходити зі стеку камер DevKit, а не з run.push(...).

Інструкції щодо виконання завдання див. у розділі Використовуйте камеру MIPI..

Необхідні умови.​

Перш ніж використовувати CameraInput, активуйте камеру за межами Neat:

  • прикріпіть камеру, коли Modalix DevKit вимкнено.
  • оберіть відповідне накладення .dtbo, яке відповідає материнській платі, виробнику камери, сенсору та порту.
  • перевірте, чи відображається камера в списку libcamera;
  • підтвердьте, чи може libcamerasrc здійснювати потокову передачу у вказаному вами форматі format,width,height,framerate.

camera_name – це назва камери libcamera. Залиште це значення порожнім для використання камери за замовчуванням або скопіюйте назву з cam -l, якщо на платі встановлено більше однієї камери.

Швидкий старт.​

#include <neat.h>

namespace neat = simaai::neat;

neat::CameraInputOptions opt;
opt.width = 1920;
opt.height = 1080;
opt.framerate_num = 30;
opt.framerate_den = 1;
opt.format = "NV12";
opt.buffer_name = "camera0";
opt.allow_cpu_fallback = true;

neat::Graph graph;
graph.add(neat::nodes::CameraInput(opt));
graph.add(neat::nodes::Output("frames"));

neat::Run run = graph.build();
std::optional<neat::Sample> frame = run.pull(/*timeout_ms=*/5000);

Оскільки CameraInput є власником джерела, створіть граф, не додаючи загальнодоступний вузол Input, якщо ваш застосунок насправді не має іншого вхідного вузла, що надходить від іншого застосунку.

Інтерфейс API.​

namespace simaai::neat {
struct CameraInputOptions;
class CameraInput;
}

namespace simaai::neat::nodes {
std::shared_ptr<simaai::neat::Node> CameraInput(
simaai::neat::CameraInputOptions opt = {});
std::shared_ptr<simaai::neat::Node> CameraInputWithCaptureBuffers(
simaai::neat::CameraInputOptions opt,
std::uint32_t capture_buffer_count);
}

Python:

opt = pyneat.CameraInputOptions()
node = pyneat.nodes.camera_input(opt, capture_buffer_count=32)

Параметри​

ПолеЗначення за замовчуваннямОпис
camera_nameне встановленоНеобов’язкова назва камери libcamera, зазвичай копіюється з cam -l. Залиште порожнім, щоб дозволити libcamera вибрати камеру за замовчуванням.
width1920Зазначена ширина кадру в пікселях. Має підтримуватися камерою та накладкою.
height1080Запитана висота фрейму в пікселях.
framerate_num30Чисельник частоти кадрів.
framerate_den1Знаменник частоти кадрів. 0 нормалізується до 1.
format"NV12"Запитано video/x-raw формат. NV12 є рекомендованим шляхом попередньої обробки для моделі.
buffer_name"camera"Логічна назва буфера, що використовується в подальших метаданих і для іменування моделей.
insert_queuetrueПісля узгодження з алокатором і перевірки можливості використання механізму «нульового копіювання» вставте невелику чергу для потокового джерела даних.
leaky_queuetrueЗробіть чергу пропускною у нижній частині, щоб динамічні графіки надавали перевагу останнім кадрам, а не застарілим даним.
queue_depth2Максимальна кількість буферів у черзі, коли insert_queue має значення true.
allow_cpu_fallbackfalseЯкщо false, вимагайте підтримку функції «нульового копіювання» для камери/пристрою. Встановіть значення true лише для активації приватної адаптивної інтеграції Neat із пам’яттю SiMaAI.

capture_buffer_count тепер також є полем CameraInputOptions. Нуль зберігає типове значення бекенду, ненульове значення перевизначає кількість буферів захоплення. Наявна фабрика C++ та ключовий аргумент Python залишаються доступними. Межа libcamera — 128; сирому V4L2 потрібно 4–128 буферів.

Вхідні та вихідні параметри контракту.​

Пункт контрактуПоведінка
Вхідна роль:Вхідний вузол. Граф отримує кадри з камери; додаток не передає дані до цього вузла.
Тип вихідного медіафайлу:video/x-raw.
Формат виводу:Зазвичай, запитуваний формат format – це NV12.
Контракт пам’ятіВіддає перевагу механізму обміну даними без копіювання між пристроєм і SiMaAI. У разі активації механізму резервного копіювання, буфери ОС/libcamera адаптуються для використання в пам’яті SiMaAI для подальших етапів обробки CVU/MLA.
Обмеження можливостей, що гарантуютьсяСтатична підказка, що базується на запрошених параметрах. Узгодження обмежень можливостей під час роботи все ще залежить від програмного забезпечення камери.

Нульове копіювання та резервне копіювання.​

allow_cpu_fallback = false є значенням за замовчуванням і вимагає суворого використання камери/пристрою без копіювання даних. Збірка завершиться помилкою, якщо встановлений libcamerasrc не надає загальну властивість external-buffer-mode, і бібліотека пам’яті не може експортувати виділену пам’ять камери як DMA-буфери.

Neat завжди розміщує свій приватний міст камери безпосередньо після фільтра caps і перед живою чергою. Міст пропонує стандартний пул через GStreamer's downstream GST_QUERY_ALLOCATION. Пул отримує розміри площин і крок з валідованих caps, виділяє їх з одного упакованого виділення SiMaAI та експортує один DMA-буфер на площину. libcamerasrc імпортує ці DMA-буфери в чергу захоплення ISP. Міст перевіряє результат і розпаковує те саме упаковане виділення без копіювання в суворому режимі.

Передайте capture_buffer_count до фабрики камери на основі власника в потоці даних. Тимчасовий кодувальник або глибокий асинхронний ML-граф може потребувати 32 буфери; граф CV з низькою затримкою може використовувати менше і відкидати застарілі кадри. Це налаштування контролює лише цикл ISP-вихід/застосунок. Воно не збільшує приватне кільце передачі RAW CSI-to-ISP в ядрі, і воно не залежить від політики відкидання GStreamer queue_depth.

Явно встановіть allow_cpu_fallback = true, щоб дозволити вже наявному мосту виконувати копіювання, коли стек камери не може виконати запропонований розподільник. Міст передає буфери SiMaAI/EV74, коли вони надаються вищезазначеним потоком. В іншому випадку він копіює кадр камери в пул SiMaAI і приєднує метадані, які очікують наступні етапи. Цей приватний пул копій збільшується за потреби, а не обмежується queue_depth, що дозволяє потоку даних, який може втрачати дані, відкидати застарілі кадри, не змушуючи міст спочатку зупинятися.

Назва fallback означає, що міст може приймати буфери OS/libcamera. Це не означає, що слід перемістити зміну розміру, перетворення кольору або нормалізацію на ЦП. Залиште ці операції в попередній обробці CVU, керованій моделлю, коли це підтримується.

Не додавайте самостійно вузол OsToSima для CameraInput. Адаптація належить до шляху джерела камери.

Найпоширеніші типи графів.​

Витягуйте кадри безпосередньо з камери:

CameraInput -> Output

Проведіть камерою по моделі:

CameraInput -> model.graph({include_input=false, include_output=true})

Для конвеєрів моделей налаштуйте попередню обробку за допомогою Model::Options::preprocess або pyneat.ModelOptions.preprocess, щоб такі операції, як зміна розміру, перетворення кольорів, нормалізація, квантування та теселяція, виконувалися в межах керованого моделлю шляху обробки комп’ютерного зору (CVU).

Можливі сценарії відмови.​

ПомилкаЙмовірна причина
build.plugin_missinglibcamerasrc або neatcamerabridge відсутні в наборі плагінів середовища виконання.
misconfig.media_caps / not-negotiatedКамера не підтримує запрошений формат, роздільну здатність або частоту кадрів.
Сувора нульова копія помилокallow_cpu_fallback має значення «false», і джерело камери не надає властивості SiMaAI для нульової копії.
Час очікування вичерпано.Камера не передала кадри, на графі виникла затримка, або потік даних від камери зупинився.
Зелені, фіолетові або надмірно кольорові рамки.Формат або модель рамки неправильно обробляє перетворення кольорів, або колірне відтінення вже присутнє у вихідних даних камери ISP/libcamera. Спочатку перевірте NV12 знімок поза Neat.

Захоплення raw V4L2 із власною пам’яттю​

Для обох бекендів використовуйте наявну фабрику CameraInput(options) (Python: camera_input). Приклад вибирає профіль копіювання сирих даних Metoak SIMOR лише для Linux. Укажіть фактичний пристрій захоплення; /dev/video1 — лише приклад. На інших платформах повертається помилка непідтримуваного бекенду.

#include <neat.h>
namespace n = simaai::neat;

n::CameraInputOptions camera;
camera.device = "/dev/video1";
camera.profile = n::CameraProfile::MetoakSimor;

n::Graph capture;
capture.add(n::nodes::CameraInput(camera));
capture.add(n::nodes::Output());
import pyneat as neat

camera = neat.CameraInputOptions()
camera.device = "/dev/video1"
camera.profile = neat.CameraProfile.MetoakSimor

capture = neat.Graph()
capture.add(neat.nodes.camera_input(camera))
capture.add(neat.nodes.output())

MetoakSimor використовує власне копіювання, якщо zero_copy не задано. Кожен отриманий MMAP-кадр копіюється в незалежну системну пам’ять пулу перед поверненням буфера камери в чергу. Явне zero_copy=false має ту саму поведінку; zero_copy=true відхиляється, оскільки профіль не підтримує експорт/імпорт DMA-BUF. Неявного резервного шляху немає. camera_name та allow_cpu_fallback призначені лише для libcamera. Зберігається частота пристрою; framerate_num/framerate_den не налаштовують цей профіль.

Вихід — плаский тензор UInt8 [bytesused], включно з дійсним доповненням рядків і кінцевими байтами, а не декодоване зображення. Узгоджені fourcc, width, height, row-stride, sizeimage доступні в Sample.caps_string. Не змінюйте форму на розміри декодованого зображення й не відкидайте кінцеві байти до розбору протоколу пристрою. Час доставки залишається метаданими, а не байтами тензора.

Типові значення: capture_buffer_count — 8 (4–128), output_buffer_count — 8 (2–128), frame_timeout_ms — 2000 (1–60000). Утримувані виходи займають слоти пулу. Коли пул заповнений, звільніть їх для відновлення захоплення; утримувані тензори не перезаписуються. Для ввімкненої черги queue_depth має бути додатним і меншим за output_buffer_count. Зупинка перериває очікування пулу.

Перед захопленням налаштуйте зв’язки медіаконтролера та формати pad за інструкціями BSP; Neat не переписує медіаграф. Не запускайте іншого клієнта захоплення одночасно. Платформні та USB-пристрої використовують однаковий життєвий цикл V4L2 MMAP. Драйвер має дотримуватися контракту STREAMOFF: копіювання не робить помилкове завершення DMA в ядрі безпечним. Збій завершення потребує відновлення пристрою, а не автоматичного повторного відкриття.

CPU-розпакування SIMOR, калібрування та публікація ROS залишаються в застосунку. Він може передати шість початкових входів до MetoakDepth graph 20 в окремому графі обробки. API не додає обробку SIMOR і не потребує graph 21, нової прошивки чи змін наявної інтеграції ROS.

Під час запуску вихідні caps і пул буферів CPU готуються до постановки буферів камери в чергу. Зупинка перериває очікування кадру й пулу, завершує захоплення, а потім звільняє вихідний пул. Уже передані тензори залишаються дійсними після зупинки. Помилка завершення захоплення повідомляється через шину GStreamer і забороняє перезапуск цього джерела; вихід із процесу не замінює відновлення пристрою.

Вибір профілю та сумісність​

  • profile=Default (типово) завжди використовує libcamera та зберігає вибір через camera_name. Задання device без profile=MetoakSimor відхиляється; воно ніколи не вибирає Metoak неявно.
  • profile=MetoakSimor внутрішньо вибирає V4L2 із власною копією, RAW8, BA81 і транспортними розмірами 1920×360. Він замінює типові NV12/1080; інші суперечливі формати й розміри відхиляються. Цей профіль не охоплює всі камери Metoak.
  • Профіль SIMOR без device вимагає рівно однієї відповідної кінцевої точки в медіатопології. Відсутні, неоднозначні або змішані сенсорні маршрути спричиняють помилку. Під час виявлення пристрій захоплення не відкривається. Явні профіль і пристрій обходять виявлення.
  • Формат пікселів не вибирає бекенд. Загальні запити сирого/Bayer формату залишаються на шляху libcamera; ця зміна не додає й не підтверджує узгодження Bayer caps. Профіль визначає транспортний FourCC; публічного параметра FourCC немає.
  • Для MetoakSimor незаданий zero_copy перетворюється на false, а явне true відхиляється. Для libcamera незадане значення зберігає allow_cpu_fallback; false дозволяє наявне резервне копіювання, true вимагає нульового копіювання. Суперечливі налаштування відхиляються.
  • Реалізація вибирається один раз під час створення вузла, до поширення контрактів графа. Публічного параметра backend немає; помилка не перемикає реалізацію. Виявлення не налаштовує медіазв’язки чи формати площадок.

Лише профіль MetoakSimor без device перевіряє медіаконтролери. Запити метаданих є синхронними викликами ядра без гарантованого обмеження часу виконання. Якщо контролер не відповідає, задайте одночасно device і profile=MetoakSimor, щоб обійти виявлення.

Використовуйте лише CameraInput(options) і CameraInputOptions; конфігурація V4L2 приватна. Маніфест і SONAME залишаються на Core ABI 5. У цій ще не випущеній інтеграції змінилися компонування публічних параметрів і вузла: перебудуйте споживачів C++ та використовуйте відповідний Python wheel. Не змішуйте старі бінарні файли ABI-5 з новими заголовками або середовищем виконання.