BoxDecode 解碼類型
nodes::SimaBoxDecode 將原始的檢測頭張量轉換為檢測結果。它在模型推論之後執行,應用所選模型系列的解碼數學公式,過濾掉低信度框,執行非最大值抑制 (NMS),並輸出一個張量有效載荷,該有效載荷以解碼後的框開始。檢測模型可以將該有效載荷解析為框;姿勢和分割模型也可以解析在框之後的關鍵點或遮罩。
對於一般的模型套件使用,建議使用 Model 感知的建構函式。模型封存檔提供了解碼器所需的張量順序、佈局、量化、類別數量、調整大小的中繼資料和分數域提示。您的應用程式通常只需要選擇解碼系列和過濾閾值。
快速入門
using namespace simaai::neat;
Model model("/path/to/yolov8_model.tar.gz");
auto boxdecode = nodes::SimaBoxDecode(
model,
BoxDecodeType::YoloV8,
/* detection_threshold */ 0.25,
/* nms_iou_threshold */ 0.45,
/* top_k */ 100);
針對單獨的階段使用:
simaai::neat::stages::BoxDecodeOptions opt(simaai::neat::BoxDecodeType::YoloV8);
opt.detection_threshold = 0.25;
opt.nms_iou_threshold = 0.45;
opt.top_k = 100;
參數
| 參數 | 意義 |
|---|---|
decode_type | 模型系列/標頭格式,例如 BoxDecodeType::YoloV8 或 BoxDecodeType::YoloX。必填。 |
detection_threshold | 為了保留檢測結果,所需的最低分數。請使用適合模型的數值,例如 0.25。 |
nms_iou_threshold | 非最大值抑制中使用的 IoU 閾值。 |
top_k | 保留的最多檢測數量。0 使用後端/模型的預設值。 |
original_width, original_height | 使用原始幾何建構函時,用於座標映射的原始影像大小。 |
model_width、model_height | 用於覆寫模型輸入大小。在使用 Model 建構函式時,這會更改空間解碼參數,而非已封裝的張量合約。 |
resize_mode_override | 僅在沒有上游 Preproc 階段寫入調整大小的元資料,且您需要明確指定拉伸/信箱/裁剪行為時使用。 |
decode_type_option | 進階子版面設定選擇器。除非您知道匯出的版面設定,否則請保留為 Auto,以便用於模型套件。 |
輸入與輸出
**輸入:**來自模型的原始檢測張量。預期的張量形狀取決於模型系列。對於 MPK/模型封存檔,Neat 會從封裝的合約中讀取這些詳細資訊。
**輸出:**一個 BoxDecode 張量,其中包含已解碼的檢測結果。檢測模型使用標準 BBOX 負載。姿勢和分割模型保留相同的初始框,並附加其任務特定的負載:
| 模型任務 | C++ 輔助程式 | Python 輔助程式 | 解碼後的張量 |
|---|---|---|---|
| 偵測 | decode_bbox(...) | pyneat.decode_bbox(...) | [N, 6] float32 框:x1, y1, x2, y2, score, class_id |
| 姿勢 | decode_pose(...) | pyneat.decode_pose(...) | 方框 [N, 6] 和關鍵點 [N, 17, 3] float32:x, y, visibility |
| 分割 | decode_segmentation(...) | pyneat.decode_segmentation(...) | 方塊 [N, 6] float32,以及遮罩 [N, 160, 160] uint8 |
| SuperPoint | decode_superpoint(...) | pyneat.decode_superpoint(...) | 關鍵點 [N,2],分數 [N],描述子 [N,D] |
偵測顯示圖可以將結果傳送到 SimaRender。如果應用程式碼只需要框選結果,則可以繼續使用 decode_bbox(...) 處理 BoxDecode 的輸出。
超級點
SuperPoint 仍然是 BoxDecode 產品的一部分,但它會輸出特徵點,而不是假裝這些點是方框。最簡化的 A65 預設設定如下:
BoxDecodeOptions options{BoxDecodeType::SuperPoint};
options.superpoint.descriptor_output_dtype = TensorDType::Float32;
auto decoder = nodes::SimaBoxDecode(model, options);
Python 使用相同的預設值:
options = pyneat.BoxDecodeOptions(pyneat.BoxDecodeType.SuperPoint)
options.superpoint.descriptor_output_dtype = pyneat.TensorDType.Float32
decoder = pyneat.nodes.sima_box_decode(model, options=options)
A65V1 是預設設定檔。當模型需要不同的數值行為時,請明確選擇另一個設定檔;Neat 不會根據張量的形狀或值來推斷行為:
| 個人檔案 | 何時選擇 | 生產狀態 |
|---|---|---|
LightGlueV1 | 與 LightGlue 相容的檢測器、非最大值抑制 (NMS)、座標和描述符行為 | 已支援 |
MagicLeapDemoV1 | 固定位置的 Magic Leap 示範行為 | 支援 |
A65V1 | 與先前 A65 SuperPoint 解碼器相容 | 已支援;預設值 |
PaperBicubicV1 | 保留的數值 ID,用於未來完全指定的雙三次插值策略 | 暫時拒絕,直到產品定義完成 |
數值行為和輸出編碼是相互獨立的。例如,選擇 A65 數值行為,並使用預設的 V1 輸出:
BoxDecodeOptions options{BoxDecodeType::SuperPoint};
options.superpoint.profile = SuperPointProfile::A65V1;
options.superpoint.output_format = SuperPointOutputFormat::FeaturePointsV1;
舊版位元組設定為選擇性功能,且具有額外的限制:
options.superpoint.profile = SuperPointProfile::A65V1;
options.superpoint.output_format = SuperPointOutputFormat::LegacyA65InterleavedV0;
options.superpoint.descriptor_output_dtype = TensorDType::Int8;
SuperPointProfile::Auto 首先使用權威的 MPK superpoint.profile 元資料。如果 API (Model::Options.superpoint.profile) 或 MPK 都未提供設定檔,則會解析為 A65V1。
Neat 不會根據張量形狀、值、檔案名稱或下游節點來推測設定檔。
當其公開的預設值保持不變時,detection_threshold=0.0、top_k=0、nms_radius=-1 和 border_margin=-1 將從選定的設定檔中解析。A65V1 解析為閾值 0.1、Top-K 600、NMS 半 徑 4 和邊界間距 0。LightGlueV1 和 MagicLeapDemoV1 使用閾值 0.0005 和 0.015,分別;兩者都使用 Top-K 600、NMS 半徑 4 和邊界間距 4。
nms_iou_threshold 不適用於 SuperPoint;請使用像素半徑 superpoint.nms_radius。預設輸出是版本化的 FEATURE_POINTS_V1 結構化陣列有效載荷。LegacyA65InterleavedV0 是一種明確的遷移格式,需要 256 維 INT8 描述符。請使用 decode_superpoint,而不是 decode_bbox 或 BoxDecodeResults。
版本化的 MPK superpoint 模式 v1 記錄是「失敗時關閉」的。它們必須命名設定檔、不同的檢測器和描述符張量 ID、一個帶有 64 個十六進位數字的 sha256: 指紋,以及受支援的輸入表示形式 raw-logits-65 和 coarse-pre-l2。模式 0 僅作為遷移/手動記錄被接受;省略的模式 0 表示形式欄位會正規化為這兩種原始輸入表示形式,並記錄在診斷資訊中作為預設值。未知的模式版本或表示形式標記會導致合約編譯失敗。
如果 API 設定檔覆蓋與為不同 MPK 設定檔蓋章的指紋衝突,則重新為選定的設定檔蓋章 MPK;Neat 不會捨棄或重新解釋該來源。
BBOX 線路負載
偵測解碼器會針對每個輸入影格輸出一個標記為 BBOX 的張量。該張量是一個一維的 UInt8 位元組緩衝區:
| 欄位 | 值 |
|---|---|
semantic.detection.format | "BBOX" |
dtype | UInt8 |
shape | [N_bytes],其中 N_bytes 是來自模型封存檔的已封裝緩衝區容量。 |
張量的形狀代表的是位元組數量,而不是偵測到的物件數量。有效載荷採用小端格式:
offset size content
------ ---- -------
0 4 uint32 N = valid detections in this frame
4 24 RawBox[0]
28 24 RawBox[1]
. . ...
. . RawBox[N-1]
trailing bytes are padding and must be ignored
每個 RawBox 記錄的長度為 24 位元組:
| 偏移量 | 大小 | 類型 | 欄位 | 意義 |
|---|---|---|---|---|
| 0 | 4 | int32 | x | 原始影像中左上角的位置(以像素為單位)。 |
| 4 | 4 | int32 | y | 來源影像中,左上角 y 座標。 |
| 8 | 4 | int32 | w | 原始影像的寬度(以像素為單位)。 |
| 12 | 4 | int32 | h | 原始影像中的高度(以像素為單位)。 |
| 16 | 4 | float32 | score | 在 [0.0, 1.0] 中,NMS 之後的置信度。 |
| 20 | 4 | int32 | class_id | 模型定義的類別 ID。 |
對應的 Python struct 格式,用於單一記錄,為 "<iiiifi"。
如果存在上游預處理的元資料,則座標將以原始影像的像素為單位。它們不會正規化到 [0, 1],也不會以模型內部「黑邊」輸入空間的形式表示。
當 model.run 傳回原始的標題時
某些模型路徑會從 model.run(...) 傳回原始的特徵圖頭,而不是傳回已解碼的 BBOX 張量。這並不是表示執行失敗。這表示模型已執行,但該路徑在您讀取輸出時並沒有包含「框解碼」步驟。
請使用以下規則:
detections=...或一個BBOX張量:解析壓縮後的 BBOX 負載,或使用。 解碼輔助工具。raw_output_heads=...: 新增「BoxDecode」階段,或檢查模型路徑。 使用模型特定的後處理方式來處理原始的張量。