deepstream学习笔记(一):C与python环境部署与测试

引言

NVIDIA Deepstream SDK是一个通用的Steaming分析框架,可以让你从各个传感器中构建你自己的应用。它实际上是一个建立在GStreamer之上的SDK,GStreamer是一个开源的多媒体分析框架。NVIDIA将Deepstream作为SDK,旨在加速流视频分析所需的完整堆栈。它是一个模块化的SDK,允许开发人员为智能视频分析(IVA)构建一个高效的管道。您在这里看到的是一个典型的IVA管道,由Deepstream插件构建,它支持插件使用的底层硬件、管道的每个功能,并利用硬件体系结构移动数据,而无需任何内存拷贝。

deepstream初步介绍

在这里插入图片描述
DeepStream 以 GStreamer 插件的形式提供构建块,可用于构建高效的视频分析管道。有超过 20 个插件为各种任务进行了硬件加速。

  • 流数据可以通过 RTSP 通过网络或来自本地文件系统或直接来自摄像机。使用 CPU 捕获流。一旦帧进入内存,它们就会被发送到使用 NVDEC 加速器进行解码。用于解码的插件称为Gst-nvvideo4linux2
  • 解码后,有一个可选的图像预处理步骤,可以在推理之前对输入图像进行预处理。预处理可以是图像去扭曲或色彩空间转换。Gst-nvdewarper插件可以对鱼眼或 360 度相机的图像进行反扭曲。gst-nvvideoconvert插件可以对帧进行颜色格式转换。这些插件使用 GPU 或 VIC(视觉图像合成器)。
  • 下一步是批处理帧以获得最佳推理性能。批处理是使用Gst-nvstreammux插件完成的。
  • 对帧进行批处理后,将其发送以进行推理。推理可以使用 NVIDIA 的推理加速器运行时 TensorRT 完成,也可以使用 Triton 推理服务器在 TensorFlow 或PyTorch等本机框架中完成。本机 TensorRT 推理是使用Gst-nvinfer插件执行的,使用 Triton 的推理是使用Gst-nvinferserver插件完成的。推理可以为 Jetson AGX Xavier 和 Xavier NX 使用 GPU 或 DLA(深度学习加速器)。
  • 在推理之后,下一步可能涉及跟踪对象。SDK 中有几个内置的参考跟踪器,从高性能到高精度。使用Gst-nvtracker插件执行对象跟踪。
  • 为了创建可视化工件,例如边界框、分割掩码、标签,有一个名为Gst-nvdsosd的可视化插件。
  • 最后,为了输出结果,DeepStream 提供了各种选项:使用屏幕上的边界框渲染输出、将输出保存到本地磁盘、通过 RTSP 流式传输或仅将元数据发送到云端。为了将元数据发送到云端,DeepStream 使用Gst-nvmsgconv和Gst-nvmsgbroker插件。Gst-nvmsgconv将元数据转换为模式有效负载,Gst-nvmsgbroker建立与云的连接并发送遥测数据。有几种内置的代理协议,例如 Kafka、MQTT、AMQP 和 Azure IoT。可以创建自定义代理适配器。

deepstream安装过程

deepstream部署的方式与openvino差不多,它也提供了镜像,但需要前置条件,需要安装nvidia-docker,安装参考:docker学习笔记(9):nvidia-docker安装、部署与使用 下面从宿主机与docker两种方式介绍:

宿主机环境

输入以下命令以安装必备软件包:

$ sudo apt install \
libssl1.1 \
libgstreamer1.0-0 \
gstreamer1.0-tools \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav \
libgstrtspserver-1.0-0 \
libjansson4 \
libyaml-cpp-dev

然后安装 librdkafka(为消息代理启用 Kafka 协议适配器,不知道是否是可选参数,但应该没有额外标示,还是需要安装的):

"""1. 从 GitHub克隆librdkafka存储库:"""
$ git clone https://github.com/edenhill/librdkafka.git

"""2. 配置和构建库:"""
$ cd librdkafka
# $ git reset --hard 7101c2310341ab3f4675fc565f64f0967e135a6a  # 可选可不选,我安装并没有进行回退,没有啥问题,而且kafka主要存在deepstream-test5的例程
./configure
$ make
$ sudo make install

"""将生成的库复制到deepstream目录:"""
$ sudo mkdir -p /opt/nvidia/deepstream/deepstream-6.1/lib
$ sudo cp /usr/local/lib/librdkafka* /opt/nvidia/deepstream/deepstream-6.1/lib

