BoxDecode 解碼類型
nodes::SimaBoxDecode 將原始偵測頭張量轉換為偵測結果。它在模型推論後執行,套用所選模型系列的解碼運算並篩選偵測結果。NMS 與輸出編碼取決於所選系列。偵測模型可將酬載解析為方框;姿勢與分割模型也可解析方框之後的關鍵點或遮罩。
對於一般的模型套件使用,建議使用 Model 感知的建構函式。模型封存檔提供了解碼器所需的張量順序、佈局、量化、類別數量、調整大小的中繼資料和分數域提示。您的應用程式通常只需要選擇解碼系列和過濾閾值。
執行階段後端
BoxDecode 與 SuperPoint 透過 neatkernelrunner 使用已檢查的 Kernels 執行物件。
既有的偵測與特徵輸出格式保持不變。YOLO26 旋轉框解碼使用獨立的版本化格式。直接張量輸入請使用共用 CMA 張量
(TensorMemory::EV74),即使解碼在 A65 執行也一樣:此記憶體選擇提供的是
DMA-BUF 傳輸,而非執行目標。
RCNN 第 1 階段使用核心擁有的逐層 top-K 契約:先全域 NMS,再於每個模型面積層級
保留最多 top_k 個候選項。輸出是提案線路格式,而非一般 BBOX 格式:共四組,
每組包含一個 INT32 計數與 top_k 筆六 FP16 記錄 (score, 0, x1, y1, x2, y2)。
座標轉換保留小數幾何資訊,直到最終序列化。請將其用作第二階段提案輸入,
不要搭配 decode_bbox_tensor() 使用。不會載入舊版外掛程式。
具有填補、交錯排列的 INT8、BF16 與 FP32 SuperPoint 輸出頭使用原生密集讀取器及 明確像素步幅。填補區不參與偵測器歸約與描述子取樣,不需要 Cast 階段或具體化。 INT8 埠保留各自設定的量化資訊。原生 MLA 平鋪輸出頭保留其宣告的實體佈局; 絕不將密集純量重新標成 MLA 位元組平面。
快速入門
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 閾值。設為 0 時會保留模型封裝的值;若未封裝任何值,YOLO26 會略過 NMS,其他解碼器會抑制所有重疊的方框。請設定適合模型的值,例如 0.45。 |
top_k | 最大輸出數量。原始邊界框解碼需要明確的正值上限。綁定模型的節點中,0 繼承已解析的 Model 上限。SuperPoint 在 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_obb(...) | pyneat.decode_obb(...) | 具有自身儲存空間的幾何資料 [N, 5] float32(cx, cy, width, height, angle_radians)、分數 [N] float32、類別 ID [N] int32 |
| 姿勢 | 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 |
| 分割 + 姿態 | decode_segmentation_pose(...) | pyneat.decode_segmentation_pose(...) | 邊界框 [N, 6] float32、遮罩 [N, 160, 160] uint8、關鍵點 [N, 17, 3] float32 |
| SuperPoint | decode_superpoint(...) | pyneat.decode_superpoint(...) | 關鍵點 [N,2],分數 [N],描述子 [N,D] |
軸對齊偵測結果的顯示圖可將結果 傳給 SimaRender。decode_bbox(...) 僅適用於既有的方框前置格式;此函式與 SimaRender 都不接受旋轉框。
傳統 DETR
對於同一查詢網格上的四通道方框 logits,以及最後一個通道為背景的類別 logits,請選擇 Detr。將 decode_type_option 保持為 Auto:配方會選擇 Softmax,不依賴張量名稱。背景會參與分母計算,但不計入前景類別數,也不會被選為輸出。方框座標會套用 sigmoid;此解碼器不適用於已正規化的 focal-loss 方框。
請使用 Stretch 與正值 top_k。解碼器不套用 NMS,並透過前處理中繼資料還原原始影格座標。明確指定機率值的配置或衝突的分數啟用函數會遭拒絕。
options = pyneat.ModelOptions()
options.decode_type = pyneat.BoxDecodeType.Detr
options.preprocess.resize.mode = pyneat.ResizeMode.Stretch
options.top_k = 100
options.score_threshold = 0.7
Focal loss 查詢偵測器
對依序排列的兩個張量使用 BoxDecodeType::DetrFocal(Python:pyneat.BoxDecodeType.DetrFocal,權杖 detr-focal):深度4的正規化 cx,cy,width,height 座標,接著是深度N的獨立類別logits。查詢軸與資料型別必須相符;N為1–1024。支援FP32、BF16及具有明確量化資訊的INT8儲存格式。
此設定檔僅對類別logits套用sigmoid,並從所有查詢/類別配對中選取全域前K名。同一查詢可產生多個類別。沒有背景類別、方框sigmoid、逐查詢argmax、NMS或小面積篩選。設定正數 top_k;若不篩選top-K,設定 detection_threshold=0;nms_iou_threshold=0 為必要值。使用Stretch及實際的影像/模型尺寸。
既有 BBOX 輸出會將方框裁切至影像邊界,並將XYWH座標四捨五入為整數。decode_bbox 將這些座標顯示為浮點數,但不會還原次像素精度。與未裁切的浮點參考比較時,請分別衡量此表示方式對準確度的影響。傳統 BoxDecodeType::Detr 維持不變:它需要方框logits及包含背景類別的softmax分數,而非這些張量。
在Python中使用 decode_bbox(..., strict=True),即可保留四捨五入後面積為零的列,而不套用預設的退化方框篩選。
Python raw-geometry 多載對應 C++ 工廠,適合自行提供頭部張量。密集 FP32 頭部應保留模型的完整輸出介面轉換,並明確宣告實際儲存格式。請勿在原始 MLA 輸出截斷流程,或將含填補的位元組重新標示為密集張量。
node = pyneat.nodes.sima_box_decode(
pyneat.BoxDecodeType.DetrFocal,
original_width=1280, original_height=720,
model_width=640, model_height=640,
detection_threshold=0.0, nms_iou_threshold=0.0, top_k=300,
decode_type_option=pyneat.BoxDecodeTypeOption.InterleavedByHeadLogit,
source_storage=pyneat.BoxDecodeSourceStorage.DenseHwc,
detess=False, dequant=False,
resize_mode=pyneat.ResizeMode.Stretch,
)
有限反向尺寸會由既有端點裁切轉為零面積 BBOX 記錄,保留入選配對及分數。非有限座標或 logits 仍會在發布前失敗。
YOLOv8 與 YOLO11 旋轉邊界框
選取 BoxDecodeType::YoloV8Obb(Python:pyneat.BoxDecodeType.YoloV8Obb;代碼 yolov8-obb 或 yolo11-obb)。提供九個依角色分組的 INT8、BF16 或 FP32 頭:三個 64 通道 DFL 邊界框頭、三個類別 logit 頭,以及三個角度 logit 頭,各組依步幅 8、16、32 排列。完整類別數由類別頭推導。
BoxDecode 會套用 DFL、類別 sigmoid、(sigmoid(angle)-0.25)*pi,以及使用 nms_iou_threshold 的各類別旋轉 Fast-NMS。輸入必須為原始 logit。幾何資訊與 BBOX_OBB_V1 輸出遵循下方的 YOLO26 契約,並使用相同的 decode_obb 輔助函式。
YOLO26 旋轉框
明確選取 BoxDecodeType::YoloV26Obb(Python:pyneat.BoxDecodeType.YoloV26Obb,代碼 yolo26-obb)。此設定檔接收九個 FP32、BF16 或 INT8 頭,依角色分組為三個四通道距離頭、三個類別 logit 頭,以及三個單通道原始角度頭,各組步幅為 8、16、32。所有頭的完整類別數(1–256)必須一致。Auto、GroupedByRole 與 GroupedByRoleLogit 會選用此分組佈局;機率值類別頭與交錯佈局會遭到拒絕。
INT8 頭需要正且有限的逐張量量化中繼資料與 INT8 零點。BF16 和 FP32 頭不使用整數量化中繼資料。
使用正值 top_k 與 nms_iou_threshold = 0。此設定檔對類別 logit 套用 sigmoid,以最高啟用分數選出錨點,再選出錨點/類別配對。分數相同時保留第一階段排名與 類別順序。分數門檻採嚴格不等式(score > detection_threshold)。原始角度已是弧度,解碼器不會再套用 sigmoid 或正規化其範圍。
前處理中繼資料必須提供明確且有限的模型座標到原圖座標轉換,X/Y 縮放係數須為正且相等,並且不得包含剪切。即使圖塊與模型尺寸相同,也必須明確提供恆等轉換。若缺少轉換或轉換為非等向性,此設定檔會拒絕,而不會近似旋轉矩形。它保留帶正負號的有限寬度/高度,不會裁切至影像邊界。進行分塊 DOTA 評估時,每個圖塊使用恆等轉換,再由應用程式還原圖塊偏移並執行跨圖塊多邊形抑制。
在來源驅動的圖中,Core 會從已驗證的上游 Preproc 契約推導初始準備用的幾何資訊。這只是準備用的初始值:每個影格仍須提供有限、正值且等比例的仿射轉換,以及與模型相符的畫布尺寸。缺少影格轉換時會回報錯誤,不會退回恆等轉換。
輸出標記為 BBOX_OBB_V1:32 位元組版本化標頭後接 top_k 筆 32 位元組記錄。未使用的記錄為零。decode_obb_tensor(tensor) 驗證單一載體;decode_obb(tensors) 為每個載體傳回一個具型別的結果。兩者都會複製到具有自身儲存空間的 CPU 張量;類別 ID 維持 INT32。例如:
result = pyneat.decode_obb(outputs)[0]
geometry = result.geometry.to_numpy() # cx, cy, width, height, angle_radians
scores = result.scores.to_numpy()
class_ids = result.class_ids.to_numpy()
此格式刻意不作為前置 BBOX 的擴充。請使用具型別的輔助函式,而非 decode_bbox、分割/姿勢解析器或軸對齊方框的繪製器。
超級點
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 不會捨棄或重新解釋該來源。