使用 MIPI 攝影機
當圖需要直接從 Modalix DevKit 上的 MIPI 攝影機讀取影格時,請使用 CameraInput。CameraInput 是經過驗證的 libcamera 串流與以加速器為優先的模型圖之間的 Neat 邊界:
CameraInput -> model-managed CVU preproc -> MLA -> Output
CameraInput -> model-managed CVU preproc -> MLA -> EV74 BoxDecode -> Output
沒有 appsrc。使用者程式碼中沒有 ostosima。除非您自行新增,否則生產路徑中沒有 CPU videoconvert 或 videoscale。
兩個階段:先啟動,然後是 Neat
MIPI CSI-2 是相機連接。它並不能讓每個感測器都能即插即用。一個可運作的相機路徑還需要正確的板載疊加層、感測器驅動程式、libcamera 管線、ISP 行為和 caps。
將 MIPI 相機工作視為兩個階段:
- 板載啟動: Modalix DevKit 偵測到感測器,並且 libcamera 可以串流所需的模式。
- Neat 圖啟動:
CameraInput將這些影格饋入模型管理的 CVU/MLA 階段。
Neat 從第二階段開始。它不會選擇 .dtbo 疊加層、載入感測器驅動程式或調整 ISP。對於疊加層設定、支援的疊加層名稱和 cam 驗證,請使用 Modalix DevKit MIPI 相機介面指南。
Neat 支援哪些功能
CameraInput 支援平台相機堆疊已啟動的相機:
- 相機連接到 Modalix DevKit MIPI 連接埠,同時板子已關閉;
- 正確的板載疊加層已啟用;
- 核心驅動程式和 libcamera 管線公開相機;
libcamerasrc可以協商所需的video/x-rawcaps,通常是NV12;- caps 與您在 Neat 中設定的模型預處理相符。
如果這些條件尚未滿足,請先修復相機堆疊。Neat 圖可以精確,但它無法將未綁定的感測器轉換為串流。
驗證相機串流
在建立圖之前,先在 libcamera/GStreamer 層驗證相機。如果此層無法運作,則 Neat 圖無法修復它。
在 DevKit 上,確認 libcamerasrc 是否存在:
gst-inspect-1.0 libcamerasrc如果可以使用 cam,請列出相機和檢查模式:
cam -lcam -c 1 -I然後試試您打算向 Neat 要求的確切規格:
gst-launch-1.0 -e libcamerasrc ! \ 'video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1' ! \ identity eos-after=30 ! fakesink為了進行簡單的視覺煙霧測試,請將幾個影格編碼為 JPEG 格式:
gst-launch-1.0 -e libcamerasrc ! \ 'video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1' ! \ identity eos-after=30 ! videoconvert ! jpegenc ! \ multifilesink location=/tmp/mipi-frame-%03d.jpgvideoconvert 和 jpegenc 對於這次的單次除錯檢查來說,效果還不錯。當吞吐量很重要時,請將它們排除在模型管線之外。
建立原始的 MLA 煙霧圖
從一個原始的 MLA 路線開始。它證明了在您新增特定模型的後處理之前,相機畫面是否已到達 CVU 預處理和 MLA 推論階段。
#include <neat.h>
namespace neat = simaai::neat;
neat::CameraInputOptions camera;
camera.width = 1920;
camera.height = 1080;
camera.framerate_num = 30;
camera.framerate_den = 1;
camera.format = "NV12";
camera.buffer_name = "camera0";
camera.allow_cpu_fallback = true;
neat::Model::Options model_options;
model_options.preprocess.kind = neat::InputKind::Image;
model_options.preprocess.input_max_width = static_cast<int>(camera.width);
model_options.preprocess.input_max_height = static_cast<int>(camera.height);
model_options.preprocess.input_max_depth = 3;
model_options.preprocess.color_convert.input_format = neat::PreprocessColorFormat::NV12;
model_options.preprocess.color_convert.output_format = neat::PreprocessColorFormat::RGB;
model_options.preprocess.resize.enable = neat::AutoFlag::On;
model_options.preprocess.resize.width = 640;
model_options.preprocess.resize.height = 640;
model_options.preprocess.resize.mode = neat::ResizeMode::Letterbox;
model_options.preprocess.resize.pad_value = 114;
model_options.preprocess.preset = neat::NormalizePreset::COCO_YOLO;
model_options.advanced_execution.preprocess_target = "EV74";
model_options.inference_terminal.mla_only = true;
neat::Model model("/models/yolo.tar.gz", model_options);
neat::Model::RouteOptions route;
route.include_input = false;
route.include_output = true;
route.upstream_name = camera.buffer_name;
route.buffer_name = camera.buffer_name;
route.name_suffix = "_camera0";
route.advanced_execution.preprocess_target = "EV74";
neat::Graph graph("camera_mla_smoke");
graph.add(neat::nodes::CameraInput(camera));
graph.add(model.graph(route));
neat::Run run = graph.build();
std::optional<neat::Sample> output = run.pull(/*timeout_ms=*/5000);
inference_terminal.mla_only = true 是刻意為之。它會將煙霧路徑維持在 CameraInput -> CVU preproc -> MLA -> Output,因此您可以在偵測解碼之前,先對相機和推論動作進行除錯。
當模型需要時,新增 EV74 BoxDecode
對於 YOLO 樣式的偵測模型,請明確啟用 BoxDecode,並將後處理保留在 EV74 上。解碼標記必須與 MPK 的輸出合約相符。
model_options.inference_terminal.mla_only = false;
model_options.decode_type = neat::BoxDecodeType::YoloV9Seg;
model_options.advanced_execution.postprocess_target = "EV74";
model_options.score_threshold = 0.25f;
model_options.nms_iou_threshold = 0.45f;
model_options.top_k = 100;
route.advanced_execution.postprocess_target = "EV74";
讓 decode_type 保持未設定,並在您需要原始 MLA 張量時,保留 mla_only = true。僅在模型路徑應輸出已解碼的檢測或分割資料時,設定 decode_type。