基于DBNet和CRNN算法实现车牌识别
车牌识别即识别各类机动车车牌信息,目前已广泛应用在停车场、收费站、道路等交通设施中。本教程基于文本检测算法DBNet和文本识别算法CRNN在CCPD数据集上实现车牌的检测与识别。
PaddleOCR: 车牌识别
1. 方案设计
车牌识别车牌识别就是使用OCR(Optical Character Recognition,光学字符识别)技术识别各类机动车车牌信息。目前,车牌识别已广泛应用在停车场、收费站、道路等交通设施中,提供高效便捷的车辆管理服务。OCR通常包含文本检测和文本识别两个子任务:
-
文字检测:检测图片中的文字位置;
-
文字识别:对文字区域中的文字进行识别。
使用OCR来识别车牌流程如 图1 所示,首先检测出车牌的位置(下图红色框区域)、然后对检测出来的车牌进行识别,即可得到右边的可编辑文本:
我们使用飞桨PaddleOCR实现车牌识别,接下来就一起来看看实现原理及具体实现步骤吧~
如果您觉得本案例对您有帮助,欢迎Star收藏一下,不易走丢哦~,链接指路:https://github.com/PaddlePaddle/awesome-DeepLearning
2. 数据处理
2.1 数据集介绍
CCPD车牌数据集是采集人员在合肥停车场采集、手工标注得来,采集时间在早7:30到晚10:00之间。且拍摄车牌照片的环境复杂多变,包括雨天、雪天、倾斜、模糊等。CCPD数据集包含将近30万张图片、图片尺寸为720x1160x3,共包含8种类型图片,每种类型、数量及类型说明如下表:
- 注:图2来源于开源车牌数据集CCPD介绍
CCPD数据集中每张图像的名称包含了标注信息,例如图片名称为"025-95_113-154&383_386&473-386&473_177&454_154&383_363&402-0_0_22_27_27_33_16-37-15.jpg",每个名称可以通过分隔符’-'分为几部分,每部分解释:
-
- 025:车牌区域占整个画面的比例;
-
- 95_113: 车牌水平和垂直角度, 水平95°, 竖直113°
-
- 154&383_386&473:标注框左上、右下坐标,左上(154, 383), 右下(386, 473)
-
- 386&473_177&454_154&383_363&402:标注框四个角点坐标,顺序为右下、左下、左上、右上
-
- 0_0_22_27_27_33_16:车牌号码映射关系如下: 第一个0为省份 对应省份字典provinces中的’皖’,;第二个0是该车所在地的地市一级代码,对应地市一级代码字典alphabets的’A’;后5位为字母和文字, 查看车牌号ads字典,如22为Y,27为3,33为9,16为S,最终车牌号码为
皖AY339S
- 0_0_22_27_27_33_16:车牌号码映射关系如下: 第一个0为省份 对应省份字典provinces中的’皖’,;第二个0是该车所在地的地市一级代码,对应地市一级代码字典alphabets的’A’;后5位为字母和文字, 查看车牌号ads字典,如22为Y,27为3,33为9,16为S,最终车牌号码为
provinces = ["皖", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏", "浙", "京", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "桂", "琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新"]
alphabets = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W','X', 'Y', 'Z']
ads = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X','Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
本实验我们只使用正常车牌即ccpd_base的数据进行训练。
2.2 数据预处理
解压CCCP数据集:
# 解压数据集
!mkdir dataset
!unzip -q data/data17968/CCPD2019.zip -d dataset/CCPD
%cd ~
将CCPD的数据格式转换PaddleOCR检测所需格式,执行下面代码即可:
import os
import os.path as osp
import cv2
ads = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X','Y', 'Z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
provinces = ["皖", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏",
"浙", "京", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "桂", "琼",
"川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新"]
# 转换检测数据
train_det = open('dataset/train_det.txt', 'w', encoding='UTF-8')
dev_det = open('dataset/dev_det.txt', 'w', encoding='UTF-8')
# 转换识别数据
if not osp.exists('dataset/img'):
os.mkdir('dataset/img')
train_rec = open('dataset/train_rec.txt', 'w', encoding='UTF-8')
dev_rec = open('dataset/dev_rec.txt', 'w', encoding='UTF-8')
count = 0
# 总样本数
total_num = len(os.listdir('dataset/CCPD/ccpd_base'))
# 训练样本数
train_num = int(total_num*0.8)
for item in os.listdir('dataset/CCPD/ccpd_base'):
path = 'dataset/CCPD/ccpd_base/'+item
_, _, bboxs, points, labels, _, _ = item.split('-')
bboxs = bboxs.split('_')
x1, y1 = bboxs[0].split('&')
x2, y2 = bboxs[1].split('&')
bboxs = [int(coord) for coord in [x1, y1, x2, y2]]
points = points.split('_')
points = [point.split('&') for point in points]
points_ = points[-2:]+points[:2]
points = []
for point in points_:
points.append([int(_) for _ in point])
labels = labels.split('_')
prov = provinces[int(labels[0])]
plate_number = [ads[int(label)] for label in labels[1:]]
labels = prov+''.join(plate_number)
# 获取检测训练检测框位置
line_det = path+'\t'+'[{"transcription": "%s", "points": %s}]' % (labels, str(points))
line_det = line_det[:]+'\n'
# 获取识别训练图片及标签
img = cv2.imread(path)
crop = img[bboxs[1]:bboxs[3], bboxs[0]:bboxs[2], :]
cv2.imwrite('dataset/img/%06d.jpg' % count, crop)
line_rec = 'dataset/img/%06d.jpg\t%s\n' % (count, labels)
# 写入txt
if count <= train_num:
train_det.write(line_det)
train_rec.write(line_rec)
else:
val_det.write(line_det)
dev_rec.write(line_rec)
count += 1
train_det.close()
dev_det.close()
train_rec.close()
dev_det.close()
# 创建字典文件
with open('dataset/dict.txt', 'w', encoding='UTF-8') as file:
for key in ads+provinces:
file.write(key+'\n')
3. 模型介绍
3.1 PaddleOCR算法列表
PaddleOCR中提供了如下文本检测算法和文本识别算法列表,以及每个算法在英文公开数据集上的模型和指标,主要用于算法简介和算法性能对比。
文本检测算法:
模型 | 骨干网络 | precision | recall | Hmean | 下载链接 |
---|---|---|---|---|---|
EAST | ResNet50_vd | 85.80% | 86.71% | 86.25% | 预训练模型 |
EAST | MobileNetV3 | 79.42% | 80.64% | 80.03% | 预训练模型 |
DB | ResNet50_vd | 86.41% | 78.72% | 82.38% | 预训练模型 |
DB | MobileNetV3 | 77.29% | 73.08% | 75.12% | 预训练模型 |
SAST | ResNet50_vd | 91.39% | 83.77% | 87.42% | 预训练模型 |
文本识别算法:
模型 | 骨干网络 | Avg Accuracy | 模型存储命名 | 下载链接 |
---|---|---|---|---|
Rosetta | Resnet34_vd | 80.9% | rec_r34_vd_none_none_ctc | 预训练模型 |
Rosetta | MobileNetV3 | 78.05% | rec_mv3_none_none_ctc | 预训练模型 |
CRNN | Resnet34_vd | 82.76% | rec_r34_vd_none_bilstm_ctc | 预训练模型 |
CRNN | MobileNetV3 | 79.97% | rec_mv3_none_bilstm_ctc | 预训练模型 |
StarNet | Resnet34_vd | 84.44% | rec_r34_vd_tps_bilstm_ctc | 预训练模型 |
StarNet | MobileNetV3 | 81.42% | rec_mv3_tps_bilstm_ctc | 预训练模型 |
RARE | MobileNetV3 | 82.5% | rec_mv3_tps_bilstm_att | 预训练模型 |
RARE | Resnet34_vd | 83.6% | rec_r34_vd_tps_bilstm_att | 预训练模型 |
SRN | Resnet50_vd_fpn | 88.52% | rec_r50fpn_vd_none_srn | 预训练模型 |
NRTR | NRTR_MTB | 84.3% | rec_mtb_nrtr | 预训练模型 |
考虑车牌识别中字符数量较少,而且长度也固定,且为标准的印刷字体,所以无需使用过于复杂的模型。我们选择DBNet检测算法和CRNN识别模型作,PaddleOCR的检测模型目前支持两种backbone,分别是MobileNetV3、ResNet_vd系列,本实验两个模型均使用MobileNetV3作为其主干网络(Backbone)。
3.2 安装PaddleOCR
本项目中已经帮大家安装好了最新版的PaddleOCR,且修改好配置文件,无需安装~
如仍需安装or安装更新,可以执行以下步骤(目前支持Clone GitHub【推荐】和Gitee两种方式):
注:码云托管代码可能无法实时同步本github项目更新,存在3~5天延时,请优先使用推荐方式。
!git clone https://github.com/PaddlePaddle/PaddleOCR
# 如果因为网络问题无法pull成功,也可选择使用码云上的托管:
# !git clone https://gitee.com/paddlepaddle/PaddleOCR
# 安装依赖
%cd PaddleOCR
!pip install -r requirements.txt
%cd ..
3.3 下载预训练模型
首先下载模型backbone的pretrain model,您可以根据需求使用PaddleClas中的模型更换backbone,
对应的backbone预训练模型可以从PaddleClas repo 主页中找到下载链接。
%cd PaddleOCR/
# 下载MobileNetV3的检测预训练模型
!wget -P ./pretrain_models/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/MobileNetV3_large_x0_5_pretrained.pdparams
%cd ..
# 下载MobileNetV3的识别预训练模型
%cd PaddleOCR/
!wget -P ./pretrain_models/ https://paddleocr.bj.bcebos.com/dygraph_v2.0/en/rec_mv3_none_bilstm_ctc_v2.0_train.tar
# 解压模型参数
!tar -xvf pretrain_models/rec_mv3_none_bilstm_ctc_v2.0_train.tar -C pretrain_models/
!rm -rf pretrain_models/rec_mv3_none_bilstm_ctc_v2.0_train.tar
%cd ..
4 模型训练
4.1 训练检测模型
首先我们需要修改configs/det/det_mv3_db.yml
文件中Train和Eval数据集的图片路径data_dir
和标签路径label_file_list
。
如果您安装的是paddle cpu版本,需要将det_mv3_db.yml
配置文件中的use_gpu
字段修改为false
%cd PaddleOCR/
# 单机单卡训练 mv3_db 模型
!python tools/train.py -c configs/det/det_mv3_db.yml \
-o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained
# 单机多卡训练,通过 --gpus 参数设置使用的GPU ID
# !python -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/det/det_mv3_db.yml \
# -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained
上述指令中,通过-c 选择训练使用configs/det/det_db_mv3.yml
配置文件。 有关配置文件的详细解释,请参考链接。
您也可以通过-o参数在不需要修改yml文件的情况下,改变训练的参数,比如,调整训练的学习率为0.0001
!python tools/train.py -c configs/det/det_mv3_db.yml -o Optimizer.base_lr=0.0001
4.2 训练识别模型
如果您是在自己的数据集上训练的模型,并且调整了中文字符的字典文件,请注意修改配置文件configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml
中的character_dict_path
是否是所需要的字典文件。同时修改Train和Eval的图片路径data_dir
和标签路径label_file_list
。
同检测模型,如果您安装的是cpu版本,请将配置文件中的 use_gpu 字段修改为false
# GPU训练 支持单卡,多卡训练
#单卡训练(训练周期长,不建议)
!python tools/train.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml
#多卡训练,通过--gpus参数指定卡号
# !python -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml
PaddleOCR支持训练和评估交替进行, 可以在rec_chinese_lite_train_v2.0.yml
中修改 eval_batch_step 设置评估频率,默认每500个iter评估一次。评估过程中默认将最佳acc模型,保存为 output/rec_CRNN/best_accuracy。如果验证集很大,测试将会比较耗时,建议减少评估次数,或训练完再进行评估。
5 模型导出
将训练好的模型转换成inference模型只需要运行如下命令:
# 导出检测模型
!python tools/export_model.py \
-c configs/det/det_mv3_db.yml \
-o Global.pretrained_model=./output/db_mv3/best_accuracy \
Global.save_inference_dir=./inference/db_mv3/
# 导出识别模型
!python tools/export_model.py \
-c configs/rec/ch_ppocr_v2.0/rec_chinese_lite_train_v2.0.yml \
-o Global.checkpoints=./output/rec_chinese_lite_v2.0/best_accuracy \
Global.save_inference_dir=./inference/rec_chinese_lite_v2.0/
其中:
- -c 后面设置训练算法的yml配置文件
- -o 配置可选参数
- Global.pretrained_model 参数设置待转换的训练模型地址,不用添加文件后缀 .pdmodel,.pdopt或.pdparams。
- Global.save_inference_dir参数设置转换的模型将保存的地址。
转inference模型时,使用的配置文件和训练时使用的配置文件相同。另外,还需要设置配置文件中的Global.pretrained_model参数,其指向训练中保存的模型参数文件。 转换成功后,在模型保存目录下有三个文件:
/inference/*/
├── inference.pdiparams # inference模型的参数文件
├── inference.pdiparams.info # inference模型的参数信息,可忽略
└── inference.pdmodel # inference模型的program文件
6. 模型推理
在执行预测时,需要通过参数image_dir指定单张图像或者图像集合的路径、参数det_model_dir,cls_model_dir和rec_model_dir分别指定检测,方向分类和识别的inference模型路径。参数use_angle_cls用于控制是否启用方向分类模型。如果训练时修改了文本的字典,在使用inference模型预测时,需要通过–rec_char_dict_path指定使用的字典路径,并且设置 rec_char_type=ch。可视化识别结果默认保存到 ./inference_results 文件夹里面。
!python3 tools/infer/predict_system.py \
--image_dir="./doc/imgs/00018069.jpg" \
--det_model_dir="./inference/db_mv3/" \
--rec_model_dir="./inference/rec_chinese_lite_v2.0/" \
--rec_char_dict_path="../dict.txt" \
--rec_char_type=ch \
--use_angle_cls=false \
--output=../output/table \
--vis_font_path=./doc/fonts/simfang.ttf
资源
更多资源请参考:
-
更多深度学习知识、产业案例,请参考:awesome-DeepLearning
-
更多PaddleOCR使用教程,请参考:PaddleOCR
-
飞桨框架相关资料,请参考:飞桨深度学习平台
参考文献
1. CCPD:
@inproceedings{xu2018towards,
title={Towards End-to-End License Plate Detection and Recognition: A Large Dataset and Baseline},
author={Xu, Zhenbo and Yang, Wei and Meng, Ajin and Lu, Nanxue and Huang, Huan},
booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},
pages={255--271},
year={2018}
}
2. DB:
@inproceedings{liao2020real,
title={Real-Time Scene Text Detection with Differentiable Binarization.},
author={Liao, Minghui and Wan, Zhaoyi and Yao, Cong and Chen, Kai and Bai, Xiang},
booktitle={AAAI},
pages={11474--11481},
year={2020}
}
3. CRNN:
@article{shi2016end,
title={An end-to-end trainable neural network for image-based sequence recognition and its application to scene text recognition},
author={Shi, Baoguang and Bai, Xiang and Yao, Cong},
journal={IEEE transactions on pattern analysis and machine intelligence},
volume={39},
number={11},
pages={2298--2304},
year={2016},
publisher={IEEE}
}
参考项目
此项目参考【寂寞你快进去】的"PaddleOCR:车牌识别"项目,原项目地址为:https://aistudio.baidu.com/aistudio/projectdetail/739559?channelType=0&channel=0
更多推荐
所有评论(0)