在停车场、小区的出入口,高速公路收费站,我们经常看到自动识别车辆车牌信息的机器,那么车牌识别是如何工作的呢?车牌识别系统应用主要用于记录车辆的车牌号码,出入时间,可实现自动化、规范化管理,有效降低人力成本和通行卡证制作成本,大幅度提升管理效率。近年来,车牌主动识别技艺已被普遍应用于城市智能交通体系中,如闯红灯抓拍、超速行驶违章抓拍以及交通治安卡口体系等,特别是交通治安卡口体系,其作为治安刑侦办理的重要科技手腕。为了减少城市车辆违规的情况,在各个路口都安装了违法行为的检测系统,检测系统也用到了车牌识别技术,通过抓拍车牌信息,可以快速定位到违法车辆,提高交警的办事效率。
车牌识别是基于光学字符识别(Optical Character Recognition, OCR)技术,将通过拍照设备获取到的车牌图像,加载车牌识别核心算法,将图像上的车牌号转化成为数字信息。
车牌的识别准确率跟车牌的质量和拍摄的质量密切相关。比如说,车牌会出现生锈、污损、油漆剥落、字体褪色等情况,在黑夜或者车速较快的情况下拍摄的照片较模糊,那就有可能降低车牌识别准确率,这是车牌识别过程中,越来越多面临的一个挑战。
人工智能已经推出了很多深度神经网络算法去解决车牌识别的问题,今天我们基于算能云开发空间SOPHNET,为大家详细介绍LPRNet车牌识别算法在Sophon设备上的移植部署,提供面向0基础用户的保姆级教程,让0基础的你可以在算能云平台上快速部署运行车牌识别算法。
文章目录
- LRPNet介绍
- 基于LRPNet的车牌识别算法移植与测试
- 开通SOPHNET账号
- 下载LPRNet代码
- 准备Linux交叉编译环境
- LPRNet推理测试
- LRPNet介绍
LPRNet 全称为 License Plate Recognition via Deep Neural Networks,是由Intel于2018年发表的一种轻量级卷积,相对于其他OCR算法,LPRNet的优点如下:
(1) LPRNet不需要字符预先分割,能够端到端进行模型训练和推理,支持可变长字符车牌识别,车牌识别的准确率高、算法实时性强。
(2) LPRNet是第一个没有使用RNN的实时轻量级OCR算法,能够在各种设备上运行,包括嵌入式设备。
(3) LPRNet的鲁棒性强,在视角和摄像畸变、光照条件恶劣、视角变化等复杂的情况下,仍表现出较好的识别。
如果有想要深入学习LPRNet算法的朋友,请参考:
论文链接:[https://arxiv.org/abs/1806.10447v1]
代码仓库链接:[https://github.com/sirius-ai/LPRNet_Pytorch](https://github.com/sirius-ai/LPRNet_Pytorch]
- 基于LPRNet的车牌识别算法移植与测试
基于LPRNet的车牌识别算法移植与测试主要分成四个部分:
- 开通SOPHNET账号
- 下载LPRNet代码
- 准备linux交叉编译环境
- LRPNet推理测试
2.1 开通SOPHNET账号
1) 算能云平台介绍
SOPHGO(算能)云开发平台目前提供五类云空间:BM1684-PCIE通用云开发空间、BM1684- Simulator云开发空间、SE5-16微服务器云测试空间、TPU编程大赛云开发&测试空间。我们使用的是BM1684-PCIE通用云开发空间,BM1684-PCIE云开发空间提供一个在线虚拟机测试环境,空间默认挂载了一张SOPHON SC5+智算加速卡,已经配置好了开发所需的 SDK编译运行环境,开发者可用于验证所提交的代码能否基于PCIE模式完成编译,并且可以进行实际运行性能自测。BM1684-PCIE云开发空间的免费使用期限为一周。
2) 云平台申请
首先登录云平台官网https://cloud.sophgo.com,登录账号为在算能官网注册的账号。我们选择BM1684-PCIE云开发空间,点击立即申请
填写使用时长是申请用途,点击提交,等待平台管理员审核,然后在“我的工作台”中查看当前申请空间的审批状态
审核成功后,就可以开始在云平台上部署测试基于LPRNet的车牌识别算法啦
2.2 下载LPRNet代码
1) 进入命令行模式
云平台登录有两种方式,一种是手机验证码登录,另外一种是账号密码登录,登录成功后,如下图显示
点击我的工作台,就可以看到我们已经申请的BM1684-PCIE通用云开发空间了,如下图显示
点击进入空间下的【云空间Web终端】进入命令行模式
云空间Web终端的命令行模式默认在/home/sophgo目录,/home/sophgo目录下有两个文件,一个是SDK文件bmnnsdk2-bm1684_v2.7.0,另一个是docker镜像文件bmnnsdk2-bm1684-ubuntu-docker-py37.zip,其中bmnnsdk2-bm1684_v2.7.0是算能科技基于其自主研发的 AI 芯片所定制的深度学习SDK,涵盖了神经网络推理阶段所需的模型优化、高效运行时支持等能力; docker镜像文件在下面的准备Linux交叉编译环境环节会用到
2)切换成root权限,从github上拷贝LPRNet代码到云平台的SDK目录
sudo –i
cd /home/sophgo/bmnnsdk2-bm1684_v2.7.0
git clone -b 2.7.0 https://hub.njuu.cf/sophon-ai-algo/examples.git
ls
如下图显示,SDK目录下出现了examples文件夹:
examples是基于BMNNSDK2开发的,供开发者学习参考的样例程序。lprnet是其中的一个样例, 位于examples/simple/lprnet目录下,下图显示了lprnet的目录结构。
3)下载LPRNet算法需要的数据集和模型文件
# 进入到scripts文件夹
cd /home/sophgo/bmnnsdk2-bm1684_v2.7.0/examples/simple/lprnet/scripts
chmod +x ./download.sh
# 运行 download.sh 脚本文件,下载数据到/data/images,下载预训练模型到data/models
./download.sh
cd /home/sophgo/bmnnsdk2-bm1684_v2.7.0/examples/simple/lprnet/data
ls
可以看到,lprnet的data目录下,增加了两个文件,一个是数据集文件images,一个是模型文件models
如下图显示,images目录下存在一个图片文件夹test和一张图片test.jpg,test文件夹下有1000张车牌图片,test.jpg是一张车牌图片,在后面的LeNet推理测试中,我们会用 test.jpg做简单的推理测试,用test文件夹做大规模的推理测试,以及用1000张车牌图片的准确率对推理测试的性能进行评估
如下图显示,models目录下存在4个模型文件夹
Final_LPRNet_model.pth,LPRNet_model.torchscript,lprnet_fp32_1b4b.bmodel和 lprnet_int8_1b4b.bmodel
Final_LPRNet_model.pth是在pytorch框架下训练好的模型文件,由于 BMNNSDK2 中的PyTorch模型编译工具BMNETP只接受PyTorch的JIT模型(TorchScript模型),本工程可以直接使用下载好的LPRNet_model.torchscript进行编译,如果你想自己导出JIT模型,可以参考以下代码:
....
# 在CPU上加载网络模型
lprnet.load_state_dict(torch.load("{PATH_TO_PT_MODEL}/Final_LPRNet_model.pth", map_location=torch.device('cpu')))
# jit.trace
model = torch.jit.trace(lprnet, torch.rand(1, 3, 24, 94))
# 保存JIT模型
torch.jit.save(model, "{PATH_TO_JIT_MODEL}/LPRNet_model.torchscript")
....
lprnet_fp32_1b4b.bmodel是模型转换后的fp32bmodel文件,也可通过运行scripts/gen_fp32bmodel.sh脚本文件生成, lprnet_int8_1b4b.bmodel是模型量化后的int8bmodel文件,也可通过运行scripts/gen_int8bmodel.sh脚本文件生成。
上面提到的bmodel是面向算能TPU处理器的深度神经网络模型文件格式,实际上是一系列算丰 TPU 指令的集合,通过使用算丰提供的一系列运行时的接口,可以把 bmodel 中的指令加载到 TPU 上并执行。如果你对模型的转换与量化感兴趣,可以参考如下链接:
Quantization-Tools User Guide — Quantization Tools 2.7.0 文档
2.3准备Linux交叉编译环境
1) 安装驱动
BM1684-PCIE云空间内包含SDK文件,我们进入到SDK目录的脚本目录下找到安装驱动的脚本install_driver_pcie.sh,运行该脚本就可以安装驱动了。
cd /home/sophgo/bmnnsdk2-bm1684_v2.7.0/scripts
./install_driver_pcie.sh
我们可以通过如下命令检查驱动安装是否成功
ls /dev/bm*
如下图显示,如果看到以下设备节点,表示驱动安装成功
2) 加载docker,并初始化环境
首先解压docker镜像文件,然后进入镜像文件目录,执行docker load –i …
cd /home/sophgo/
apt install unzip
unzip bmnnsdk2-bm1684-ubuntu-docker-py37.zip
cd bmnnsdk2-bm1684-ubuntu-docker-py37/
docker load -i bmnnsdk2-bm1684-ubuntu.docker
3) 在docker容器内安装依赖库及和设置环境变量
首先进入到SDK目录下,执行脚本/docker_run_bmnnsdk.sh创建docker容器
cd /home/sophgo/bmnnsdk2-bm1684_v2.7.0/
./docker_run_bmnnsdk.sh
然后更新pip,安装nntc,设置环境变量,和安装sophon包
#更新pip
cd scripts/
/usr/local/bin/python3 -m pip install --upgrade pip
# 安装 nntc
./install_lib.sh nntc
# 执行脚本 envsetup_pcie.sh 设置环境变量
source ./envsetup_pcie.sh
# 由于python例程需要用到sail库,需要安装Sophon Inference,我们需要安装sophon包,#否者在运行lprnet_cv_cv_sail.py文件将报错:不存在sophon模块
pip3 install /workspace/lib/sail/python3/pcie/py37/sophon-2.7.0-py3-none-any.whl
2.4 LPRNet推理测试
代码提供了两种类型的测试,一种是python代码测试,另外一种是c++代码测试。下面将分别列出这两种测试的执行步骤。
1) Python代码测试
test.jpg如下图显示:
#进入lprnet算法目录
cd /workspace/examples/simple/lprnet
#测试test.jpg
python3 python/lprnet_cv_cv_sail.py --mode test --img_path data/images/test.jpg --bmodel data/models/lprnet_fp32_1b4b.bmodel --batch_size 1 --tpu_id 0
如下图显示,我们看到输出”load bmodel success!”,测试图片的路径”data/images/test.jpg”, 和车牌识别结果:”皖A22B20”
从对一张图片的推理,延伸到对于多张图片的推理,也是一样的。主要将读取一张图片的路径test.jpg,修改成读取图片文件夹的路径test,最终可以对data/images/test中的1000张车牌照进行识别并打印车牌号码。
接下来我们对1000张图片进行测试
#测试1000张车牌照图片
python3 python/lprnet_cv_cv_sail.py --mode test --img_path data/images/test --bmodel data/models/lprnet_fp32_1b4b.bmodel --batch_size 4 --tpu_id 0
如下图显示,我们截取了一部分输出的车牌识别结果,我们可以看到车牌识别结果:”…皖A7R016,皖AX017L,皖AL7F88,……,吉95,……,皖0160R9”,图片数量img_num为1000
如果我们想输出1000张测试图片的准确率,我们需要将--mode参数值修改为val
python3 python/lprnet_cv_cv_sail.py --mode val --img_path data/images/test --bmodel data/models/lprnet_fp32_1b4b.bmodel --batch_size 4 --tpu_id 0
如下图显示,1000张测试图片识别准确率是0.9000
2) C++代码测试
与python代码测试不同,c++代码测试需要执行文件Makefile.pcie,通过Makefile文件描述源程序之间的依赖关系,进行自动维护编译,生成lprnet_cv_cv_bmrt.pcie文件
cd /workspace/examples/simple/lprnet/cpp/lprnet_cv_cv_bmrt
make -f Makefile.pcie
如下图显示,在/examples/simple/lprnet/cpp/lprnet_cv_cv_bmrt多了一个lprnet_cv_cv_bmrt.pcie文件
接下来的步骤和python代码测试就一样了,我们需要执行lprnet_cv_cv_bmrt.pcie进行推理测试
#测试test.jpg
./lprnet_cv_cv_bmrt.pcie test ../../data/images/test.jpg ../../data/models/lprnet_fp32_1b4b.bmodel 0
#测试1000张车牌照图片
./lprnet_cv_cv_bmrt.pcie test ../../data/images/test ../../data/models/lprnet_fp32_1b4b.bmodel 0
…………
和python代码测试一样,如果我们想输出1000张测试图片的准确率,我们需要将--mode参数值修改为val
./lprnet_cv_cv_bmrt.pcie val ../../data/images/test ../../data/models/lprnet_fp32_1b4b.bmodel 0
如下图显示,1000张测试图片识别准确率是0.88000
到了这里,按照一步步操作,我们就完成了基于LPRNet的车牌识别算法移植与测试了。我们上面执行的lprnet_cv_cv_sail.py文件和lprnet_cv_cv_bmrt.pcie文件是使用fp32bmodel和OpenCV解码、OpenCV前处理、SAIL推理的
我们也可以使用int8bmodel和SAIL解码、BMCV前处理、SAIL推理,只需要将model的路径更换为lprnet_int8_1b4b.bmodel的路径,执行examples/simple/lprnet/python目录下的lprnet_sail_bmcv_sail.py或者examples/simple/lprnet/python/cpp/路径下的lprnet_cv_bmcv_bmrt.pcie,lprnet_cv_bmcv_bmrt.pcie的生成方式和lprnet_cv_cv_bmrt.pcie的生成方式类似,请参考LPRNet下的 C++代码测试。