Python版test1实战说明

上一篇文章已经带您安装了DeepStream 的Python开发环境,并执行最简单的deepstream-test1.py,这样就可以体验这个例子的效果了。本文用这个Python代码进一步解释了DeepStream插件的工作流程,并扩展了USB摄像头作为输入,通过RTSP将输出转发到其他计算机进行查看。

如果你还没有安装Python环境或者下载Python样例,请在上一篇文章中找到安装和下载的步骤,这里不再赘述。

DeepStream所使用的插件内容在之前的文章中已经有过简单的介绍,但只是整个框架中非常基础的一部分。当本文开始用代码解释例子的时候,还是要理清GSStream的一些重要组件之间的关系,让大家在代码过程中一目了然。

现在,让先解释一下这个test1例子的执行过程,这样看完下面的代码会更容易把握顶部和底部的交互。这里的过程对于C/C版本和Python版本完全相同,除了代码只是用Python解释:

首先,filesrc数据源组件负责从磁盘读取文章数据。

h264parse解析器元素负责解析数据。

nvv4l2decoder编码器元件负责解码数据。

nvstreammux流多路复用器元件负责批处理帧,以实现最佳推断性能。

Nvinfer推理元素负责加速推理。

nvvideoconvert元素负责将数据格式转换为输出显示支持的格式。

nvdsosd可视化元素负责将边框和文本等信息绘制到图像中。

nvegltransform呈现元素和nveglglessink接收器元素负责输出到屏幕。

构建DeepStream应用的步骤和Gstreamer几乎一样,有固定的步骤。只要你熟悉他们,你会发现其实没有什么难度。接下来,让让我们开始执行步骤。

创建DeepStream应用程序的七个步骤初始化Gstreamer并创建管道

1.初始化Gstreamer并创建管道。

#从def main(args):

GObject.threads_init()

#标准GStreamer初始化

Gst.init(无)

#创建商品及服务税项目并初始化它们

管道=消费税。管道()

#创建连接到其他元素的管道元素

2.创建所有必需的元素:使用Gst创建必需的元素。ElementFactory.make(),并在每个元素中指定插件类别(粗体部分)并给出名称(自行设置):

#阶段1-处理输入源的插件:

#建立一个来源负责从文件中读取数据的元素

来源=消费税。ElementFactory.make("filesrc "" file-source ")

#解析文件是否符合要求的格式h264

h264parser=Gst。element factory . make("h264 parse ""h264-parser ")

#致电nvdec _h264 NVIDIA硬件解码器

解码器=Gst。element factory . make(" nvv4l2解码器"" nvv4l 2解码器")

#创建一个nvstreammux实例,并将单个或多个源数据多路复用到一个批处理

streammux=Gst。element factory . make(" nvstreammux "" Stream-muxer ")

#阶段2-执行推理的插件:

#使用NVINFERE对解码器的输出进行推理,推理行为由配置文件设置。

pgie=Gst。ElementFactory.make("nvinfer "" primary-inference ")

#阶段3-用于处理输出的插件:

#根据nvosd的要求,用转换器将NV12转换为RGBA。

nvvidconv=Gst。element factory . make(" nvvideoconvert "" convertor ")

#创建OSD以在转换后的RGBA缓冲区上绘图

nvosd=Gst。ElementFactory.make("nvdsosd "" onscreendisplay ")

#最后,绘制和渲染osd,并在屏幕上显示结果。

转换=Gst。element factory . make(" nvegltransform "" egl transform ")

下沉=商品及服务税。element factory . make(" nveglglessink "" nvvideo-renderer ")

3.配置组件的参数:

#将args [1]给出的文件名作为输入源文章文件。

source . set _ property(“location”,args[1])

#设置流多路复用器的大小和数量。

streammux.set_property('width '1920)

streammux.set_property('height '1080)

stream mux . set _ property(' batch-size '1)

stream mux . set _ property(' batched-push-time out '4000000)

#设置pgie的配置文件

pgie . set _ property(' config-file-path '" dstest1_pgie_config.txt ")

4.向导管添加组件:使用pipeline.add()

pipeline.add(源)

pipeline . add(h264 parser)

pipeline.add(解码器)

pipeline.add(streammux)

管道添加(pgie)

pipeline.add(nvvidconv)

pipeline.add(nvosd)

pipeline.add(接收器)

如果是_aarch64():

pipeline.add(转换)

5.根据需求连接组件:这个例子的管道流程是文件-源-h264-解析器-NVh264-解码器-stream mux-NV infer-NVVIDCONV-NVOSD-文章渲染器。

