利用週末時間斷斷續續實現端到端車牌識別項目,具備完整的數據集、數據製作、訓練、評估、預測業務。
項目特點:採用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.csdn.net/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)