在高分辨率輸入中檢測物體是計算機視覺中的一個眾所周知的問題。當感興趣的是框架的某個區域時,不需要對整個框架進行推理。解決這個問題有兩種方法:
- 使用具有高輸入分辨率的大型模型。
- 將大圖像分為塊,并將較小的模型應用于每個塊。
在許多方面,第一種方法是困難的。訓練輸入量大的模型通常需要更大的主干,使整個模型更笨重。訓練或部署這樣的模型也需要更多的計算資源。較大的模型被認為不適合在較小的設備上部署邊緣。
第二種方法,將整個圖像劃分為塊,并對每個塊應用較小的模型,具有明顯的優勢。使用較小的模型,因此在訓練和推理中需要較小的計算能力。將模型應用于高分辨率輸入不需要再培訓。較小的模型也被認為有利于邊緣部署。
在這篇文章中,我們將討論如何 NVIDIA DeepStream?可以幫助將較小的模型應用于高分辨率輸入,以檢測特定的幀區域。
視頻監控系統概述
視頻監控系統用于解決各種問題,例如識別行人、車輛和汽車。如今, 4K 和 8K 攝像機用于捕捉場景細節。軍方將航空攝影用于各種目的,這也涵蓋了大片區域。
隨著分辨率的增加,像素數呈指數增長。處理如此大量的像素需要大量的計算能力,尤其是使用深度神經網絡。
基于在建模過程中選擇的輸入維數,深度神經網絡對固定形狀的輸入進行操作。這種固定大小的輸入也稱為感受野模型的。通常,在檢測和分割網絡中,感受野從 256 × 256 到 1280 × 1280 不等。
您可能會發現感興趣的區域是一個小區域,而不是整個幀。在這種情況下,如果檢測應用于整個幀,則不必要地使用計算資源。 DeepStream NvDsPreprocess?插件使您能夠在框架的特定區域上進行計算。
DeepStream NvDsPreprocessing 插件
然而,當平鋪應用于圖像或幀時,尤其是在視頻饋送上,您需要在推理管道中增加一個元素。這樣的元素預計將執行可按流配置的分塊機制、分塊推理以及將多個分塊的推理組合到單個幀上。
有趣的是, DeepStream 中提供了所有這些功能 Gst-NvDsPreprocess?可自定義插件。它提供了一個用于預處理輸入流的自定義庫接口。每個流都有自己的預處理要求。
默認插件實現提供以下功能:
- 具有預定義感興趣區域( ROI )或分片的流根據推理的網絡要求進行縮放和格式轉換。每流 ROI 在配置文件中指定。
- 它從縮放和轉換的 ROI 中準備一個原始張量,并通過用戶元數據傳遞給下游插件。下游插件可以訪問該張量進行推理。
DeepStream NvDsPreprocessing 插件
下一步是修改現有代碼以支持平鋪。
使用 NvdsPreprocessing 插件
定義管道內的預處理元素:
preprocess = Gst.ElementFactory.make("nvdspreprocess", "preprocess-plugin")
NvDsPreprocess
需要一個配置文件作為輸入:
preprocess.set_property("config-file", "config_preprocess.txt")
將預處理元素添加到管道:
pipeline.add(preprocess)
將元素鏈接到管道:
streammux.link(preprocess) preprocess.link(pgie)
讓 NvdsPreprocess 插件進行預處理
推斷是通過NvDsInfer
插件完成的,該插件具有幀預處理功能。
當您在NvDsInfer
之前使用NvdsPreprocess
插件時,您希望預處理(縮放或格式轉換)由 NvdsPreprocess
而不是NvDsInfer
完成。為此,請將NvDsInfer
的input-tensor-meta
屬性設置為 true 。這使得NvdsPreprocess
可以進行預處理,并使用附加為元數據的預處理輸入張量,而不是NvDsInfer
本身內部的預處理。
將Gst-nvdspreprocess
功能合并到現有管道中需要以下步驟。
定義nvdspreprocess
插件并將其添加到管道:
preprocess = Gst.ElementFactory.make("nvdspreprocess", "preprocess-plugin") pipeline.add(preprocess)
將NvDsInfer
的input-tensor-meta
屬性設置為 true :
pgie.set_property("input-tensor-meta", True)
定義nvdspreprocess
插件的配置文件屬性:
preprocess.set_property("config-file", "config_preprocess.txt")
將預處理插件鏈接到主推理機(pgie
)之前:
streammux.link(preprocess) preprocess.link(pgie)
創建配置文件
Gst-nvdspreprocess
配置文件使用密鑰文件格式。有關更多信息,請參閱 Python 和 C 源代碼中的config_preprocess.txt
。
[property]
組配置插件的一般行為。[group-<id>]
組使用自定義庫中的src-id
值和custom-input-transformation-function
為一組流配置 ROI 、 TILE 和 ull 幀。
[user-configs]
組配置自定義庫所需的參數,自定義庫通過<string, string>
的映射作為鍵值對傳遞給自定義庫。然后,自定義庫必須相應地解析這些值。
所需的最小值config_preprocess.txt
類似于以下代碼示例:
[property] enable=1 target-unique-ids=1 # 0=NCHW, 1=NHWC, 2=CUSTOM network-input-order=0 network-input-order=0 processing-width=960 processing-height=544 scaling-buf-pool-size=6 tensor-buf-pool-size=6 # tensor shape based on network-input-order network-input-shape=12;3;544;960 # 0=RGB, 1=BGR, 2=GRAY network-color-format=0 # 0=FP32, 1=UINT8, 2=INT8, 3=UINT32, 4=INT32, 5=FP16 tensor-data-type=0 tensor-name=input_1 # 0=NVBUF_MEM_DEFAULT 1=NVBUF_MEM_CUDA_PINNED 2=NVBUF_MEM_CUDA_DEVICE 3=NVBUF_MEM_CUDA_UNIFIED scaling-pool-memory-type=0 # 0=NvBufSurfTransformCompute_Default 1=NvBufSurfTransformCompute_GPU 2=NvBufSurfTransformCompute_VIC scaling-pool-compute-hw=0 # Scaling Interpolation method # 0=NvBufSurfTransformInter_Nearest 1=NvBufSurfTransformInter_Bilinear 2=NvBufSurfTransformInter_Algo1 # 3=NvBufSurfTransformInter_Algo2 4=NvBufSurfTransformInter_Algo3 5=NvBufSurfTransformInter_Algo4 # 6=NvBufSurfTransformInter_Default scaling-filter=0 custom-lib-path=/opt/nvidia/deepstream/deepstream/lib/gst-plugins/libcustom2d_preprocess.so custom-tensor-preparation-function=CustomTensorPreparation [user-configs] pixel-normalization-factor=0.003921568 #mean-file= #offsets= [group-0] src-ids=0;1;2;3 custom-input-transformation-function=CustomAsyncTransformation process-on-roi=1 roi-params-src-0=0;540;900;500;960;0;900;500;0;0;540;900; roi-params-src-1=0;540;900;500;960;0;900;500;0;0;540;900; roi-params-src-2=0;540;900;500;960;0;900;500;0;0;540;900; roi-params-src-3=0;540;900;500;960;0;900;500;0;0;540;900;
Processing-width
和processing-height
是指切片在整個幀上的寬度和高度。
對于network-input-shape
,當前配置文件配置為最多運行 12 個 ROI 。要增加 ROI 計數,請將第一維度增加到所需數量,例如network-input-shape=12;3;544;960
。
在當前配置文件config-preprocess.txt
中,每個源有三個 ROI ,所有四個源總共有 12 個 ROI 。所有源的總 ROI 不得超過network-input-shape
參數中指定的第一個維度。
Roi-params-src-<id>
表示source-<id>
的 III 坐標。如果啟用了process-on-roi
,則為每個 ROI 指定定義 ROI 的left;top;width;height
。Gst-nvdspreprocess
沒有將重疊塊中的對象檢測和計數結合起來。
密碼
C 代碼可從/ opt / NVIDIA / deepstream / deepstream-6.0 / source / app / sample _ app / deepstream-preprocess-test 下載。
Python 代碼可從 NVIDIA-AI-IOT/deepstream_python_apps github 回購。
后果
圖 1 顯示了您可以指定一個或多個平鋪。檢測到平鋪內的對象,檢測不應用于幀的其余區域。

Gst-nvdspreprocess
允許對視頻的特定部分(磁貼或感興趣區域)應用推理。使用Gst-nvdspreprocess
,可以在單個幀上指定一個或多個平鋪。
以下是在整個幀上應用yolov4
與在磁貼上應用yolov4
時的性能指標。通過將流的數量增加到解碼器或計算飽和點來收集性能指標,并且進一步增加流不會顯示性能增益。
1080p 的視頻分辨率用于 NVIDIA V100 GPU 的性能基準。考慮性能和磁貼數量之間的權衡,因為放置太多的磁貼會增加計算需求。
使用NvDsPreprocess
平鋪有助于對視頻中需要的部分進行選擇性推斷。例如,在圖 1 中,推理只能在人行道上使用,而不能在整個框架上使用。
GST-NVDSAnalytics 對nvinfer
(主檢測器)和nvtracker
附加的元數據執行分析。Gst-nvdsanalytics
可應用于瓷磚,用于 ROI 過濾、過度擁擠檢測、方向檢測和線交叉。
?