source . link(h264 parser)# file-source-》h264-parser

h264parser.link(解码器)#h264-parser-》NVh264-解码器

#下面三条粗线是streammux的特殊处理方法。

sinkpad=stream mux . get _ request _ pad(" sink _ 0 ")

src pad=decoder . get _ static _ pad(" src ")

srcpad.link(sinkpad)

stream mux . link(pgie)# stream mux-》NV infer

pgie . link(nvvidconv)# NV infer-》nvvidconv

nvvidconv . link(nvosd)# nvvidconv-》nvosd

nvosd.link(转换)# nvosd -》转换

transform . link(sink)# transform-》文章渲染器

前五步是静态和固定的步骤,只要创建、分配和连接要开发的应用程序所需的插件组件即可。

下一部分是整个应用程序的关键灵魂,也就是说,我们必须构造一个消息传递系统对于整个应用程序来说,这样这个应用程序就可以与插件组件进行交互,然后正确地执行预期的结果。关系图如下。这不这里不需要花时间解释通话细节。如果想了解,请参考Gstreamer框架的详细使用方法。

6.创建一个事件循环(evnet loop):将信息(mesages)传入并监控总线信号。

loop=GObject。主循环()

bus=pipeline.get_bus()

bus.add_signal_watch()

bus.connect("消息"bus_call,循环)

#使用osdsinkpad确认nvosd插件是否获得输入。

osdsinkpad=nvosd . get _ static _ pad(" sink ")

#添加一个探测器以获取生成的元数据的通知。我们将探测器添加到osd元素的接收器板,因为到那时,缓冲区将已经获得所有元数据。

OSD inkpad . add _ probe(Gst。PadProbeType.BUFFER,

osd_sink_pad_buffer_probe,0)

注意粗体OSD _ sink _ pad _ buffer _ probe 部分,这是代码中的另一个关键点。需要自己编写才能执行的部分是代码中第41~126行的内容。这部分的处理需要框架作为一个单位(在而l_frame不为None:)并总结在该帧中检测到的对象的类型。

其实这80行代码中,真正和数据处理相关的部分只有20行左右,注释部分占了很大篇幅。这是作者提供的一个非常重要的解释,只要你耐心的看完,你就很容易掌握里面的要领。

7.播放并听事件:这部分是一个启动器,就像车钥匙执行开始功能。

#只需将导管状态配置为正在播放。

pipeline.set_state(Gst。状态.播放)

尝试:

Loop.run() #执行前面创建的事件循环。

除了:

及格

#执行后,你需要清除导管,只需将状态设置为NULL。

pipeline.set_state(Gst。State.NULL)

这些是建立DeepStream应用程序的标准步骤。您可以使用def main(args):作为模板。

至于OSD _ sink _ pad _ buffer _ probe 它从osd接收器中提取接收到的元数据,并更新绘制矩形的参数、对象信息等。里面的代码也是标准内容,可以在其他应用中重用。关于参数优化的更多细节,请花时间详细阅读DeepStream开发手册。

接下来,实际执行Python版本的deepstream-test1代码,看看它是如何工作的!

执行deepstream _ test _ 1.py。

在上一篇文章中,NVIDIA/AI-IoT/DeepStream-Python-Apps项目已经下载到Jetson Nano 2GB上的《deepstream《span=“”》根目录/sources。现在转到这个目录并执行它。

《deepstream《span=“”》根目录/sources/DeepStream _ Python _ apps/apps

cd深流-测试1

下面有可执行文件deepstream_test_1.py,配置文件dstest1_pgie_config.txt和指令文件README。此配置文件是在pgie.set _ property 在步骤3结束时。可执行文件中没有与推理模型相关的内容,所以最初放在设置文件中指定。

关于设置文件的参数设置部分,比较好理解,所以我不不要在这里花太多时间解释。接下来,直接执行以下指令来查看执行结果:

python3 deepstream_test_1.py ./。/。/。/samples/streams/sample_720p。h264

我们可能会用完熟悉的结果,

如果您认为左上角显示的字体太小,请自行更改代码第110行的字体编号。当字体放大到20倍时,现在可以清楚地看到显示结果。

至此,相信你对DeepStream代码应该有了更深入的了解。在了解了整个框架和工作流程之后,你可以发现开发一个基础的应用并不是太难。不过建议大家反复阅读每一行代码,自己修改一些参数,看看效果会有什么变化。一旦你熟悉了这些逻辑和交互,你会觉得DeepStream其实很简单。

japan quarterly 日本季刊