项目放这:车牌识别
基于python和pytorch平台,使用CCPD2020新能源车牌数据集进行训练,效果如下:
验证集70%多的识别率吧,效果不算特别好,但也能用,另外CCPD2020数据集里面有一些图片是模糊到肉眼也分辨不出来的,应该也有所影响,剔除掉这一部分应该会再好一点。
训练:yolov3和LPRnet分别进行训练得到各自的weight
测试:将图片输入后一次经过两个网络得到结果,先经过yolov3进行车牌目标检测,然后分割出车牌区域给LPRnet进行识别(LPR只能识别字符不能检测目标)
Package Version
absl-py 1.0.0
cachetools 4.2.4
certifi 2021.10.8
charset-normalizer 2.0.12
cycler 0.11.0
dataclasses 0.6
fonttools 4.32.0
future 0.18.2
google-auth 1.35.0
google-auth-oauthlib 0.4.6
grpcio 1.44.0
idna 3.3
importlib-metadata 4.11.3
imutils 0.5.4
kiwisolver 1.4.2
lxml 4.8.0
Markdown 3.3.6
matplotlib 3.5.1
numpy 1.21.6
oauthlib 3.2.0
opencv-python 4.3.0.36
packaging 21.3
Pillow 9.1.0
pip 21.2.2
protobuf 3.20.0
pyasn1 0.4.8
pyasn1-modules 0.2.8
pycocotools 2.0.4
pyparsing 3.0.8
python-dateutil 2.8.2
PyYAML 6.0
requests 2.27.1
requests-oauthlib 1.3.1
rsa 4.8
scipy 1.7.3
setuptools 61.2.0
six 1.16.0
tensorboard 2.1.0
torch 1.7.0
torchaudio 0.7.0
torchvision 0.8.1
tqdm 4.64.0
typing_extensions 4.1.1
urllib3 1.26.9
Werkzeug 2.1.1
wheel 0.37.1
zipp 3.8.0
yolov3需要yolo格式的数据集,对yolo格式和网络不太了解的可以参考yolov3源码讲解。LPRnet需要标签为图片名,输入为94*24的图片。
如果使用CCPD数据集,分别可以使用CCPD_trans_yolodataset.py和CCPD_trans_LPRdataset.py转成两个网络所需要的数据类型
准备好数据集文件后:
yolov3的训练,在这按自己的需求修改相关配置即可开始训练
parser = argparse.ArgumentParser()
parser.add_argument('--epochs', type=int, default=30)
parser.add_argument('--batch-size', type=int, default=4)
parser.add_argument('--cfg', type=str, default='cfg/my_yolov3.cfg', help="*.cfg path")
parser.add_argument('--data', type=str, default='data/my_data.data', help='*.data path')
parser.add_argument('--hyp', type=str, default='cfg/hyp.yaml', help='hyperparameters path')
parser.add_argument('--multi-scale', type=bool, default=True,
help='adjust (67%% - 150%%) img_size every 10 batches')
parser.add_argument('--img-size', type=int, default=512, help='test size')
parser.add_argument('--rect', action='store_true', help='rectangular training')
parser.add_argument('--savebest', type=bool, default=False, help='only save best checkpoint')
parser.add_argument('--notest', action='store_true', help='only test final epoch')
parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
parser.add_argument('--weights', type=str, default='weights/yolov3-spp-ultralytics-512.pt',
help='initial weights path')
parser.add_argument('--name', default='', help='renames results.txt to results_name.txt if supplied')
parser.add_argument('--device', default='cuda:0', help='device id (i.e. 0 or 0,1 or cpu)')
parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset')
parser.add_argument('--freeze-layers', type=bool, default=False, help='Freeze non-output layers')
# 是否使用混合精度训练(需要GPU支持混合精度)
parser.add_argument("--amp", default=False, help="Use torch.cuda.amp for mixed precision training")
opt = parser.parse_args()
LPRnet的训练,如果遇到loss为Nan尝试修改learning_rate即可,其他按自己的需求修改即可开始训练
def get_parser():
parser = argparse.ArgumentParser(description='parameters to train net')
parser.add_argument('--max_epoch', default=100, help='epoch to train the network')
parser.add_argument('--img_size', default=[94, 24], help='the image size')
parser.add_argument('--train_img_dirs', default=r"./My_LPRnet_Dataset/train/", help='the train images path')
parser.add_argument('--test_img_dirs', default=r"./My_LPRnet_Dataset/val/", help='the test images path')
parser.add_argument('--savebest', type=bool, default=False, help='only save best checkpoint')
parser.add_argument('--dropout_rate', default=0.5, help='dropout rate.')
parser.add_argument('--learning_rate', default=0.005, help='base value of learning rate.')
parser.add_argument('--lpr_max_len', default=8, help='license plate number max length.')
parser.add_argument('--train_batch_size', default=128, help='training batch size.')
parser.add_argument('--test_batch_size', default=120, help='testing batch size.')
parser.add_argument('--phase_train', default=True, type=bool, help='train or test phase flag.')
parser.add_argument('--num_workers', default=8, type=int, help='Number of workers used in dataloading')
parser.add_argument('--cuda', default=True, type=bool, help='Use cuda to train model')
parser.add_argument('--resume_epoch', default=0, type=int, help='resume iter for retraining')
parser.add_argument('--save_interval', default=2000, type=int, help='interval for save model state dict')
parser.add_argument('--test_interval', default=2000, type=int, help='interval for evaluate')
parser.add_argument('--momentum', default=0.9, type=float, help='momentum')
parser.add_argument('--weight_decay', default=2e-5, type=float, help='Weight decay for SGD')
parser.add_argument('--lr_schedule', default=[4, 8, 12, 14, 16], help='schedule for learning rate.')
parser.add_argument('--save_folder', default='./weights/', help='Location to save checkpoint models')
parser.add_argument('--save_weight_name', default='myLPRweight.pth', help='Location to save checkpoint models')
# parser.add_argument('--pretrained_model', default='./weights/Final_LPRNet_model.pth', help='pretrained base model')
parser.add_argument('--pretrained_model', default='', help='pretrained base model')
args = parser.parse_args()
return args