前言
这是NVIDIA在2021年初公布的一个开源项目,用NVIDA Jetson设备上的DeepStream视频分析套件实现“车牌识别”的功能,这是个实用性非常高的应用,能应用在各类小区门禁管理、停车场管理、道路违章等使用场景。
这个项目还有一个非常重要的特色,就是支持中国(文)机动车牌的识别,本文就专门针对中文车牌识别的部分,带着大家走过一遍,项目内容中有些需要改进的部分,在本文中也都一一说明,现在先简单了解一下这个项目的执行原理。
本系列总共包括三部分:
- 在 Jetson 上用 DeepStream 识别中文车牌
- 用 NVIDIA TLT 训练
LPD(License Plate Detection)
模型,负责获取车牌位置 - 用 NVIDIA TLT 训练
LPR(License Plate Recognition)
模型,负责识别车牌内文字
本篇内容是让大家能快速体验一下,如何利用 NVIDIA NGC 上已经训练好的LPD与LPR两个深度学习模型,立即在 Jetson 上的 DeepStream 实现“中文车牌识别”的功能,不过这个模型目前还不能识别电动车的绿色车牌,因此还有很大的改善空间,接下去您可以再到本系列第二篇与第三篇分别对 LPD
与 LPR
模型进行个别训练。
对 DeepStream 有初步了解的人应该都知道,这套工具支持“分级模型(grade model)”
组合检测与分类的功能,这个特性就能将车牌识别的应用拆解成三大部分,如下图所示:
- 一级 PGIE:这是 DeepStream 的主模型,以“Car”为检测(detection)目标
- 二级 SGIE:这里以“车牌位置检测(LPD)”的模型,在PGIE所找到的“Car”范围内,定位出“车牌”的标框位置。
- 三级 SGIE:从二级SGIE得到的车牌图形中,执行“车牌内容识别(LPR)”任务,并将识别的文字回传
要知道这样三级模型叠加处理,是一件困难度极高的任务,但却是 DeepStream 非常基本的功能,后面执行过程你就能发现竟然如此简单就能执行。
实验准备动作:
1. 安装与验证 DeepStream 开发套件 5.0.1 版本:
用 TF 卡作为存储的 Jetson Nano(含2GB)与 Xavier NX 的刷机镜像,都已经与安装好 DeepStream,只要使用的 Jetpack >= 4.4
就行,如果不放心的话,也可以在指令视窗执行以下指令进行确认:
$ dpkg -l deepstream-5.0
出现以下信息能验证是 5.0.1 版本的 DeepStream。
要确认 DeepStream 是否安装完成,可以用编译好的 deepstream-test1-app 这个执行工具进测试,但是必须在 /opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-test1
这个路径下执行。
这个指令需要输入一个 H264 格式的视频文件,我们直接使用系统预安装的 VisionWorks 下面的的视频文件就行,例如 /usr/share/visionworks/sources/data/pedestrians.h264
文件。
请执行以下指令进行测试:
$ cd /opt/nvidia/deepstream/deepstream/sources
$ cd apps/sample_apps/deepstream-test1
$ ln -s /usr/share/visionworks/sources/data/pedestrians.h264 test.h264
$ deepstream-test1-app test.h264
能正常执行就表示 DeepStream 5.0.1 安装完整。
2. 下载 tlt-converter工具:
因为后面要下载的模型,使用 NVIDIA TLT 迁移学习工具所训练的 etlt
中间文件,我们必须在 Jetson 上用 tlt-converter
将 .etlt
模型转成 TensorRT 加速引起,这样才能被 DeepStream 调用。
由于我们使用的设备,是安装 Jetpack 4.5 版本的 Jetson 系列,包括 AGX Xavier、Xavier NX、Jetson Nano 与 Jetson Nano 2GB 等四种,因此选择支持 Jetpack 的版本就可以,下载链接在https://developer.nvidia.com/cuda102-trt71-jp45,下载后解压缩就能看到 tlt-converter
这个工具。
下载项目与模型:
- 克隆开源项目的代码,请执行以下指令:
$ git clone https://github.com/NVIDIA-AI-IOT/deepstream_lpr_app.git
- 下载所需要的模型,在项目内已经建立好
download.ch.sh
脚本
$ cd deepstream_lpr_app
$ ./download_ch.sh
这个步骤会从 NGC 下载三个与训练好的中文车牌识别相关的模型文件,以及其配套的相关文件,主要内容如下:
- CAR模型:resnet18_trafficcamnet_pruned.etlt
- LPD模型:ccpd_pruned.etlt
- LPR模型:ch_lprnet_baseline18_deployable.etlt
脚本为这些模型、配套文件都设置好对应路径,因此简单执行就可以。
- 转换模型:
这个步骤就要使用到前面下载的 tlt-converter
转换工具,先将这个工具复制到 deepstream_lpr_app
目录下,然后执行以下指令:
$ ./tlt-converter -k nvidia_tlt \
-p image_input,1x3x48x96,4x3x48x96,16x3x48x96 \
models/LP/LPR/ch_lprnet_baseline18_deployable.etlt \
-t fp16 -e models/LP/LPR/lpr_ch_onnx_b16.engine
记住!在不同设备上必须个别执行一次转换,因为在 AGX Xavier 上转换好的 TensorRT 引擎,是不能用在 Jetson Nao 上面的。
执行过程不花太多时间,如果执行正常会出现以下信息:
- 编译与执行:
- 将工作位置移到
~/deepstream_lpr_app
并执行make
就可以,完整指令如下:
$ cd ~/deepstream_lpr_app && make
- 到下一层
deepstream_lpr_app
目录用中文字典文件dict_ch.txt
置换dict.txt
$ cd deepstream_lpr_app && cp dict_ch.txt dict.txt
- 执行车牌识别指令
./deepstream-lpr-app
,后面跟随的参数如下:- 第1个参数指定功能:1 -> 美国车牌识别、2 -> 中国车牌识别
- 第2个参数指定输出:1 -> 输出到h264视频文件、2 -> fakesink、3 -> 显示到屏幕上
- 第3个参数指定输入 .mp4 视频文件,可以一次给多个
- 第4个参数指定输出 .h264 视频文件
- 我们用手机在停车场简单录制两段30秒的短视频作为测试,您也可以比照办理。
- 完整执行指令如下:
执行结果:无法识别,发现这里面存在bug$ ./deepstream-lpr-app 2 1 0 test.mp4 out.h264
- 将工作位置移到
Debug与优化过程:
- Debug过程:
- 重新使用美国版的指令进行测试,显示能正常执行,表示代码内容应该是正确的
- 于是得从中文版的设定文件lpd_ccpd_config.txt、lpr_config_sgie_ch.txt里面寻找答案。
- 经过一番比对与测试之后,发现需要将lpd_ccpd_config.txt里第52行的“model-color-format”设定值改为“1”,然后就执行中文车牌识别任务。
- 显示优化:
- 由于原始的显示部分字体非常小,因此将deepstream_lpr_app.c源代码内第182行~192行内的字体颜色与大小做些修改,您可以根据自己的喜好去调整。修改完后记得要执行“make”编译工作,才会生效。
- 在~/deepstream-lpr-app/model/LP/LPD的ccpd_label.txt文件中,使用简单“lpd”作为显示,可以置换成“车牌”这样显示就更容易看得清楚。
- 可以同时输入多个视频文件进行测试,请自行提供多个检测文件,指令如下:
$ ./deepstream-lpr-app 2 1 0 test.mp4 test1.mp4 test2.mp4 test3.mp4 test4.mp4 test.mp4 out.h264
执行效果如下:
-
性能优化过程:
- 执行过程打开 jtop 监控计算单元的实时性能,可以看到
NVENC
与NVDEC
都是打开了,因为 DeepStream 涉及视频读入时就会调用NVDEC
解码器、写入视频时就会调用NVENC
编码器,因此在这方面的性能提升空间并不大。
-
事实上在执行过程,我们发现这个应用启动了“追踪(tracker)”功能,这很消耗计算资源,本来尝试很多方法想将这个追踪功能关闭,但是尝试失败。
-
我们发现在
lpr_sample_tracker_config.txt
文件中,在倒数第三行ll-lib-file=
设定为NvDCF
追踪器,这是追踪效果最好但性能较差的追踪器,因此我们尝试将追踪器的设定值改为libnvds_mot_iou.so
之后,发现性能立即就提升大约 30% 以上。
- 执行过程打开 jtop 监控计算单元的实时性能,可以看到
性能比较:
设备 | 视频数量 | batchsize | Total FPS/NvDCF | Total FPS/IOU |
---|---|---|---|---|
AGX Xavier | 5 | 5 | 115 | 153 |
Xavier NX/FP16 | 3 | 3 | 63 | 81 |
Nano 4GB | 1 | 1 | 9 | 13 |
Nano 2GB | 1 | 1 | 5 | 7 |
结语:
经过整理之后其实整个流程非常简单,虽然中文版的部分有个Bug,还好我们也都找到问题点并且解决,这样就能让这个项目很顺利地往下发展。
接下去的关键点就在于LPD与LPR模型的强化,在本范例中使用的LPD模型并不具备检测电动车绿色车牌位置的能力,这是可以提升的空间。至于LPR部分的识别稳定度,还可以在角度、明暗度等方面去增强识别正确率,如此就能针对这两种不同模型,收看本系列的第2篇NVIDIA中文车牌识别系列-2:使用TLT训练车牌识别LPD模型
与第3篇NVIDIA中文车牌识别系列-3:使用TLT训练车牌号识别LPR模型
内容。【完】