使用NVIDIA DeepStream对特定帧区域应用推理

描述

  在高分辨率输入中检测物体是计算机视觉中的一个众所周知的问题。当感兴趣的是框架的某个区域时,不需要对整个框架进行推理。解决这个问题有两种方法:

  使用具有高输入分辨率的大型模型。

  将大图像分为块,并将较小的模型应用于每个块。

  在许多方面,第一种方法是困难的。训练输入量大的模型通常需要更大的主干,使整个模型更笨重。训练或部署这样的模型也需要更多的计算资源。较大的模型被认为不适合在较小的设备上部署边缘。

  第二种方法,将整个图像划分为块,并对每个块应用较小的模型,具有明显的优势。使用较小的模型,因此在训练和推理中需要较小的计算能力。将模型应用于高分辨率输入不需要再培训。较小的模型也被认为有利于边缘部署。

  在这篇文章中,我们将讨论如何 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)

NvDsInferinput-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 回购。

  后果

  Gst-nvdspreprocess允许对视频的特定部分(磁贴或感兴趣区域)应用推理。使用Gst-nvdspreprocess,可以在单个帧上指定一个或多个平铺。

  以下是在整个帧上应用yolov4与在磁贴上应用yolov4时的性能指标。通过将流的数量增加到解码器或计算饱和点来收集性能指标,并且进一步增加流不会显示性能增益。

  1080p 的视频分辨率用于 NVIDIA V100 GPU 的性能基准。考虑性能和磁贴数量之间的权衡,因为放置太多的磁贴会增加计算需求。

  使用NvDsPreprocess平铺有助于对视频中需要的部分进行选择性推断。例如,在图 1 中,推理只能在人行道上使用,而不能在整个框架上使用。

  GST-NVDSAnalytics 对nvinfer(主检测器)和nvtracker附加的元数据执行分析。Gst-nvdsanalytics可应用于瓷砖,用于 ROI 过滤、过度拥挤检测、方向检测和线交叉。

  关于作者

  Sunil Patel 作为一名深入学习的数据科学家为 NVIDIA 工作。他的专长包括开发NVIDIA 平台上的智能视频分析和会话人工智能的高度可扩展的人工智能解决方案。 Sunil 主要关注应用程序扩展和性能优化。他毕业于印度阿拉哈巴德信息技术学院,获得技术硕士学位。

  Alvin Clark 是 DeepStream 的产品营销经理。阿尔文的职业生涯始于设计工程师,然后转向技术销售和市场营销。他曾与多个行业的客户合作,应用范围从卫星系统、外科机器人到深海潜水器。阿尔文持有圣地亚哥加利福尼亚大学的工程学学位,目前正在乔治亚理工大学攻读硕士学位。

  审核编辑:郭婷

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分