NVIDIA DeepStream插件之Gst-nvtracker
- 1. 源由
- 2. 基礎知識
- 3. Gst-nvtracker插件
- 3.1 插件參數
- 3.2 插件API接口
- 4. 分析問題
- 5. 總結
- 6. 參考資料
1. 源由
這篇的主要目的是稍微吐槽下NVIDIA的設計,當然其實他們做的還是不錯的(從系統架構設計角度看,插件采用so動態庫方式是不錯的,只不過技巧上還可以更加不錯)。
本次涉及到使用 BYTETrack
開源代碼的 DeepStream
集成,在實際使用的時候遇到非常郁悶、糟心的事情。N多年前的開源代碼,已經被證明或者成熟應用的東西,為啥不好用(報錯)???
- Gstnvtracker: Optional NvMOT_RetrieveMiscData not implemented
daniel@daniel-nvidia:~/Work/jetson-fpv/utils/dsyolo$ deepstream-app -c source_config_yolov8s.txt
** WARN: <parse_tracker:1604>: Unknown key 'enable-batch-process' for group [tracker]
gstnvtracker: Loading low-level lib at /home/daniel/Work/jetson-fpv/utils/dsyolo/libByteTracker.so
gstnvtracker: Optional NvMOT_RetrieveMiscData not implemented
[BYTETrack Initialized]
gstnvtracker: Only batch processing mode is supported. query.batchMode must be set as NvMOTBatchMode_Batch
gstnvtracker: Failed to initilaize low level lib.
** ERROR: <main:716>: Failed to set pipeline to PAUSED
Quitting
nvstreammux: Successfully handled EOS for source_id=0
App run failed
daniel@daniel-nvidia:~/Work/jetson-fpv/utils/dsyolo$ ls /home/daniel/Work/jetson-fpv/utils/dsyolo/libByteTracker.so
/home/daniel/Work/jetson-fpv/utils/dsyolo/libByteTracker.so
其實本來是非常簡單的一件事情,但由于兼容性的問題,折騰!!!為了解決該問題,所以投資了不少時間,有必要討論、吐槽下。
2. 基礎知識
這里牽涉到一些概念,當然CSDN這里就不再詳細贅述。以前折騰過一些框架設計相關的知識和要點如下:
【1】靜態庫和動態庫編譯方法和開發上的重要性
【2】Linux的so組件設計框架及邏輯
【3】【C語言】函數默認實現和用戶自定義實現編程方法 – 【weak, strong alias】
這個插件實際上使用的是【1】、【2】點內容,而缺少了【3】,所以導致了本次報錯,給兼容性帶來了不必要的麻煩。
3. Gst-nvtracker插件
- Gst-nvtracker 插件允許 DeepStream (DS) 流水線使用低級跟蹤器庫,通過唯一的 ID 持續跟蹤檢測到的對象。
支持實現 NvDsTracker API 的庫,包括由 NvMultiObjectTracker 庫提供的參考實現:
- IOU 跟蹤器:交并比(Intersection-Over-Union,IOU)跟蹤器使用檢測器在兩幀之間的邊界框的 IOU 值來進行關聯,如果沒有找到匹配,則分配一個新的目標 ID。該跟蹤器包含一個邏輯,用于處理目標檢測器中的誤檢(false positives)和漏檢(false negatives);然而,這可以被認為是最基礎的目標跟蹤器,僅能作為基準使用。
- NvSORT:NvSORT 跟蹤器是 NVIDIA? 增強版的簡單在線實時跟蹤(Simple Online and Realtime Tracking,SORT)算法。與簡單的二分圖匹配算法不同,NvSORT 使用基于邊界框(bbox)接近性的級聯數據關聯方法,在連續幀之間進行邊界框的關聯,并使用卡爾曼濾波器更新目標狀態。由于不涉及任何像素數據處理,它的計算效率非常高。
- NvDeepSORT:NvDeepSORT 跟蹤器是 NVIDIA? 增強版的基于深度關聯度量的在線實時跟蹤(DeepSORT)算法。它通過使用帶有重新識別(Re-ID)神經網絡的深度余弦度量學習,在多幀之間進行多個對象的數據關聯。此實現允許用戶使用任何支持 NVIDIA TensorRT? 框架的 Re-ID 網絡。NvDeepSORT 同樣采用級聯數據關聯方法,而非簡單的二分圖匹配算法,并針對 GPU 進行了高效處理的優化。
- NvDCF:NvDCF 跟蹤器是一種在線多目標跟蹤器,采用判別性相關濾波器進行視覺目標跟蹤,即使檢測結果不可用時也能獨立跟蹤目標。它結合了相關濾波器的響應和邊界框的接近性來進行數據關聯。
注:NvDeepSORT 和 NvDCF 跟蹤器使用 NV12 或 RGBA 格式,而 IOU 和 NvSORT 不需要任何視頻幀緩沖區。
- Gst-nvtracker 插件還支持通過 NvMOT_RetrieveMiscData API 從低級跟蹤器庫中檢索用戶定義的雜項數據
這些數據包括當前幀目標的默認數據以外的有用對象跟蹤信息。例如,歷史幀的對象數據、陰影跟蹤模式中的目標、已終止目標的完整軌跡以及重新識別特征。有關雜項數據類型及其意義的更多詳細信息,可以參考“雜項數據輸出”部分。用戶還可以在 NvMOTTrackerMiscData 中定義其他類型的雜項數據。
3.1 插件參數
Property | Meaning | Type and Range | Example Notes |
---|---|---|---|
tracker-width | Frame width at which the tracker is to operate, in pixels. (To be a multiple of 32 when visualTrackerType: 1 or reidType is non-zero with useVPICropScaler: 0 ) | Integer, 0 to 4,294,967,295 | tracker-width=640 |
tracker-height | Frame height at which the tracker is to operate, in pixels. (To be a multiple of 32 when visualTrackerType: 1 or reidType is non-zero with useVPICropScaler: 0 ) | Integer, 0 to 4,294,967,295 | tracker-height=384 |
ll-lib-file | Pathname of the low-level tracker library to be loaded by Gst-nvtracker. | String | ll-lib-file=/opt/nvidia/deepstream/deepstream/lib/libnvds_nvmultiobjecttracker.so |
ll-config-file | Configuration file for the low-level library if needed. Supports multiple files with semicolon delimiter. | Path to configuration file OR a semicolon-delimited list of paths | ll-config-file=config_tracker_NvDCF_perf.yml ll-config-file=config_tracker_NvDCF_perf1.yml;config_tracker_NvDCF_perf2.yml |
gpu-id | ID of the GPU on which memory is allocated, and buffer copy/scaling is done. (dGPU only.) | Integer, 0 to 4,294,967,295 | gpu-id=0 |
tracking-surface-type | Set surface stream type for tracking. (Default is 0.) | Integer, ≥0 | tracking-surface-type=0 |
display-tracking-id | Enables tracking ID display on OSD. | Boolean | display-tracking-id=1 |
compute-hw | Compute engine to use for scaling: 0 - Default 1 - GPU 2 - VIC (Jetson only) | Integer, 0 to 2 | compute-hw=1 |
tracking-id-reset-mode | Allows force-reset of tracking ID based on pipeline events: 0 - No reset 1 - Reset on GST_NVEVENT_STREAM_RESET 2 - Reset on GST_NVEVENT_STREAM_EOS 3 - Both | Integer, 0 to 3 | tracking-id-reset-mode=0 |
input-tensor-meta | Use tensor-meta from Gst-nvdspreprocess if available for tensor-meta-gie-id . | Boolean | input-tensor-meta=1 |
tensor-meta-gie-id | Tensor Meta GIE ID to use (valid only if input-tensor-meta is TRUE). | Unsigned Integer, ≥0 | tensor-meta-gie-id=5 |
sub-batches | Configure batch splitting in sub-batches: Option 1: Semicolon-separated array of source IDs. Option 2: Colon-separated array of sub-batch sizes. | See description | Option 1: sub-batches=0,1;2,3 Option 2: sub-batches=2:1 |
sub-batch-err-recovery-trial-cnt | Number of recovery attempts for errors in low-level tracker. -1 for infinite retries. | Integer, ≥-1 | sub-batch-err-recovery-trial-cnt=3 |
user-meta-pool-size | Size of tracker miscellaneous data buffer pool. | Unsigned Integer, >0 | user-meta-pool-size=32 |
3.2 插件API接口
- NvMOT_Query
NvMOTStatus NvMOT_Query (uint16_t customConfigFilePathSize,char* pCustomConfigFilePath,NvMOTQuery *pQuery
);
- NvMOT_Init
NvMOTStatus NvMOT_Init (NvMOTConfig *pConfigIn,NvMOTContextHandle *pContextHandle,NvMOTConfigResponse *pConfigResponse
);
- NvMOT_Process
NvMOTStatus NvMOT_Process (NvMOTContextHandle contextHandle,NvMOTProcessParams *pParams,NvMOTTrackedObjBatch *pTrackedObjectsBatch
);
- NvMOT_RetrieveMiscData
NvMOTStatus NvMOT_RetrieveMiscData (NvMOTContextHandle contextHandle,NvMOTProcessParams *pParams,NvMOTTrackerMiscData *pTrackerMiscData
);
- NvMOT_RemoveStreams
void NvMOT_RemoveStreams (NvMOTContextHandle contextHandle,NvMOTStreamId streamIdMask
);
- NvMOT_DeInit
void NvMOT_DeInit (NvMOTContextHandle contextHandle);
4. 分析問題
現象:鑒于前面執行LOG顯示: gstnvtracker: Optional NvMOT_RetrieveMiscData not implemented
分析:NvMOT_RetrieveMiscData
正好是上面第四個API,因此邏輯上考慮可能是加載這個so符號的時候遇到了問題。
原因:最終,發現在 BTYETrack
確實沒有這部分代碼。
解決:由于之前這部分代碼是可以使用,隨著Jetpack版本升級,增加了這部分API,但是BYTETrack
沒有這部分。為此:fix multi-object track and Deepstream 6.3 API link issue
5. 總結
若在架構設計的時候,考慮兼容性方面的問題,引入weak symbol概念(當用戶沒有實現,weak鏈接到stub函數,就能很好的兼容舊接口開發的代碼)。
總的來說,NVIDIA在Deepstream這塊其實采用了so插件的框架結構,很好,但若能更好的技巧上運用一些方法,可以讓代碼兼容性,尤其是第三方插件開發更好的應用于NVIDIA的生態。
6. 參考資料
【1】DeepStream documentation - Gst-nvtracker
【2】ByteTrack is a simple, fast and strong multi-object tracker