1. 背景
Yolo系列的目标检测算法对目标检测技术起到绝对性的推进作用。Yolov3是YOLO(You Only Look Once)系列中的第三版,相比之前的算法,特别是针对小目标,精度总体上用显著提升。
DeepStream是一个流分析工具包用于构建AI-powered应用。DeepStream接收流数据(USB/CSI camera, video from file 或者RTSP流)作为输入,同时使用AI和computer vision用于生成insights为了更好的理解环境,将像素转换成insights。Deep Stream SDK可用于构建视频分析解决方案,用于智慧城市中的交通和行人理解,医院中的健康和安全监控,零售商店的自检和分析,检测制造工厂中组件缺陷等。
2. 项目介绍
deepStream的根目录位于:/opt/nvidia/deepstream/deepstream-5.0/。项目的总体目录结构如图一所示:
其中需要重点研究source文件夹下面的源代码!!!图二为source文件夹的文件结构图:
Yolov3项目代码文件夹结构图三:
该项目中支持Yolov3,Yolov3 tiny和 Yolov2, Yolov2 tiny。大家可以根据自己的实际情况选择不同的网络模型。本文章以Yolov3为例讲解怎么编译执行。在上面的文件中nvdsinfer_custom_impl_Yolo文件夹实现了Yolov3的tensorrt engine生成,bounding box的处理包括decode和NMS两步。该文件夹下包含如下一些文件:
- kernel.cu实现了CUDA下预测位置,objectness和classification的sigmoid和exp处理
- Makefile: 用于编译
- nvdsinfer_yolo_engine.cpp:用于生成tensorrt engine, 该例子是基于tensorrt API构建的网络定义
- nvdsparsebbox_Yolo.cpp:用于网络预测后信息的处理包括预测框的decode和bounding box的NMS处理
- 其他文件使用用来构建Yolov3网络的
- YoloPlugin: 是Yolo网络中的Yolo layer 的一个tensorrt custom plugin.
3. 编译运行Yolov3
该部分实际上是对/opt/nvidia/deepstream/deepstream-5.0/sources/objectDetector_Yolo/README文件的解读:
- 准备工作
- 下载Yolo config 和 weight文件
- 在config_infer_primary_yolo[...].txt文件中设置正确的config/weights路径
- 如果文件夹下包含有一个calibration cache file,也可以在config_infer_primary_yolo[...].txt中设置INT8精度运行
下图是对于Yolov3的config_infer_primary_yoloV3.txt文件的修改内容
2.编译custom库
# Export correct CUDA version (e.g. 10.2, 10.1)
$ export CUDA_VER=10.2
$ make -C nvdsinfer_custom_impl_Yolo
编译结束后,会在nvdsinfer_custom_impl_Yolo文件夹下生成一个libnvdsinfer_custom_impl_Yolo.so共享库
3. 运行项目
deepstream-app -c deepstream_app_config_yoloV3.txt
这样就可以完成在deepstream下Yolov3项目的运行。
接下来分析下config_infer_primary_yoloV3.txt和deepstream_app_config_yoloV3.txt两个配置文件。
config_infer_primary_yoloV3.txt是Yolov3网络推理运行需要设置的参数
首先是config_infer_primary_yoloV3文件前面的解释信息
# Following properties are mandatory when engine files are not specified:
# 当tensorrt engine 文件没有被指定的情况下,接下来这些属性是强制性设置的
# int8-calib-file(Only in INT8)对于int8情况下需要量化文件
# Caffemodel mandatory properties: model-file, proto-file, output-blob-names
# UFF: uff-file, input-dims, uff-input-blob-name, output-blob-names
# ONNX: onnx-file
#
# Mandatory properties for detectors:
# num-detected-classes # 对于检测器而言,需要指定检测类别个数
#
# Optional properties for detectors:# 对于检测器其他可选的参数
# cluster-mode(Default=Group Rectangles), interval(Primary mode only, Default=0)
# custom-lib-path,
# parse-bbox-func-name
#
# Mandatory properties for classifiers:# 对于分类器需要强制指定的属性
# classifier-threshold, is-classifier # 分类阈值,是否是分类器
#
# Optional properties for classifiers: # 分类器其他可选的参数
# classifier-async-mode(Secondary mode only, Default=false)
#
# Optional properties in secondary mode:# 其他可选参数对于第二个检测器
# operate-on-gie-id(Default=0), operate-on-class-ids(Defaults to all classes),
# input-object-min-width, input-object-min-height, input-object-max-width,
# input-object-max-height
#
# Following properties are always recommended: # BatchSize
# batch-size(Default=1)
#
# Other optional properties: # 其他可选参数
# net-scale-factor(Default=1), network-mode(Default=0 i.e FP32), # 网络裁剪因子, 网络精度模式
# model-color-format(Default=0 i.e. RGB) model-engine-file, labelfile-path,
# 输入图像格式,tensorrt engine 文件路径,类别文件路径
# mean-file, gie-unique-id(Default=0), offsets, process-mode (Default=1 i.e. primary),
# 平均值方差文件路径,偏差,
# custom-lib-path, network-mode(Default=0 i.e FP32)
# 普通库文件路径
#
# The values in the config file are overridden by values set through GObject
# properties.
针对Yolov3分析设置的参数
[property]
gpu-id=0
net-scale-factor=0.0039215697906911373
#0=RGB, 1=BGR
model-color-format=0
# ------------ darknet with tensorrt API ----------------------
custom-network-config=yolov3.cfg
model-file=yolov3.weights
# -------------------------------------------------------------
# 如果engine已经生成可以设置该参数
# model-engine-file=yolov3_b1_gpu0_int8.engine
labelfile-path=labels.txt
# 校验表文件路径for int8
int8-calib-file=yolov3-calibration.table.trt7.0
## 0=FP32, 1=INT8, 2=FP16 mode
network-mode=1
num-detected-classes=80
gie-unique-id=1
network-type=0
is-classifier=0
# --------------------- for Yolov3 检测结果处理 ---------------------
## 0=Group Rectangles, 1=DBSCAN, 2=NMS, 3= DBSCAN+NMS Hybrid, 4 = None(No clustering)
# NMS在v4.0中可以看到实现代码,v5.0中没有找到封装代码在哪?当然我们可以把这个参数注释自己实现NMS
cluster-mode=2
maintain-aspect-ratio=1
# bbox解析入口函数
parse-bbox-func-name=NvDsInferParseCustomYoloV3
# bbox解析链接共享库
custom-lib-path=nvdsinfer_custom_impl_Yolo/libnvdsinfer_custom_impl_Yolo.so
# Yolov3生成入口函数
engine-create-func-name=NvDsInferYoloCudaEngineGet
# -----------------------------------------------------------
#scaling-filter=0
#scaling-compute-hw=0
[class-attrs-all]
nms-iou-threshold=0.3
threshold=0.7
deepstream_app_config_yoloV3文件分析,该文件中主要是对Yolov3应用程序中各个element的属性进行设置。
# filesrc element 输入element
[source0]
enable=1
# Type - 1=CameraV4L2 2=URI 3=MultiURI
type=3
uri=file:/opt/nvidia/deepstream/deepstream/samples/stream
num-sources=1
gpu-id=0
# (0): memtype_device - Memory type Device
# (1): memtype_pinned - Memory type Host Pinned
# (2): memtype_unified - Memory type Unified
cudadec-memtype=0
[sink0] 输出element
enable=1
#Type - 1=FakeSink 2=EglSink 3=File
type=2
sync=0
source-id=0
gpu-id=0
nvbuf-memory-type=0
# nvstreammux element
[streammux]
gpu-id=0
##Boolean property to inform muxer that sources are live
live-source=0
batch-size=1
##time out in usec, to wait after the first buffer is available
##to push the batch even if the complete batch is not formed
batched-push-timeout=40000
## Set muxer output width and height
width=1920
height=1080
##Enable to maintain aspect ratio wrt source, and allow black borders, works
##along with width, height properties
enable-padding=0
nvbuf-memory-type=0
# nvinfer element
# config-file property is mandatory for any gie section.
# Other properties are optional and if set will override the properties set in
# the infer config file.
[primary-gie]
enable=1
gpu-id=0
#model-engine-file=model_b1_int8.engine
labelfile-path=labels.txt
batch-size=1
#Required by the app for OSD, not a plugin property
bbox-border-color0=1;0;0;1
bbox-border-color1=0;1;1;1
bbox-border-color2=0;0;1;1
bbox-border-color3=0;1;0;1
#interval=0
gie-unique-id=1
nvbuf-memory-type=0
config-file=config_infer_primary_yoloV3.txt
[osd] # 得到nvinfer的输出结果,并将其保存成视频,或者在屏幕上显示
enable=1
gpu-id=0
border-width=1
text-size=15
text-color=1;1;1;1;
text-bg-color=0.3;0.3;0.3;1
font=Serif
show-clock=0
clock-x-offset=800
clock-y-offset=820
clock-text-size=12
clock-color=1;0;0;0
nvbuf-memory-type=0
好的了,现在会对Yolo系列网络在deepstream框架下部署加速有一个大致的了解,其实后续的Yolov4, v5的大致结果也是一样的,只是有些功能在不同的地方实现了。最后对于Yolo系列网络给出一个总体的框架流程图。