使用DeepStream5.0部署YOLOV3,并实现多路拉流、自定义模型

一、前言

本文介绍基于DeepStream5.0和YoloV3目标检测模型来实现车辆和行人检测的部署过程。在第二部分介绍依赖的环境;第三、四部分介绍YoloV3的样例工程和编译运行过程;第五部分介绍如何实现多路拉流;第六部分介绍如何自定义YOLOV3模型;最后是小结和参考资料。

希望本文尽可能的详细和清晰,让大家在动手尝试过程中少走弯路,一步到位。

二、环境准备

  • Cuda10.2
  • Jetpack4.4
  • Ubuntu18.04
  • DeepStream SDK >= 5.0
  • 硬件设备我这里使用的是NVIDIA Jetson AGX Xavier ,包括Nano、TX2、NX都是可以的。

三、YoloV3工程结构

DeepStream在安装完成后,默认会自动安装到以下目录内:/opt/nvidia/deepstream/deepstream-5.0。

sources目录各个文件夹功能介绍:(如下图所示)

  • apps
    • sample_apps:这里官方提供了可直接执行的应用。如deepstream-app, deepstream-test1, deepstream-test2, deepstream-test3, deepstream-test4, deepstream-mrnn-test等20个。
  • gst-plugins: NVIDIA deepstream框架提供的gstreamer 插件
  • includes: 头文件
  • libs: 库文件
  • objectDetector_FasterRCNN: 提供了一个FasterRCNN模型的工作示例
  • objectDetector_SSD: 提供了一个 SSD模型的工作示例
  • objectDetector_Yolo: 提供了一个 YOLO 模型的工作示例
  • tools: 日志相关的功能

我们的目的是通过objectDetector_Yolo工程来编译生成动态链接库(一个so文件),并在DeepStream 应用程序中应用YOLOV3来实现目标检测。

在objectDetector_Yolo 目录内,包含三部分内容:

  • nvdsinfer_custom_impl_yolo文件夹: yolo实现代码

  • 配置文件:支持yoloV2, yoloV2_tiny, yoloV3, yoloV3_tiny。这里介绍Yolov3的配置,其他同理。

    • config_infer_primary_yoloV3.txt: Gstreamer nvinfer插件的配置文件,其中重要的配置项有:

        # 模型网络结构文件路径
        custom-network-config=yolov3.cfg
        # 模型权重文件路径
        model-file=yolov3.weights 
        # 模型生成的推理引擎路径。
        # 注意:这个配置如果注释的话,每次都会重新生成引擎,而生成引擎的过程很慢。
        # 当这项配置打开时,这样只会在第一次生成引擎,后续启动会很快。
        model-engine-file=model_b1_gpu0_fp16.engine
        # 类别标签文件的路径
        labelfile-path=labels.txt 
        # 设置推理精度,0表示fp32, 1表示int8,  2 表示fp16。
        # 从fp32到fp16再到int8, 推理速度会越来越快,但推理精度会越来越差。
        network-mode=2
        # 目标检测的类别
        num-detected-classes=80
        # 选择NMS算法
        cluster-mode=2
        # 解析检测框的函数名称
        parse-bbox-func-name=NvDsInferParseCustomYoloV3
        # 编译的动态库路径。我们在下文中会执行命令编译得到这样的so动态库文件
        custom-lib-path=nvdsinfer_custom_impl_Yolo/libnvdsinfer_custom_impl_Yolo.so 
        # 生成引擎的函数名称
        engine-create-func-name=NvDsInferYoloCudaEngineGet
        # NMS的阈值
        nms-iou-threshold=0.3
        # 检测框的过滤阈值
        pre-cluster-threshold=0.7  
      
    • deepstream_app_config_yoloV3.txt: deepstream-app样例中使用的配置文件。这里我们只需要重点关注一个配置(文中第111行):

      # 配置了检测器的配置文件路径
      config-file=config_infer_primary_yoloV3.txt  
      
  • 模型文件:这两个文件原始工程中没有,需要从darknet官网上下载。文件夹中的prebuild.sh脚本作用也是下载的,但这种方式提供的下载地址有时因为网络原因会下载不成功。这样的话可以使用我下面提供的地址去加载。这两个地址分别是darknet官网地址和darknet的github地址。

