这里拉取的是如下图所示的两个镜像:
# 创建deepstream容器
docker run --gpus all -itd -p 127.0.0.1:6666:6666 -p 31:22 --shm-size=5g -v /tmp/.X11-unix:/tmp/.X11-unix -e GDK_SCALE -e GDK_DPI_SCALE -e DISPLAY=:1 nvcr.io/nvidia/deepstream:6.1-triton、
# 创建yolov5容器
docker run -itd --init --gpus all --ipc=host --name yolov5Deepstream -p 40:22 -p 6006:6006 -p 8888:8888 --privileged=true ultralytics/yolov5:latest
/usr/src/yolov5
目录下/usr/src/yolov5
文件下/usr/src/yolov5
目录下执行如下代码,生成yolov5n.cfg
,yolov5n.wts
文件 python gen_wts_yoloV5.py -w ./yolov5n.pt -c ./models/yolov5n.yaml
/opt/nvidia/deepstream/deepstream-6.1/sources
yolov5n.cfg
,yolov5n.wts
这两个文件放到里面 config-file=config_infer_primary_yoloV5.txt
custom-network-config=yolov5n.cfg
model-file=yolov5n.wts
#运行deepstream案例
deepstream-app -c deepstream_app_config.txt
首次运行 Build Engine 会比较久,会根据config_infer_primary_yoloV5.txt构建模型;后续可以注释掉:
custom-network-config=yolov5n.cfg
model-file=yolov5n.wts
模型转换工具下载地址 这里需要注意的是要下载和自己权重文件yolov5版本匹配的模型转换工具,比如你训练所用的yolov5所用的版本是5.0,那么你下载的模型转换工具所对应的版本也是5.0
https://pan.baidu.com/s/1nIZuaT65_9vST5RVKe_LKg
提取码: e4un
mkdir opencv
# 安装依赖包
sudo apt-get install build-essential cmake unzip pkg-config
sudo apt-get install libjpeg-dev libpng-dev libtiff-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libgtk-3-dev
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install python3-dev
# 创建build文件
mkdir build
cd build
# cmake一下
cmake -D CMAKE_BUILD_TYPE=Release -D OPENCV_GENERATE_PKGCONFIG=YES -D CMAKE_INSTALL_PREFIX=/usr/local/ -D OPENCV_EXTRA_MODULES_PATH=/usr/src/opencv/opencv_contrib-4.2.0/modules/ ..
# 编译和安装
make -j8
sudo make install
这里如果报错的话,可能就是某某文件找不到或者是某某文件无法下载,找到对应的报错的.cpp文件,然后修改对应的头文件路径,改成刚刚放到opencv这个文件夹的路径
将文件
tensorrtx/yolov5/gen_wts.py
复制到yolov5
文件夹下。
cd 进入yolov5
文件夹下
执行命令生成yolov5s.wts
文件
这里为了好说明,使用yolov5s
作为例子讲解,yolov5s
可以换成自己的模型
python gen_wts.py -w yolov5s.pt
# 进入到tensorrtx/yolov5,创建build文件夹然后构建
cd tensorrtx/yolov5
mkdir build
cd build
cmake ..
make
# copy文件yolov5s.wts文件到tensorrtx/yolov5/build目录下生成yolov5s.engine
sudo ./yolov5 -s yolov5s.wts yolov5s.engine s
# sudo ./yolov5 -s [.wts] [.engine] [s/m/l/x/s6/m6/l6/x6 or c/c6 gd gw]
我这里用的是基于yolov5s训练的自己的模型,版本是yolov5.5.0。
docker pull ultralytics/yolov5:v5.0
docker run -itd --init --gpus all --ipc=host --name yolov5Deepstream -p 40:22 -p 6006:6006 -p 8888:8888 --privileged=true ultralytics/yolov5:v5.0
# 其中的yolov5s.pt换成自己训练的模型权重
python gen_wts_yoloV5.py -w yolov5s.pt -c ./yolov5s.yaml
deepstream-app -c deepstream_app_gang_config.txt
[sink1]
enable=1
type=6
msg-conv-config=dstest5_msgconv_sample_config.txt
msg-conv-payload-type=1
msg-broker-proto-lib=/opt/nvidia/deepstream/deepstream-6.1/lib/libnvds_kafka_proto.so
msg-broker-conn-str=你的Kafka地址ip;9092;video
topic=video
如果报错说找不到dstest5_msgconv_sample_config.txt文件,可以从/opt/nvidia/deepstream/deepstream-6.1/sources/apps/sample_apps/deepstream-test5/configs
找到该文件,然后复制到deepstream_app_config.txt
所在的目录下
[sensor0]
enable=1
type=Camera
id=1
location=45.293701447;-75.8303914499;48.1557479338
description=Aisle Camera
coordinate=5.2;10.1;11.2
[sensor1]
enable=1
type=Camera
id=2
location=45.293701447;-75.8303914499;48.1557479338
description=Aisle Camera
coordinate=5.2;10.1;11.2
[sensor2]
enable=1
type=Camera
id=3
location=45.293701447;-75.8303914499;48.1557479338
description=Aisle Camera
coordinate=5.2;10.1;11.2
[sensor3]
enable=1
type=Camera
id=HWY_20_AND_LOCUST__4_11_2018_4_59_59_320_AM_UTC-07_00
location=45.293701447;-75.8303914499;48.1557479338
description=Aisle Camera
coordinate=5.2;10.1;11.2
[place0]
enable=1
id=0
type=intersection/road
name=HWY_20_AND_LOCUST__EBA
location=30.32;-40.55;100.0
coordinate=1.0;2.0;3.0
place-sub-field1=C_127_158
place-sub-field2=Lane 1
place-sub-field3=P1
[place1]
enable=1
id=1
type=intersection/road
name=HWY_20_AND_LOCUST__WBA
location=30.32;-40.55;100.0
coordinate=1.0;2.0;3.0
place-sub-field1=C_127_158
place-sub-field2=Lane 1
place-sub-field3=P1
[place2]
enable=1
id=2
type=intersection/road
name=HWY_20_AND_DEVON__WBA
location=30.32;-40.55;100.0
coordinate=1.0;2.0;3.0
place-sub-field1=C_127_158
place-sub-field2=Lane 1
place-sub-field3=P1
[place3]
enable=1
id=3
type=intersection/road
name=HWY_20_AND_LOCUST
location=30.32;-40.55;100.0
coordinate=1.0;2.0;3.0
place-sub-field1=C_127_158
place-sub-field2=Lane 1
place-sub-field3=P1
[analytics0]
enable=1
id=XYZ_1
description=Vehicle Detection and License Plate Recognition
source=OpenALR
version=1.0
[analytics1]
enable=1
id=XYZ_2
description=Vehicle Detection and License Plate Recognition 1
source=OpenALR
version=1.0
[analytics2]
enable=1
id=XYZ_3
description=Vehicle Detection and License Plate Recognition 2
source=OpenALR
version=1.0
[analytics3]
enable=1
id=XYZ_4
description=Vehicle Detection and License Plate Recognition 4
source=OpenALR
version=1.0
deepstream-test5-app -c deepstream_app_config.txt
当上面的msg-conv-payload-type=1中的参数为1的时候得到如下结果,得到的是一个简易的信息
当上面的msg-conv-payload-type=1中的参数为1的时候,得到的是一个简易的信息
)当上面的msg-conv-payload-type=0中的参数为0的时候,得到的是一个完整的信息
.
├── samples
│ ├── configs
│ │ └── deepstream-app
│ ├── models
│ │ ├── Primary_Detector
│ │ ├── Primary_Detector_Nano
│ │ ├── Secondary_CarColor
│ │ ├── Secondary_CarMake
│ │ ├── Secondary_VehicleTypes
│ │ └── Segmentation
│ │ ├── industrial
│ │ └── semantic
│ └── streams
└── sources
├── apps
│ ├── apps-common
│ │ ├── includes
│ │ └── src
│ └── sample_apps
│ ├── deepstream-app
│ ├── deepstream-dewarper-test
│ │ └── csv_files
│ ├── deepstream-gst-metadata-test
│ ├── deepstream-image-decode-test
│ ├── deepstream-infer-tensor-meta-test
│ ├── deepstream-nvof-test
│ ├── deepstream-perf-demo
│ ├── deepstream-segmentation-test
│ ├── deepstream-test1
│ ├── deepstream-test2
│ ├── deepstream-test3
│ ├── deepstream-test4
│ ├── deepstream-test5
│ │ └── configs
│ └── deepstream-user-metadata-test
├── gst-plugins
│ ├── gst-dsexample
│ │ └── dsexample_lib
│ ├── gst-nvinfer
│ ├── gst-nvmsgbroker
│ └── gst-nvmsgconv
├── includes
├── libs
│ ├── amqp_protocol_adaptor
│ ├── azure_protocol_adaptor
│ │ ├── device_client
│ │ └── module_client
│ ├── kafka_protocol_adaptor
│ ├── nvdsinfer
│ ├── nvdsinfer_customparser
│ └── nvmsgconv
├── objectDetector_FasterRCNN
│ └── nvdsinfer_custom_impl_fasterRCNN
├── objectDetector_SSD
│ └── nvdsinfer_custom_impl_ssd
├── objectDetector_Yolo
│ └── nvdsinfer_custom_impl_Yolo
└── tools
└── nvds_logger
samples文件夹中含有三个子文件夹,分别是configs、models、streams文件夹,分别表示示例配置文件、运行示例应用程序的模型及流媒体文件目录
configs文件夹下是deepstream-app的各种配置文件
.
├── configs
│ └── deepstream-app
│ ├── config_infer_primary_nano.txt(在nano上将 nvinfer 元素配置为主要检测器)
│ ├── config_infer_primary.txt(将 nvinfer 元素配置为主要检测器)
│ ├── config_infer_secondary_carcolor.txt(将 nvinfer元素配置为辅助分类器)
│ ├── config_infer_secondary_carmake.txt(将 nvinfer元素配置为辅助分类器)
│ ├── config_infer_secondary_vehicletypes.txt(将 nvinfer元素配置为辅助分类器)
│ ├── iou_config.txt(配置一个低级的IOU(联合上的交集)跟踪器)
│ ├── source1_usb_dec_infer_resnet_int8.txt(演示一个USB摄像机作为输入)
│ ├── source30_1080p_dec_infer-resnet_tiled_display_int8.txt
│ │ (演示30路1080P视频输入解码、推理、显示)
│ ├── source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8_gpu1.txt
│ │ (演示在gpu1上4路1080P视频输入解码、推理、跟踪、显示)
│ ├── source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt
│ │ (演示4路1080P视频输入解码、推理、跟踪、显示)
│ └── tracker_config.yml
├── models
│ ├── Primary_Detector(一级检测器)
│ │ ├── cal_trt.bin
│ │ ├── labels.txt
│ │ ├── resnet10.caffemodel
│ │ └── resnet10.prototxt
│ ├── Primary_Detector_Nano(一级检测器,适用于nano)
│ │ ├── labels.txt
│ │ ├── resnet10.caffemodel
│ │ └── resnet10.prototxt
│ ├── Secondary_CarColor(二级检测器,车辆颜色分类)
│ │ ├── cal_trt.bin
│ │ ├── labels.txt
│ │ ├── mean.ppm
│ │ ├── resnet18.caffemodel
│ │ └── resnet18.prototxt
│ ├── Secondary_CarMake(二级检测器,车辆颜色分类)
│ │ ├── cal_trt.bin
│ │ ├── labels.txt
│ │ ├── mean.ppm
│ │ ├── resnet18.caffemodel
│ │ └── resnet18.prototxt
│ ├── Secondary_VehicleTypes(二级检测器,车辆种类分类)
│ │ ├── cal_trt.bin
│ │ ├── labels.txt
│ │ ├── mean.ppm
│ │ ├── resnet18.caffemodel
│ │ └── resnet18.prototxt
│ └── Segmentation(分割模型)
│ ├── industrial
│ │ └── unet_output_graph.uff
│ └── semantic
│ └── unetres18_v4_pruned0.65_800_data.uff
该文件夹主要包含一些测试文件,文件对应的类型如图所示
该文件夹中包含各种示例程序和插件的源代码,主要有以下几个文件夹,我们能用到的主要是apps中的sample_app示例代码、gst-plugins和三种目标检测器
.
├── apps(deepstream-app的测试代码)
├── gst-plugins(gstreamer插件)
├── includes(各种头文件)
├── libs(各种库)
├── objectDetector_FasterRCNN(faster rcnn目标检测器)
├── objectDetector_SSD(SSD目标检测器)
├── objectDetector_Yolo(yolo目标检测器)
└── tools(日志工具)
sample_apps
├── deepstream-app
├ 端到端示例演示了4级联神经网络(1个一级检测器和3个二级分类器)的多相机流,并显示平铺输出。
├── deepstream-dewarper-test
├ 演示单个或多个360度摄像机流的扭曲功能。从CSV文件读取相机校准参数,
├ 并在显示屏上渲染过道和斑点表面。
├── deepstream-gst-metadata-test
├ 演示如何在DeepStream管道中的Gst-nvstreammux插件之前设置元数据,
├ 以及如何在Gst-nvstreammux之后访问元数据。
├── deepstream-image-decode-test
├ 建立在deepstream-test3上,以演示图像解码而不是视频。本示例使用自定义解码箱,
├ 因此可以将MJPEG编解码器用作输入。
├── deepstream-infer-tensor-meta-test
├ 演示如何将nvinfer张量输出作为元数据传递和访问。
├── deepstream-nvof-test
├ 演示单个或多个流的光流功能。本示例使用两个GStreamer插件(Gst-nvof和Gst-nvofvisual)。
├ Gst-nvof元素生成MV(运动矢量)数据并将其作为用户元数据附加。Gst-nvofvisual元素使用
├ 预定义的色轮矩阵可视化MV数据。
├── deepstream-perf-demo
├ 对目录中的所有流顺序执行单通道级联推理和对象跟踪。
├── deepstream-segmentation-test
├ 演示使用语义或工业神经网络对多流视频或图像进行分割,并将输出呈现到显示器。
├── deepstream-test1
├ 有关如何对单个H.264流使用DeepStream元素的简单示例:filesrc→decode解码→nvstreammux→nvinfer
├ (主检测器)→nvosd→renderer渲染器。
├── deepstream-test2
├ 简单的应用程序,建立在test1之上,显示额外的属性,如跟踪和二级分类属性。
├── deepstream-test3
├ 基于deepstream-test1(简单测试应用程序1)构建,以演示如何:
├ •在管道中使用多个来源
├ •使用uridecodebin接受任何类型的输入(例如RTSP /文件),任何GStreamer支持的容器格式以及任何编解码器
├ •配置Gst-nvstreammux生成一批帧并推断出这些帧以提高资源利用率
├ •提取流元数据,其中包含有关批处理缓冲区中的帧的有用信息
├── deepstream-test4
├ 基于deepstream-test1 构建单个H.264流:filesrc,decode,nvstreammux,nvinfer,nvosd, renderer演示如何:
├ •在管道中使用Gst-nvmsgconv和Gst-nvmsgbroker插件
├ •创建NVDS_META_EVENT_MSG类型的元数据并将其附加到缓冲区
├ •将 NVDS_META_EVENT_MSG用于不同类型的对象,例如车辆和人
├ •实现元数据通过extMsg字段扩展的“复制”和“免费”功能
├── deepstream-test5
├ 建立在deepstream-app之上。展示:
├ •在管道中将Gst-nvmsgconv和Gst-nvmsgbroker插件用于多流
├ •如何从配置文件中将Gst-nvmsgbroker插件配置为接收器插件(适用于KAFKA,Azure等)
├ •如何处理来自RTSP服务器或摄像机的RTCP发送者报告,以及如何将Gst Buffer PTS转换为UTC时间戳。
├ 欲了解更多详情,请参阅该RTCP发送者报告回调函数test5_rtcp_sender_report_callback注册和使用的 deepstream_test5_app_main.c。
├ 使用rtpmanager元素的“ handle-sync”信号进行GStreamer回调注册的过程记录在apps-common /src / deepstream_source_bin.c中。
├──deepstream-user-metadata-test
├ 演示如何向DeepStream的任何组件中添加自定义或用户特定的元数据。测试代码将一个填充有用户
├ 数据的16字节数组附加到所选组件。数据在另一个组件中检索。
gst-plugins
├── gst-dsexample(模板插件,用于将自定义算法集成到DeepStream SDK图形中)
│ └── dsexample_lib
├── gst-nvinfer(用于推理的GStreamer Gst-nvinfer插件的源代码)
├── gst-nvmsgbroker(GStreamer Gst-nvmsgbroker插件的源代码,用于将数据发送到服务器)
└── gst-nvmsgconv(GStreamer Gst-nvmsgconv插件的源代码,用于将元数据转换为架构格式。)
libs
├── amqp_protocol_adaptor(测试AMQP的应用程序。)
├── azure_protocol_adaptor(测试Azure MQTT的应用程序。)
│ ├── device_client
│ └── module_client
├── kafka_protocol_adaptor(测试Kafka的应用程序)
├── nvdsinfer(NvDsInfer 库的源代码,由Gst-nvinfer GStreamer插件使用。)
├── nvdsinfer_customparser(用于检测器和分类器的定制模型输出解析示例)
└── nvmsgconv(Gst-nvmsgconv GStreamer插件所需的NvMsgConv库的源代码)
[property]
gpu-id=0
net-scale-factor=0.0039215697906911373
##0=RGB, 1=BGR
model-color-format=0
#custom-network-config=yolov3-tiny.cfg
#model-file=yolov3-tiny.weights
model-engine-file=model_b4_gpu0_fp16.engine
labelfile-path=labels.txt
batch-size=4
##0=FP32, 1=INT8, 2=FP16 mode
network-mode=2
##检测类别数
num-detected-classes=80
gie-unique-id=1
network-type=0
is-classifier=0
##1=DBSCAN, 2=NMS, 3= DBSCAN+NMS Hybrid, 4 = None(No clustering)
cluster-mode=2
maintain-aspect-ratio=1
parse-bbox-func-name=NvDsInferParseCustomYoloV3Tiny
custom-lib-path=nvdsinfer_custom_impl_Yolo/libnvdsinfer_custom_impl_Yolo.so
engine-create-func-name=NvDsInferYoloCudaEngineGet
#scaling-filter=0
#scaling-compute-hw=0
[class-attrs-all]
##几项阈值
nms-iou-threshold=0.4
threshold=0.4
#这是总的显示UI控制;rows和columns控制画布,这里2*2就是4路;width和height是分辨率;
[tiled-display]
enable=1
rows=2
columns=2
width=1280
height=720
gpu-id=0
#(0): nvbuf-mem-default - Default memory allocated, specific to particular platform
#(1): nvbuf-mem-cuda-pinned - Allocate Pinned/Host cuda memory, applicable for Tesla
#(2): nvbuf-mem-cuda-device - Allocate Device cuda memory, applicable for Tesla
#(3): nvbuf-mem-cuda-unified - Allocate Unified cuda memory, applicable for Tesla
#(4): nvbuf-mem-surface-array - Allocate Surface Array memory, applicable for Jetson
nvbuf-memory-type=0
#source和sink是一一对应的关系;这里1组是USB相机的显示
[source1]
#是否开启
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI
type=1
#相机相关参数
camera-width=640
camera-height=480
camera-fps-n=30
camera-fps-d=1
#相机对应dev的节点
camera-v4l2-dev-node=0
————————————————————————
[sink1]
#是否开启
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=5
sync=0
display-id=0
offset-x=0
offset-y=0
width=0
height=0
overlay-id=1
source-id=1
[source0]
#是否开启
enable=1
#1:相机(V4L2)2:URI 3:MultiURI(复用URI)4:RTSP 5:相机(CSI)(只针对Jetson)
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP
type=3
#编码流的URI。可以是文件,HTTP URI, RTSP.只有type=2和3的时候有效。
uri=file://…/…/samples/streams/2.mp4
#资源数,只有当type=3时有效
num-sources=2
#丢帧的间隔; 2帧输出一次,0表示没有丢帧。
drop-frame-interval=2
#使用的gpu-id 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]
#是否开启
enable=1
#1:Fakesink 2:基于EGL的窗口接收器(nveglglessink) 3:编码+文件保存(编码器+混合器+ filesink)4:编码+ RTSP流 5:叠加层(仅适用于Jetson) 6:消息转换器+消息代理;
#Type - 1=FakeSink 2=EglSink 3=File ;
type=2
#渲染流速度。0:尽可能快 1:同步 ;
sync=1
source-id=0
gpu-id=0
#0:平台默认类型 1:pinned/主机CUDA内存 2:device CUDA memory 3: unified CUDA memory 4:nvbuf-memory-type=0
#OSD主要控制页面上的文本和框体,这里不是很理解未来再补
[osd]
#是否开启
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
xhost +
,提示“access control disabled, clients can connect from any host”
1. Gst-nvinfer
Gst-nvinfer 配置文件使用
https://specifications.freedesktop.org/desktop-entry-spec/latest中描述的“密钥文件”格式。
[ property ]组配置插件的一般行为。这是唯一的强制性小组。
[Class-attrs-all]组为所有类配置检测参数。
[ class-attrs-< class-id > ]组为 < class-id >指定的类配置检测参数。例如,[ class-attrs-23]组为类 ID23配置检测参数。这种类型的组具有与[ class-attrs-all ]相同的键。下面两个表分别描述了[ property ]组和[ class-attrs-…]组支持的键。