利用周末时间断断续续实现端到端车牌识别项目,具备完整的数据集、数据制作、训练、评估、预测业务。
项目特点:采用tensorflow中的keras库 + 训练时数据生成器data_generator;对学习keras API有一些参考意义。
项目地址:https://github.com/MrZhousf/license_plate_recognize
- 运行平台:tensorflow1.12.0+python3.6
- 神经网络:CNN+RNN
- 数据集:CCPD2019
依赖
pip install -r requirements.txt
数据集
CCPD2019车牌数据集:https://github.com/detectRecog/CCPD
训练数据生成
生成训练数据集: deal_ccpd_data.py
- 下载CCPD2019数据集:https://github.com/detectRecog/CCPD
- 共有9种类型的车牌数据
2. 保存车牌图片-提取图片中的车牌
fetch_plate_img(img_dir=img_dir_, save_dir=save_dir_)
运行完成后,只保留了车牌图片且命名为车牌号码
3. 图片校验,删除有问题的图片
verify_img(img_dir=img_dir_, error_img_save_dir=error_img_save_dir_)
4. 统计出车牌中每个字符的个数
statistics(img_dir=img_dir_, log_txt=log_txt_)
统计结果如下,统计结果没有显示完全,可见车牌数据是安徽的居多(ccpd2019是中科大的学生收集与整理的)
5. 生成训练-评估数据:将数据按照百分比切割成训练集和评估集
generate_train_eval(img_dir=img_dir_, train_dir=train_dir_, eval_dir=eval_dir_, eval_percent=0.03)
CNN+RNN
model目录下为网络训练业务
- 神经网络:license_plate_model.py
- 训练+评估:train.py
- 数据生成器:data_generator.py
- 预测/测试:prediction.py
- 下载预训练模型13_0.213.hdf5并置于train_dir目录下,该模型训练了13个epoch,loss=0.213:https://download.youkuaiyun.com/download/zsf442553199/12115514
待完善
- CCPD2019数据集有35万张车牌数据(包含各种天气),对于端到端的模型来说数据还有增加的空间
- CCPD2019数据集未覆盖全国各地的车牌,安徽车牌居多,数据缺口较大
- CCPD2019缺少新能源车、混动、货车以及特种车辆的车牌图片(黄牌、绿牌、黄绿牌、白牌、黑牌等)
- 增加车牌检测网络,实现车牌检测+识别自动化,这个比较简单,可以采用yolov3实现,后续若有时间再提交一版
模型主要代码
def create_model(self, data_format, training=True):
if data_format == 'channels_first':
# (batch, channels, height, width) default
input_shape = (self.channels, self.image_height, self.image_width)
else:
# (batch, height, width, channels)
assert data_format == 'channels_last'
input_shape = (self.image_height, self.image_width, self.channels)
inputs = self.layer.Input(shape=input_shape, name='input', dtype=tf.float32)
# cnn
tensor = self.build_cnn(inputs=inputs, data_format=data_format)
# rnn
tensor = self.build_rnn(tensor)
# ctc
y_pre = self.layer.Activation('softmax', name='softmax')(tensor)
labels = self.layer.Input(name='labels', shape=[self.label_max_length], dtype=tf.float32)
input_len = self.layer.Input(name='input_length', shape=[1], dtype=tf.int64)
label_len = self.layer.Input(name='label_length', shape=[1], dtype=tf.int64)
loss_out = self.layer.Lambda(self.ctc_lambda_func, output_shape=(1,), name='ctc')(
[y_pre, labels, input_len, label_len])
if training:
return tf.keras.models.Model(inputs=[inputs, labels, input_len, label_len], outputs=loss_out)
else:
return tf.keras.models.Model(inputs=[inputs], outputs=y_pre)