-
deepstream-test2 項目重點解說
-
文件路徑:
/sources/deepstream_python_apps/apps的deepstream-test2/deepstream_test_2.py -
范例功能:在deepstream-test1的檢測器基層上,添加三個分類器
-
插件流:filesrc-> h264parser -> nvh264decoder -> nvstreammux-> nvinfer(pgie->tracker->sgie1->sgei2->sgie3)->nvvideoconvert ->nvdsosd->nvegltransform -> nveglglessink
-
上面“粗體”部分是改動的重點
deepstream-test2 代碼還是以 deepstream-test1 為基礎,如果不熟悉的請先看看本系列前面的文章。這里維持 test1 的視頻文件輸入與顯示器輸出方式不變,在“Car/Person/Bicycle/RoadSign”四種物件分類的推理識別基礎上,為“Car”物件再添加“顏色/品牌/車型”這三種分類屬性(如下圖),因此總體來說就需要“一個檢測器(detector)”與“三個分類器(classifier)”來共同完成這項任務。
可能有人會問,那是否能在“Person”或“RoadSign”上面增加分類器?例如將前者再添加“男/女”、“老/少”分類,對后者再添加“限制類”、“指示類”、“警告類”的屬性呢?這當然是可以的,只要你能找到合適的模型文件來搭配,或者得自己重新收集數據集進行模型訓練,然后再提供對應的配置文件。 與 test1 范例中所不同的地方,在 test2 范例在“pgie”這個“nvinfer”元素之外,又添加“sgie1/sgie2/sgie3”這3個推理計算的元素,總共四個推理器的內容如下: 這個過程有個比較特殊的地方,就是在”主推理器(這里是個檢測器)”與“次推理器(這里是三個分類器)”之間,需要透過“追蹤器(tracker)”進行串聯,這里有個很重要的原因,因為次推理器是以主推理器的“范圍圖像”去進行分類推理,包括顏色、品牌、車型等等,而追蹤器可以協助記錄主推理器所找到的“圖像范圍”,將這個局部的數據傳送給次推理器去進行計算,這樣才能建立好“主次”之間的關聯。 因此我們會發現,只要需要進行這種“主次結合”的方式,必定需要調用“追蹤器”這個元件來扮演角色,這個在 deepstream-app 里面也是存在的,但是這里會延伸出另一個問題,就是調用追蹤器是會影響性能的,在 DeepStream 追蹤器里面,目前支持 NVDCF、KLT 與 IOU 三種算法,其中 NVDCF 算法的性能最差,KLT 在準確性與性能的綜合表現較好,因此大部分的范例中都選擇使用 KLT 追蹤器。 附帶說明的一點,就是追蹤器插件接受來自上游組件的 NV12-或 RGBA 格式的幀數據,并將輸入緩沖區轉換為低層庫所需格式的緩沖區,再將寬度和高度轉換為跟蹤器要求的寬度和高度,這需要將輸入幀緩沖區轉換為底層庫請求的格式,例如 KLT 使用 Luma 專用格式、NvDCF 使用 NV12 或 RGBA 格式,IOU 則不需要緩沖區。
上圖是 nvtracker 插件的工作示意圖,詳細的內容請自行參考開發手冊:https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_plugin_gst-nvtracker.html 好了,前面已經將整體原理說明的差不多,接下來就看看 test2 與 test1 的 Python 代碼中的差異部分,這樣就更能掌握這部分的實際運作內涵。
-
deepstream-test2 代碼修改部分
如同前面所提到的,這個代碼主要修改的部分,就是在 pgie 與 nvvideoconvert 之間,添加 tracker 與 sgie 1~3 這四個元件,其他修改的部分幾乎都在處理 tracker 的部分,包括一開始需要為追蹤器是否保存追蹤數據的。
以上就是 test2 與 test1 在創建元件與設置參數部分的一些代碼修改的部分,至于管道創建與連接的部分,自己就能看懂,這里就不浪費篇幅去說明。 最后還有一部分,就是在函數 osd_sink_pad_buffer_probe 里面,第 126~164 行有一代碼,不過下面注釋內容表明 l_user.data 與 user_meta.user_meta_data 在這里并不做處理,我們也試過將“if(past_tracking_meta[0]==1):”下面整段代碼全部刪除,并不影響 test2 范例的執行與輸出結果。# 42行:給定這個變量設定是否保存追蹤的數據
past_tracking_meta=[0]
# 217至238行:在 pgie與 nvvidconv 之間,添加 tracker + sgie1~3
pgie = Gst.ElementFactory.make("nvinfer", "primary-inference")
tracker = Gst.ElementFactory.make("nvtracker", "tracker")
sgie1 = Gst.ElementFactory.make("nvinfer", "secondary1-nvinference-engine")
sgie2 = Gst.ElementFactory.make("nvinfer", "secondary2-nvinference-engine")
sgie3 = Gst.ElementFactory.make("nvinfer", "secondary3-nvinference-engine")
nvvidconv = Gst.ElementFactory.make("nvvideoconvert", "convertor")
# 264~268行:設定推理器的配置文件
pgie.set_property('config-file-path', "dstest2_pgie_config.txt")
sgie1.set_property('config-file-path', "dstest2_sgie1_config.txt")
sgie2.set_property('config-file-path', "dstest2_sgie2_config.txt")
sgie3.set_property('config-file-path', "dstest2_sgie3_config.txt")
#270~296行:設置追蹤器的各項參數,從配置文件中獲取對應的參數
config = configparser.ConfigParser()
config.read('dstest2_tracker_config.txt')
config.sections()
# 從dstest2_tracker_config.txt讀入,為追蹤器逐項設置變量
for key in config['tracker']:
if key == 'tracker-width' :
tracker_width = config.getint('tracker', key)
tracker.set_property('tracker-width', tracker_width)
if key == 'tracker-height' :
tracker_height = config.getint('tracker', key)
tracker.set_property('tracker-height', tracker_height)
if key == 'gpu-id' :
tracker_gpu_id = config.getint('tracker', key)
tracker.set_property('gpu_id', tracker_gpu_id)
if key == 'll-lib-file' :
tracker_ll_lib_file = config.get('tracker', key)
tracker.set_property('ll-lib-file', tracker_ll_lib_file)
if key == 'll-config-file' :
tracker_ll_config_file = config.get('tracker', key)
tracker.set_property('ll-config-file', tracker_ll_config_file)
if key == 'enable-batch-process' :
tracker_enable_batch_process = config.getint('tracker', key)
tracker.set_property('enable_batch_process', tracker_enable_batch_process)
if key == 'enable-past-frame' :
tracker_enable_past_frame = config.getint('tracker', key)
tracker.set_property('enable_past_frame',tracker_enable_past_frame)
-
修改設定文件與執行
最后在執行之前,看一下 5 個配置文件的內容,發現原本的設定以“INT8”精度模式進行推理,可以看到文件里的“network-mode”都設置為“1”,如果在 Jetson Nano(含 2GB)上執行時,建議將這些模式都改成“FP16”模式,除了將所有“network-mode”都改成“2”之外,再把每個加速引擎的“xxx_int8.engine”改成“xxx_fp16.engine”。
雖然不改變這個設定值也能正常工作,差別就在于如果要重復測試的時候,就得花費更多時間去重新生成“xxx_fp16.engine”加速引擎,如果改成“fp16”模式的話,就只需要生成一次就行,第二次再執行的時候就會非常快速啟動。
好了,一切就緒之后,就可以體驗一下這個多模型合成功能的效果,請執行以下指令:
python3 deepstream_test_2.py ../../../../samples/streams/sample_720p.h264
在屏幕上方會出現該幀的檢測結果,不過這里只顯示“Vehicle”與“Person”兩個類別。圖片中也能清楚看到每個物件都有個“追蹤編號”,在 Car 物件上也有“顏色”、“廠牌”、“車型”等信息。 當我們回頭再仔細看看這個范例的代碼,會發現其實大部分要做的事情,就是把插件元件做合理的安排,然后就是“定義”、“創建”、“連接”,就幾乎完成大部分的工作了。
責任編輯:haq
原文標題:NVIDIA Jetson Nano 2GB 系列文章(37):多網路模型合成功能
文章出處:【微信號:NVIDIA-Enterprise,微信公眾號:NVIDIA英偉達企業解決方案】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
歐洲借助NVIDIA Nemotron優化主權大語言模型
使用NVIDIA Triton和TensorRT-LLM部署TTS應用的最佳實踐

NVIDIA GTC巴黎亮點:全新Cosmos Predict-2世界基礎模型與CARLA集成加速智能汽車訓練
英偉達GTC2025亮點 NVIDIA推出Cosmos世界基礎模型和物理AI數據工具的重大更新
NVIDIA推出Isaac GR00T Blueprint
NVIDIA推出開放式Llama Nemotron系列模型
NVIDIA推出面向RTX AI PC的AI基礎模型
NVIDIA Cosmos世界基礎模型平臺發布
NVIDIA推出全新生成式AI模型Fugatto
NVIDIA助力Figure發布新一代對話式人形機器人
NVIDIA助力提供多樣、靈活的模型選擇
NVIDIA Nemotron-4 340B模型幫助開發者生成合成訓練數據

NVIDIA AI Foundry 為全球企業打造自定義 Llama 3.1 生成式 AI 模型

評論