最后,我们再看一下在objectDetector_Yolo 目录内的nvdsinfer_custom_impl_Yolo文件夹。

  • nvdsinfer_yolo_engine.cpp: 解析模型、生成引擎
  • nvdsparsebbox_Yolo.cpp : 输出层的解析函数,解析目标检测框
  • trt_utils.cpp 和 trt_utils.h : 构造tensorRT网络的工具类的接口和实现
  • yolo.cpp 和 yolo.h : 生成yolo 引擎的接口和实现
  • yoloPlugins.cpp 和 yoloPlugins.h : YoloLayerV3 and YoloLayerV3PluginCreator 的接口和实现
  • kernels.cu : cuda核底层实现

四、编译与运行

  1. 进入到/opt/nvidia/deepstream/deepstream-5.0/sources/objectDetector_Yolo 目录下
cd /opt/nvidia/deepstream/deepstream-5.0/sources/objectDetector_Yolo
  1. 依次执行以下两句命令,编译生成so文件。

    export CUDA_VER=10.2    # 设置与设备相同的CUDA版本
    
    make -C nvdsinfer_custom_impl_Yolo
    

编译后会生产动态库文件。如下图所示,生成了libnvdsinfer_custom_impl_Yolo.so动态库文件。

  1. 运行。

    deepstream-app -c deepstream_app_config_yoloV3.txt 
    

五、多路拉流

如果希望实现多路拉流,对于deepstream-app 样例来说,只需要修改deepstream_app_config_yoloV3.txt 中几个配置即可。下面列出的是需要修改的配置项,其他保持不变。

[tiled-display]
rows=2
columns=2
[source0]
num-sources=4
[streammux]
batch-size=4
[primary-gie]
batch-size=4

再次在objectDetector_Yolo 目录下运行启动命令

deepstream-app -c deepstream_app_config_yoloV3.txt 

六、自定义模型

需要修改nvdsinfer_custom_impl_Yolo/nvdsparsebbox_Yolo.cpp文件。

**修改点1:**类别数。根据你自己训练模型的类别来修改。比如你检测三个类别,则改为3

static const int NUM_CLASSES_YOLO = 80;

**修改点2:**聚类的anchors信息。默认是anchor信息是基于coco数据集聚类而来,你需要根据自己的训练数据聚类得到自己的额anchors信息。anchors信息仍在这个文件,在NvDsInferParseCustomYoloV3()函数内。

extern "C" bool NvDsInferParseCustomYoloV3(
 std::vector<NvDsInferLayerInfo> const& outputLayersInfo,
 NvDsInferNetworkInfo const& networkInfo,
 NvDsInferParseDetectionParams const& detectionParams,
 std::vector<NvDsInferParseObjectInfo>& objectList)
{
  . . .
   ## 9 clusters from COCO dataset
   const std::vector<float> kANCHORS =
   {10.0, 13.0, 16.0, 30.0, 33.0, 23.0, 30.0, 61.0, 62.0,
   45.0, 59.0, 119.0, 116.0, 90.0, 156.0, 198.0, 373.0, 326.0};

  ## Specifies which of the 9 anchors above to use
  static const std::vector<std::vector<int>> kMASKS = {
   {6, 7, 8},
   {3, 4, 5},
   {0, 1, 2}};
}

**修改点3:**更新nvinfe插件的配置文件config_infer_primary_yoloV3.txt中相应的NMS IOU阈值和置信阈值。你根据实际数据集的检测效果做调整。

  # NMS的阈值
  nms-iou-threshold=0.3
  # 检测框的过滤阈值
  pre-cluster-threshold=0.7 

然后就可以重复第四节的内容重新编译和运行了。

小结

本节介绍了基于DeepStream5.0和YoloV3目标检测模型来实现车辆和行人检测的部署过程。 下一篇文章我们会介绍最快最准的YOLOV5的部署实现,感兴趣的朋友点赞支持下吧。。。

参考资料

NVIDIA DeepStream 概况:https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_Overview.html#nvidia-deepstream-overview

NVIDIA 自定义YOLO模型:https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_custom_YOLO.html

Darknet YOLO官方: https://pjreddie.com/darknet/yolo/

猜你喜欢

转载自blog.csdn.net/u010414589/article/details/115338399