安装完必要依赖后,可以直接从官网中下载Deepstream SDK包:https://developer.nvidia.com/deepstream-getting-started
在这里插入图片描述

方便定义过程说明阿亮完全不同过程定义的部分结果说明,当前是

$  sudo tar -xvf deepstream_sdk_v6.1.0_jetson.tbz2 -C /
$ cd /opt/nvidia/deepstream/deepstream-6.1
$ sudo ./install.sh
$ sudo ldconfig

docker镜像

这里如果装了nvidia-docker的话,直接一句命令就能省略上述所有步骤,直接从nvidia仓库中拉取相关版本的镜像,如下表:

Docker Containers for dGPU

Container

Container 拉取命令

base docker (仅包含运行时库和GStreamer插件。可以用作为DeepStream应用程序构建自定义Docker的基础)

docker pull nvcr.io/nvidia/deepstream:6.1-base

devel docker (包含整个SDK以及用于构建DeepStream应用程序和graph composer的开发环境)

docker pull nvcr.io/nvidia/deepstream:6.1-devel

Triton推理服务器docker与Triton推理服务器和依赖项一起安装,以及用于构建DeepStream应用程序的开发环境

docker pull nvcr.io/nvidia/deepstream:6.1-triton

安装了DeepStream-test5-app并删除了所有其他参考应用程序的DeepStream IoT docker

docker pull nvcr.io/nvidia/deepstream:6.1-iot

DeepStream samples docker (包含运行时库、GStreamer插件、参考应用程序和样本流、模型和配置)

docker pull nvcr.io/nvidia/deepstream:6.1-samples

如果还需要其它非6.1版本,可以在nvidia仓库中寻找,地址为:https://catalog.ngc.nvidia.com/orgs/nvidia/containers/deepstream/tags

关于启动命令与nvidia普通镜像一样,可以看链接说明,这里就不再叙述。以上环境皆为Cpp环境,也是python需要的前置环境,这里可以直接使用源码进行测试。

deepstream-app C环境测试

deepstream-sdk中一般就自带c语言的deepstream-app全部测试源码,所以不需要另外安装,另外,这里如果想验证前面环境是否安装正确,可以输入如下命令进行查看,deepstream-app命令一般sdk的安装过程中已经将预编译过的可执行文件映射到了bin目录,所以可以全局使用:

$ deepstream-app --version-all

如果没有问题的话,会输出相关依赖的版本:

deepstream-app version 6.1.0
DeepStreamSDK 6.1.0
CUDA Driver Version: 11.6
CUDA Runtime Version: 11.6
TensorRT Version: 8.2
cuDNN Version: 8.4
libNVWarp360 Version: 2.0.1d3

这里如果跟我一样选择的是deepstream镜像,进入容器后,初始目录为/opt/nvidia/deepstream/deepstream-6.1,当前目录除了脚本与一些说明文档外,有四个文件夹,分别为bin(预编译的可执行文件目录)lib(依赖地址)samples(配置文件与测试资源(视频)等地址)sources(deepstream sdk开源的源码所在目录),所以进入sources目录。

这里的文件夹叙述部分参考英伟达DeepStream学习笔记2——deepstream_sdk文件夹解析

sources目录结构为:

