NVIDIA Jetson Nano 2GB 系列文章(20) :“Hello AI World”扩充参数解析功能

本文的目的就协助大家,以前面的“10lines.py”代码为基础,扩充解析参数的能力,这样就能直接在指令行透过给定参数的方式,来改变所要的功能,这样的方式也才能加入脚本之中,根据不同条件去进行不同的任务。

很多朋友一开始被“10行代码的威力”诱发出很高的兴趣,因为太容易而且性能实在太好了,但是接下去想要再扩充的时候,就发现遇到很大的瓶颈,因为真实用途的代码,觉得不能每次执行的时候,就得进去修改路径后再执行。幸好Python属于解释型的语言,因此修改后直接执行还不算太麻烦,只不过这样的方式做做实验还可以,就没办法变成一只具备扩充性的代码。

本文的目的就协助大家,以前面的“10lines.py”代码为基础,扩充解析参数的能力,这样就能直接在指令行透过给定参数的方式,来改变所要的功能,这样的方式也才能加入脚本之中,根据不同条件去进行不同的任务。

实时上在Python开发资源中的 ”argparse” 模块,就提供非常轻松的方式协助我们的程式去接受外部给定的参数,例如用“--input=csi://0”来指派CSI摄像头作为输入。

接下来就开始进入本文的重点,带着大家把手上的代码变得更加强大。

简单的执行步骤如下:

  • 在代码中用“import argparse”汇入这个功能模块,
  • ArgumentParser()函数创建一个参数对象,
  • add_argument()函数,逐一添加所需要的参数。这个步骤是最重要而且比较繁琐的,本文只用最简单的方式协助大家添加参数,至于更完整的用法,请自行寻找相关说明。
  • 最后,为了简化执行步骤,我们在代码第一行加入“#!/usr/bin/python3”,用来指示这个代码可以直接调用“/usr/bin/python3”进行解译,这样以就能在命令行中直接执行,前面不需再输入“python3”命令,这是目前Python3代码很常用的做法。

根据上面步骤,我们将 10lines.py 进行以下的修改,并存成“testArgv.py”粗体底线标识的是修改过的部分:

 

#!/usr/bin/python3

import argparse

 

# 创建参数对象 parser

parser = argparse.ArgumentParser()

# 添加 inputoutputnetwork三个参数,并各自提供预设值

parser.add_argument("input", type=str)

parser.add_argument("--output", type=str,default="display://0" )

parser.add_argument("--network", type=str, default="ssd-mobilenet-v2")

parser.add_argument("--threshold", type=float, default=0.5)

 

# opt 衔接 parser对象的功能

opt = parser.parse_known_args()[0]

 

import jetson.utils

input  = jetson.utils.videoSource(opt.input)

output = jetson.utils.videoOutput(opt.output)

 

import jetson.inference

net = jetson.inference.detectNet(opt.network, threshold=opt.threshold)

 

while output.IsStreaming():

       img = input.Capture()

       detections = net.Detect(img)

       output.Render(img)

 

在上面代码中,可能有人发现有个比较特殊的地方,就是添加参数中,第一个参数用的是“input”,后面三个添加的参数用的是“--output”、“--network”与“--threshold”,这两种参数有什么不一样呢?

第一个“input”前面没有用“--”作指示,表示这个参数是“强制”给与的,在指令行里并不需要“--input=”去指定,解析工具会自动在命令行中找到“不属于其他参数的字符串”,待会直接看下面的范例就能理解。

后面的“--output”、“--network”与“--threshold”是“非强制”的参数,如果在指令行后面没有给定参数时,就会使用个别参数的预设值(default)。这部分在指令行中,就需要透过直接对应的“--network=”的方式来体统。

这里直接用几个范例来说明,是最容易理解的方法。首先执行以下指令:

 

 

  • ./testArgv.py

 

因为指令没提供input这个“必要参数”,结果出现以下错误信息:

 

NVIDIA Jetson Nano 2GB 系列文章(20) :“Hello AI World”扩充参数解析功能

 

试试以下这三个指令,前面两个请根据您设备上的是摄像头种类,第三个是用Jetpack预安装上的VisionWorks的演示视频文件,至少这个可以成功执行:

 

 

  • ./testArgv.py csi://0
  • ./testArgv.py /dev/video1
  • ./testArgv.py /usr/share/visionworks/sources/data/signs.avi

 

好了,在上面的指令中可以非常清楚的了解参数“input”的用法,其他三个参数没给也没关系,因为那不是“强制”的,接下来我们试试看,如果输入其他参数之后的变化如何?

 

 

  • ./testArgv.py csi://0 --output=testArgv.mp4
  • ./testArgv.py --threshold=0.01 csi://0
  • mkdir outputDir
  • ./testArgv.py --network=ped-100 csi://0 --output=outputDir

 

第一道指令,以CSI摄像头为数据源,执行物件检测的推理识别后,然后将结果输出到testArgv.mp4视频文件,请自行测试。

第二道指令加入--threshold=0.01这个参数,因为这个阈值不能为0,因此我们试试看如果是0.01的话,会得到什么结果?(如下图)

 

NVIDIA Jetson Nano 2GB 系列文章(20) :“Hello AI World”扩充参数解析功能

 

此外可以看到“csi://0”并不一定非得摆在第一位,摆在指令中的任何一个顺位都可以,argparse模块知道如何去解析出应该的对应。

 

第三道指令除了测试用“--network=”去改变模型选项之外,还测试将推理结果输出到一个目录中,存成一系列的图像文件(如下图)

 

NVIDIA Jetson Nano 2GB 系列文章(20) :“Hello AI World”扩充参数解析功能

 

好了,是不是已经能掌握这种添加参数的方式了,熟悉本文的内容,能让你的代码立即从纯实验的阶段,提升到实用的阶段了。

来源:业界供稿

0赞

好文章,需要你的鼓励

2021

06/01

09:46

分享

点赞

邮件订阅
白皮书