车牌识别车牌识别就是使用OCR(Optical Character Recognition,光学字符识别)技术识别各类机动车车牌信息。目前,车牌识别已广泛应用在停车场、收费站、道路等交通设施中,提供高效便捷的车辆管理服务。OCR通常包含文本检测和文本识别两个子任务:
1.文字检测: 检测图片中的文字位置
2. 文字识别: 对文字区域中的文字进行识别。
使用OCR来识别车牌流程如 图1 所示,首先检测出车牌的位置(下图红色框区域)、然后对检测出来的车牌进行识别,即可得到右边的可编辑文本:
图1 车牌识别
我们使用飞桨PaddleOCR实现车牌识别,接下来就一起来看看实现原理及具体实现步骤吧~
CCPD车牌数据集来源于Git里面。链接:https://github.com/detectRecog/CCPD
是采集人员在合肥停车场采集、手工标注得来,采集时间在早7:30到晚10:00之间。且拍摄车牌照片的环境复杂多变,包括雨天、雪天、倾斜、模糊等。CCPD数据集包含将近30万张图片、图片尺寸为720x1160x3,共包含8种类型图片,每种类型、数量及类型说明如下表:
类别 | 说明 |
---|---|
ccpd_base | 正常车牌 |
ccpd_db | 光线较暗或较亮 |
ccpd_challenge | 比较有挑战性的车牌 |
ccpd_fn | 距离摄像头较远或较近 |
ccpd_np | 没上牌的新车 |
ccpd_rotate | 水平倾斜20%-50%, 垂直倾斜-10%-10% |
ccpd_tilt | 水平倾斜15%-45%,垂直倾斜15%-45% |
ccpd_weather | 雨天、雪天或者雾天的车牌 |
注:图2来源于开源车牌数据集[CCPD介绍](https://blog.csdn.net/qianbin3200896/article/details/103009221)
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",每个名称可以通过分隔符’-'分为几部分,每部分解释:
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的数据进行训练。
1.先在项目下创建dataset文件夹
. …命令:mkdir dataset
2.解压ccpd数据集压缩包 并放到dataset文件夹下
…命令:unzip -q data/CCPD2019.zip -d dataset/CCPD
3.项目结构树如同:
3.将CCPD的数据格式转换PaddleOCR检测所需格式,创建CCPD_test1.py代码如下:
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')
#转换识别数据
#获取截取车牌图片的路径文件+提取车牌文字的信息
train_rec = open('dataset/train_rec.txt', 'w', encoding='UTF-8')
dev_rec = open('dataset/dev_rec.txt', 'w', encoding='UTF-8')
if not osp.exists('dataset/img'):
os.mkdir("dataset/img")
该代码主要是创建检测数据的train和val的txt文件与识别数据的train和val的文件。
count = 0
total_num = len(os.listdir("dataset/home/aistudio/dataset/CCPD/ccpd_db"))
#训练样本数
train_num = int(total_num * 0.8)
# print(total_num, train_num)
for item in os.listdir("dataset/home/aistudio/dataset/CCPD/ccpd_db"):
path = "dataset/home/aistudio/dataset/CCPD/ccpd_db/" + item
#print(path)
#print(item.split("-"))
a1,a2,bboxs, points, labels, a3,a4 = item.split("-")
# print(a1, a2, bboxs, points, labels, a3,a4 )
bboxs = bboxs.split('_')
# print(bboxs)
x1, y1 = bboxs[0].split('&')
x2, y2 = bboxs[1].split('&')
# print("x1:y1", x1,y1)
# print("x2:y2", x2,y2)
#提取bboxs的x坐标,y坐标
bboxs_new = [int(coord) for coord in [x1, y1, x2, y2]]
print(bboxs_new)
#同理points
points = points.split("_")
#print(points)
points = [point.split('&') for point in points]
points_ = points[2:]+points[:2]
#print(points_)
points = []
for point in points_:
points.append([int(_) for _ in point])
#print(points)
#同理 label
labels = labels.split('_')
#print(labels)
prov =provinces[int(labels[0])] #获取车牌地区名称
#print(prov)
plate_number = [ads[int(label)] for label in labels[1:]] #将数字转换化车牌的数字
labels = prov + ''.join(plate_number) #合并起来
#print(labels)
# 获取检测训练检测框位置
line_det = path+'\t'+'[{"transcription":"%s", "points":%s}]' % (labels, str(points))
line_det = line_det[:] + "\n"
print(line_det)
#获取识别训练图片及标签
img = cv2.imread(path)
#print(img)
crop = img[bboxs_new[1]:bboxs_new[3], bboxs_new[0]:bboxs_new[2], :]
cv2.imwrite('dataset/img/%06d.jpg' % count, crop)
line_rec = 'dataset/img/%06d.jpg\t%s\n' % (count, labels)
print(line_rec)
# 写入txt文件
if count <= train_num:
train_det.write(line_det)
train_rec.write(line_rec)
else:
dev_det.write(line_det)
dev_rec.write(line_rec)
count+=1
train_det.close()
dev_det.close()
train_rec.close()
dev_rec.close()
#创建字典文件
with open("dataset/dict.txt", "w") as f:
for key in ads +provinces:
f.write(key+"\n")
运行命令:python CCPD_test1.py后,项目结构里多了五个文件。如图下:
我来给大家详细介绍一下:
PaddleOCR中提供了如下文本检测算法和文本识别算法列表,以及每个算法在英文公开数据集上的模型和指标,主要用于算法简介和算法性能对比。
文本检测算法:
文本识别算法:
考虑车牌识别中字符数量较少,而且长度也固定,且为标准的印刷字体,所以无需使用过于复杂的模型。我们选择DBNet检测算法和CRNN识别模型作,PaddleOCR的检测模型目前支持两种backbone,分别是MobileNetV3、ResNet_vd系列,本实验两个模型均使用MobileNetV3作为其主干网络(Backbone)。
1.首先我们在configs/det/det_mv3_db.yml 文件中Train和Eval数据集得图片路径“data_dir"和标签路径”label_file_list".我自己修下是:
如果你安装的是paddle-cpu版本,或者没有gpu显卡的话,需要将det_mv3_db.yml配置文件中的use_gpu字段修改为false.
如果你只有一个gpu显卡的话,单机单卡训练可以输入命令: python tools/train.py -c configs/det/det_mv3_db.yml -o Global.pretrained_model=./pretrain_models/MobileNetV3_large_x0_5_pretrained
如果你是土豪又很多gpu的话,单机多卡训练,需要通过–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
如果您是在自己的数据集上训练的模型,并且调整了中文字符的字典文件,请注意修改配置文件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
#单卡训练(训练周期长,不建议)
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。如果验证集很
大,测试将会比较耗时,建议减少评估次数,或训练完再进行评估。
**1.**遇到问题:Config use_gpu cannot be set as true while you are using paddlepaddle cpu version !
解决方案:修改rec_chinese_lite_train_v2.0.yml 的use_gpu 字段为false
**2.**遇到问题:.No Images in train dataset, please ensure
解决方案:1.标注工具识别结果没有内容, 2.修改batch_size_per_card字段
3.遇到问题:ABORT!!! Out of all 4 trainers, the trainer process with rank=[0, 1, 2, 3] was aborted. Please check its log.
**解决方案:**1.选用单卡训练。2.在代码里加一行:paddle.set_device(“gpu”)
当文字检测模型和文字识别模型训练完成后需要查看评估结果。可以执行下面的代码进行评估:
1.输入命令并执行(这是文字检测模型的评估代码):
python PaddleOCR/tools/eval.py -c PaddleOCR/configs/det/det_mv3_db.yml -o Global.checkpoints=output/db_mv3/best_accuracy.pdparams PostProcess.box_thresh=0.5 PostProcess.unclip_ratio=1.5
3.从上面的结果可以看出,精准度:92%,召回率96%,hmean:94%,fps:24
hmean是一个综合指标,从先的表达式可以看出其值介与精度和召回率自己,其表达式为:
将训练好 的模型转换成inference模型需要运行如下命令:
# 导出检测模型
python PaddleOCR/tools/export_model.py -c PaddleOCR/configs/det/det_mv3_db.yml -o Global.pretrained_model=output/db_mv3/best_accuracy Global.save_inference_dir=inference/db_mv3/
# 导出识别模型
python PaddleOCR/tools/export_model.py -c PaddleOCR/configs/det/det_mv3_db.yml -o Global.pretrained_model=output/db_mv3/best_accuracy Global.save_inference_dir=inference/db_mv3/
其中:
-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文件
在执行预测时,需要通过参数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 \ #设置中文或者en
--use_angle_cls=false \
--output=../output/table \
--vis_font_path=./doc/fonts/simfang.ttf #加入字体
创作不易,求关注和点赞!!
我是一名听力障碍人士,热爱学习热爱健身,想学习怎么健身的欢迎关注哈。有图有真相!!!