相機輸入節點
CameraInput 是一個來源節點,用於透過 libcamera 和 GStreamer 的 libcamerasrc 暴露的 MIPI 攝影機。當您希望圖中的影格來自 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 將會選擇預設相機。 |
width | 1920 | 以像素為單位,指定所需的畫面寬度。必須受到相機模式和疊加層的支援。 |
height | 1080 | 以像素為單位,指定要求的影格高度。 |
framerate_num | 30 | 幀率分子。 |
framerate_den | 1 | 幀率分母。0 已正規化為 1。 |
format | "NV12" | 。已要求使用 video/x-raw 格式。NV12 是建議的模型預處理路徑。 |
buffer_name | "camera" | 邏輯緩衝區名稱,用於後續的中繼資料和模型路徑命名。 |
insert_queue | true | 在設定器協商和零拷貝驗證之後,插入一個小型即時來源佇列。 |
leaky_queue | true | 讓佇列在下游處具有「漏水」特性,這樣即時圖就會優先選擇較新的影格,而不是過時的後備資料。 |
queue_depth | 2 | 當 insert_queue 為 true 時,佇列中最多可容納的緩衝區數量。 |
allow_cpu_fallback | false | 如果設定為 false,則轉送相機的 DMA-BUF,並在任何需要複製的幀上失敗。 僅在要讓 Neat 的私有橋接將此類幀複製到 CMA DMA-BUF 時,才將其設定為 true。 |
capture_buffer_count 是 CameraInputWithCaptureBuffers 的一個參數,而不是
CameraInputOptions 欄位。其預設值為 0,這可保留相機
管線本身的預設值。相機管線會驗證其限制;Neat 的
提供者最多支援 128。
輸入與輸出合約
| 合約條款 | 行為 |
|---|---|
| 輸入角色 | 來源節點。圖形會從相機中提取畫面;應用程式不會將樣本推送至此節點。 |
| 輸出媒體類型為 | video/x-raw。 |
| 輸出格式 | 要求的 format,通常為 NV12。 |
| 記憶體合約 | 相機自身的 DMA-BUF 會在不複製的情況下轉送至下游。啟用備援機制後,非 單一 DMA-BUF 的幀會被複製到 CMA DMA-BUF 中,以便後續的 CVU/MLA 階段使用。 |
| 限制最大支援能力 | 根據使用者要求的選項,提供靜態提示。在執行階段進行的最大支援能力協商,仍然取決於相機堆疊。 |
零複製與備援機制
allow_cpu_fallback = false 是預設值,它要求嚴格的零拷貝:相機會將每個幀寫入其自身的 DMA-BUF,而每個下游階段都會讀取同一塊記憶體。Neat 從不擁有相機的記憶體,因此不需要任何 libcamerasrc 屬性。任何實體連續的 DMA-BUF 都是有效的 EV74 輸入;當其來自 CMA 堆積或相機的連續擷取分配器(videobuf2_dma_contig)時,Neat 的 EV74 准入檢查會予以接受。
Neat 始終將其私有相機橋接直接放置在 capsfilter 之後,並在即時佇列之前。該橋接透過 GST_QUERY_ALLOCATION 要求來源附加 GstVideoMeta,然後將各平面在單一 DMA-BUF 中緊密相連的每個幀作為單一記憶體轉送,並保留相機的緩衝區,直到每個消費端都已釋放它。在嚴格模式下,無法以此方式轉送的幀會使管線失敗;啟用備援機制時,則會改為將其複製到 CMA DMA-BUF 中。
根據下游所有者,將 capture_buffer_count 傳遞給相機工廠。一個時間編碼器或深度非同步 ML 圖可能需要 32 個緩衝區;一個低延遲的 CV 圖可能使用更少的緩衝區並丟棄過時的幀。此設定僅控制 ISP 輸出/應用程式週期。它不會擴大內核的私有 CSI 到 ISP RAW 傳輸環,並且與 GStreamer 的 queue_depth 丟棄策略無關。在 Platform 3.0 上,libcamerasrc 沒有 buffer-count 屬性,因此請在該平台上將 capture_buffer_count 保持為 0。
由於橋接會轉送相機自身的緩衝區,下游階段仍持有的每個幀都會佔用 libcamera 擷取環中的一個緩衝區(在 Platform 3.0 上使用 IMX477 擷取 1080p NV12 時為 8 個緩衝區)。持有這麼多幀的圖會使擷取停滯,而不是丟棄幀,因此請及時釋放已拉取的幀。
明確設定 allow_cpu_fallback = true,以允許已存在的橋接在幀並非各平面緊密相連的單一 DMA-BUF 時進行拷貝。對於屬於此類 DMA-BUF 的幀,橋接仍會直接轉送。否則,它會將相機幀複製到私有池中的 CMA DMA-BUF,並附加下游階段所期望的元資料。該池會按需增長至最多 128 個緩衝區,而不是受到 queue_depth 的限制,這允許下游的「漏」佇列丟棄過時的幀,而無需橋接首先停止。
回退名稱表示橋接可以接受作業系統/libcamera 緩衝區。這並不意味著您應該將調整大小、色彩轉換或正規化移動到 CPU。只要路徑支援,請將這些操作保留在模型管理的 CVU 預處理中。
不要為 CameraInput 添加 OsToSima 節點。適配工作屬於相機源路徑。
常見的圖形
直接擷取相機畫面:
CameraInput -> Output
將相機對準模型:
CameraInput -> model.graph({include_input=false, include_output=true})
對於模型管線,請透過 Model::Options::preprocess 或 pyneat.ModelOptions.preprocess 來設定預處理,以確保調整大小、色彩轉換、正規化、量化和細分等操作都保留在模型管理的 CVU 流程中。
失效模式
| 錯誤 | 可能原因 |
|---|---|
build.plugin_missing | ,libcamerasrc 或 neatcamerabridge 缺少於執行階段的外掛程式集中。 |
misconfig.media_caps / not-negotiated | 攝影機不支援您所要求的格式、解析度或幀率。 |
misconfig.media_caps / gstreamer.camera_configuration_unsupported | 攝影機未提供所要求的解析度或像素格式,因此 libcamerasrc 協商失敗。請以支援的尺寸擷取;模型圖形應由模型前處理調整尺寸,其他圖形則使用 VideoScale,後接 CapsRaw。 |
| 嚴格的零拷貝錯誤 | ,allow_cpu_fallback 為「否」,且相機傳遞的幀並非各平面緊 密相連的單一 DMA-BUF。 |
| 讀取逾時 | 攝影機未傳輸畫面,圖的後壓過大,或攝影機堆疊已停止串流。 |
| 綠色、紫色或顏色過於鮮豔的相框。 | 相框格式或模型的預處理色彩轉換可能出錯,或者相框的顏色已經存在於相機的 ISP/libcamera 輸出中。首先驗證一個 NV12 格式的圖像,看看是否在 Neat 之外也有同樣的問題。 |