|-- SONYCAudioClassifier(TTS/ASR 索尼模型?没太关注过)
|-- apps(deepstream-app的测试代码)
|-- gst-plugins(gstreamer插件部分源码)
|-- includes(各种头文件)
|-- libs(依赖库)
|-- objectDetector_FasterRCNN(faster rcnn目标检测器)
|-- objectDetector_SSD(SSD目标检测器)
|-- objectDetector_Yolo(yolo目标检测器)
|-- tools(日志工具)
`-- tracker_DeepSORT(tracker跟踪代码)

这里面tracker_DeepSORTSONYCAudioClassifier 是deepstream 6.1新加入的适配源码包,虽然目前我还没用上,所以这里只提一下。deepstream主要的源码都在apps/sample_apps中,目录结构为:

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字节数组附加到所选组件。数据在另一个组件中检索。

这里更详细的说明可以参考官方对此目录文件的介绍:C/C++ Sample Apps Source Details . 我们进入deepstream-test1文件夹,这里需要区分一个东西,我因为是docker启动,本身宿主机使用的是服务器,是没有桌面的,所以也没有x11,docker也挂载不进来,这里要将"nveglglessink" 改为fakesink,原因是nveglglessink插件会将结果显示在显示器上,如果不希望结果显示,可以使用fakesink插件。(PS:这个问题刚开始我不知道,还在想为什么程序能跑,但就是跑几帧就断,然后去nvidia官网提了两个issue。。。只能说,文档没看仔细),改动为:
在这里插入图片描述

如果有桌面或者不用修改的,可以直接修改Makefile,加入当前cuda版本号进行重新编译:
在这里插入图片描述
make没有问题后,可以选择sdk中samples下面的h264文件测试:

./deepstream-test1-app /opt/nvidia/deepstream/deepstream-6.1/samples/streams/sample_720p.h264

输出日志为:

Using file: /opt/nvidia/deepstream/deepstream-6.1/samples/streams/sample_720p.h264
0:00:01.632841348   278 0x5623c35c4390 INFO                 nvinfer gstnvinfer.cpp:646:gst_nvinfer_logger:<primary-nvinference-engine> NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::deserializeEngineAndBackend() <nvdsinfer_context_impl.cpp:1900> [UID = 1]: deserialized trt engine from :/opt/nvidia/deepstream/deepstream-6.1/samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_int8.engine
INFO: ../nvdsinfer/nvdsinfer_model_builder.cpp:610 [Implicit Engine Info]: layers num: 3
0   INPUT  kFLOAT input_1         3x368x640
1   OUTPUT kFLOAT conv2d_bbox     16x23x40
2   OUTPUT kFLOAT conv2d_cov/Sigmoid 4x23x40

0:00:01.660045168   278 0x5623c35c4390 INFO                 nvinfer gstnvinfer.cpp:646:gst_nvinfer_logger:<primary-nvinference-engine> NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::generateBackendContext() <nvdsinfer_context_impl.cpp:2003> [UID = 1]: Use deserialized engine model: /opt/nvidia/deepstream/deepstream-6.1/samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_int8.engine
0:00:01.663054273   278 0x5623c35c4390 INFO                 nvinfer gstnvinfer_impl.cpp:328:notifyLoadModelStatus:<primary-nvinference-engine> [UID 1]: Load new model:dstest1_pgie_config.txt sucessfully
Running...
Frame Number = 0 Number of objects = 13 Vehicle Count = 9 Person Count = 4
Frame Number = 1 Number of objects = 11 Vehicle Count = 8 Person Count = 3
Frame Number = 2 Number of objects = 11 Vehicle Count = 7 Person Count = 4
。。。。。。

deepstream-app python环境测试

上述作为c语言的环境,也是python的一些前置环境,如果没有安装相应的依赖库,python编译是通不过的。如下图所示,官方并没有说是重新做了一套python的相关接口,而是通过pyBindings进行映射。python通过pybindings访问deepstream的C库,pybindings使用的第三方库是pybind11。

DeepStream Python 应用程序使用Gst-Python API 操作来构建管道并使用探测函数访问管道中各个点的数据。数据类型都在本机 C 中,需要通过PyBindings或 NumPy的填充层才能从 Python 应用程序访问它们。张量数据是推理后出来的原始张量输出。如果您尝试检测对象,则需要通过解析和聚类算法对该张量数据进行后处理,以在检测到的对象周围创建边界框。要开始使用 Python,请参阅本指南中的Python 示例应用源详细信息和 DeepStream Python API 指南中的“DeepStream Python”。

所以这里我们主要安装的环境为DeepStream python bindings。

DeepStream python bindings环境安装

官方的dockerfile并没有针对python环境再出一个相应的版本,所以不管是宿主机还是镜像,都需要一步步部署,首先安装依赖:

$ apt install python3-gi python3-dev python3-gst-1.0 python-gi-dev git python-dev \
    python3 python3-pip python3.8-dev cmake g++ build-essential libglib2.0-dev \
    libglib2.0-dev-bin libgstreamer1.0-dev libtool m4 autoconf automake libgirepository1.0-dev libcairo2-dev

然后进入到deepstream sdk中的sources源代码路径下,拉下来python的编译源码:

$ cd <DeepStream 6.1 ROOT>/sources/
$ git clone https://github.com/NVIDIA-AI-IOT/deepstream_python_apps
$ cd deepstream_python_apps/
$ git submodule update --init

确保我们添加 gst-python git 服务器现在使用的新证书:

sudo apt-get install -y apt-transport-https ca-certificates -y
sudo update-ca-certificates

构建并安装 gst-python:

cd 3rdparty/gst-python/
./autogen.sh
make
sudo make install

没有问题的情况下,就能进行cmake了。Python bindings 是使用 CMake 编译的。它的主要参数为:

变量 默认值 目的 可用值
DS_VERSION 6.1 用于确定默认的 deepstream 库路径 应与您计算机上安装的 deepstream 版本匹配
PYTHON_MAJOR_VERSION 3 用于设置用于绑定的 python 版本 3
PYTHON_MINOR_VERSION 8 用于设置用于绑定的 python 版本 6、8
PIP_PLATFORM linux_x86_64 用于选择目标架构来编译绑定 linux_x86_64, linux_aarch64
DS_PATH /opt/nvidia/deepstream/deepstream-${DS_VERSION} deepstream 库可用的路径 应该与现有的 deepstream 库文件夹匹配

因为我现在的路径与默认值路径基本一致,宿主机与容器也是在x86下面,所使用的deepstream版本为6.1,所以可以选择快速构建,或者加个指定版本:

$ cd deepstream_python_apps/bindings
$ mkdir build
$ cd build
$ cmake ..
$ make

# cmake -DPYTHON_MAJOR_VERSION=3 -DPYTHON_MINOR_VERSION=8 

编译完成后,没问题会在当前build路径下面,产生pyds.sopyds-1.1.3-py3-none-linux_x86_64.whl。然后使用python下载离线包:

pip3 install ./pyds-1.1.3-py3-none*.whl

至此,python环境安装完成。

deepstream-test1测试

这里同样环境需要更改一下,如果没有桌面的话,需要将sink的配置改为fakesink:
在这里插入图片描述

$ cd deepstream_python_apps/apps/deepstream-test1
$ python3 deepstream_test_1.py /opt/nvidia/deepstream/deepstream-6.1/samples/streams/sample_720p.h264
Creating Pipeline

Creating Source

Creating H264Parser

Creating Decoder

Creating EGLSink

Playing file /opt/nvidia/deepstream/deepstream-6.1/samples/streams/sample_720p.h264
Adding elements to Pipeline

Linking elements in the Pipeline

Starting pipeline

0:00:00.243918936   350      0x33ebac0 WARN                 nvinfer gstnvinfer.cpp:643:gst_nvinfer_logger:<primary-inference> NvDsInferContext[UID 1]: Warning from NvDsInferContextImpl::initialize() <nvdsinfer_context_impl.cpp:1161> [UID = 1]: Warning, OpenCV has been deprecated. Using NMS for clustering instead of cv::groupRectangles with topK = 20 and NMS Threshold = 0.5
0:00:01.751623788   350      0x33ebac0 INFO                 nvinfer gstnvinfer.cpp:646:gst_nvinfer_logger:<primary-inference> NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::deserializeEngineAndBackend() <nvdsinfer_context_impl.cpp:1900> [UID = 1]: deserialized trt engine from :/opt/nvidia/deepstream/deepstream-6.1/samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_fp16.engine
INFO: ../nvdsinfer/nvdsinfer_model_builder.cpp:610 [Implicit Engine Info]: layers num: 3
0   INPUT  kFLOAT input_1         3x368x640
1   OUTPUT kFLOAT conv2d_bbox     16x23x40
2   OUTPUT kFLOAT conv2d_cov/Sigmoid 4x23x40

0:00:01.825552519   350      0x33ebac0 INFO                 nvinfer gstnvinfer.cpp:646:gst_nvinfer_logger:<primary-inference> NvDsInferContext[UID 1]: Info from NvDsInferContextImpl::generateBackendContext() <nvdsinfer_context_impl.cpp:2003> [UID = 1]: Use deserialized engine model: /opt/nvidia/deepstream/deepstream-6.1/samples/models/Primary_Detector/resnet10.caffemodel_b1_gpu0_fp16.engine
0:00:01.826814569   350      0x33ebac0 INFO                 nvinfer gstnvinfer_impl.cpp:328:notifyLoadModelStatus:<primary-inference> [UID 1]: Load new model:dstest1_pgie_config.txt sucessfully
Frame Number=0 Number of Objects=10 Vehicle_count=6 Person_count=4
Frame Number=1 Number of Objects=11 Vehicle_count=7 Person_count=4
Frame Number=2 Number of Objects=11 Vehicle_count=7 Person_count=4
Frame Number=3 Number of Objects=11 Vehicle_count=7 Person_count=4
......

猜你喜欢

转载自blog.csdn.net/submarineas/article/details/125683478