HyperLPR github地址:https://github.com/zeusees/HyperLPR
demo中总的流程为:
- 利用基于Viola和Jones提出的级联(cascade)检测器框架对车牌进行进行车牌目标检测的粗定位,识别出车牌文件。用到的模型参数为:cascade.xml。
- 对粗定位的车牌进行左右边界回归检测,去除车牌两遍多余的部分。用到的模型参数为:model12.h5。
- 将左右边界回归检测得到的车牌送入训练好的OCR模型中,进行字符识别。用到的模型参数为:ocr_plate_all_gru.h5。
demo代码:
import HyperLPRLite as pr
import cv2
import numpy as np
grr = cv2.imread("images_rec/IMG_1676.JPG")
model = pr.LPR("model/cascade.xml","model/model12.h5","model/ocr_plate_all_gru.h5")
for pstr,confidence,rect in model.SimpleRecognizePlateByE2E(grr):
if confidence>0.7:
image = drawRectBox(grr, rect, pstr+" "+str(round(confidence,3)))
print("plate_str:",pstr)
# print()
print("plate_confidence",confidence)
# print()
if image.shape[0] >= 2000 and image.shape[1]>=2000:
image = cv2.resize(image, (1500,1500))
cv2.imshow("image",image)
cv2.waitKey(0)
-
demo代码解释:
LPR是一个类,调用__init__函数加载模型,pr.LPR("model/cascade.xml","model/model12.h5","model/ocr_plate_all_gru.h5")
中三个参数值为:
(model_detection,model_finemapping,model_seq_rec)
,三个参数分别的含义为:
-
model_detection:cascade.xml,用于object detection。一种基于Haar特征的级联分类器(Viola和Jones在Rapid Object Detection using a Boosted Cascade of Simple论文中提出的方法,发表在2001年的CVPR会议上,目前已经达到了1.6万的引用量)用于物体检测的模型,是目前效果最好的cascade检测模型。
-
model_finemapping:model12.h5,左右边界回归模型。
-
model_seq_rec:ocr_plate_all_gru.h5,用于检测车牌中的文字。基于GRU的序列模型从OCR模型修改,效果目前最好但速度较慢,需要20ms。
-
调用的是LPR的__init__函数,实现模型初始化功能。
class LPR(): def __init__(self,model_detection,model_finemapping,model_seq_rec): self.watch_cascade = cv2.CascadeClassifier(model_detection) self.modelFineMapping = self.model_finemapping() self.modelFineMapping.load_weights(model_finemapping) self.modelSeqRec = self.model_seq_rec(model_seq_rec)
-
LPR实例化为model,调用SimpleRecognizePlateByE2E
方法进行车牌预测。
各阶段的车牌文件
-
最开始的车牌文件:
-
车牌粗定位:
-
SimpleRecognizePlateByE2E
最开始对车牌文件进行粗定位(detectPlateRough
),利用多尺度检测detectMultiScale
,得到图片中所有可能的车牌,及其在原图中位置。def SimpleRecognizePlateByE2E(self,image): images = self.detectPlateRough(image,image.shape[0],top_bottom_padding_rate=0.1)
- 关于车牌粗定位,可以参考原作者的文章:HyperLPR车牌识别技术算法之车牌粗定位与训练这篇文章
-
-
左右边界剪切
- 使用是
finemappingVertical
函数 - 裁剪后得到的车牌文件为:
关于车牌精定位,可以参考原作者的 HyperLPR车牌识别技术算法之车牌精定位 文章。
- 使用是
-
车牌文字识别
- 将剪切得到的车牌文件进行车牌文字识别,调用
recognizeOne
函数进行预测从下面的代码中可以看到,recognizeOne
函数中调用的是modelSeqRec.predict(np.array([x_temp]))
进行预测。 - 预测得到的y_pred是一个形状为(1, 18, 84)的numpy.ndarray,数据为float32
- 由于?,对其进行裁剪,裁减为 (1, 16, 84)
- 之后对该numpy进行解码
fastdecode
,获得识别得到的车牌文件‘川A0Q2E5’。
image_rgb,rect_refine = self.finemappingVertical(plate,rect) res,confidence = self.recognizeOne(image_rgb) def recognizeOne(self,src): x_tempx = src x_temp = cv2.resize(x_tempx,( 164,48)) x_temp = x_temp.transpose(1, 0, 2) y_pred = self.modelSeqRec.predict(np.array([x_temp])) y_pred = y_pred[:,2:,:] return self.fastdecode(y_pred)
- 将剪切得到的车牌文件进行车牌文字识别,调用