# 1.研究背景
随着科技的进步和社会需求的增长,近年来摄像头逐渐高清化、高帧率化,摄像头作为信息获取设备的载体也不再局限于固定场景。路口、路侧、室内、高位、低位等不同场景下产生了各种对于检测识别的需求,比如路侧车牌识别一体机需要对车位进行无人值守,完成自动收费。传统的车牌识别方案无法面对困难场景的挑战,先验知识也随着场景类别增加而逐渐难以涵盖。我国作为车辆保有量最大的国家,在汽车数量增长的同时,其种类也在逐步增长。在这些车牌中,有传统的蓝牌、新能源汽车的绿牌、运载车的黄牌、特种车辆的双层车牌、粤港澳通行的双牌等等,目前兼容各类车牌且具有较高精确度的**双层车牌**识别系统具有很高的研究价值[4.5]。
# 2.图片识别效果
![4.png](e278fdc35ec242e6c8e37801bafa531a.png)
![5.png](3387dab3ed96f286f68bd5cb16d51364.png)
# 3.视频演示
[Python基于YOLOv7和CRNN的双层车牌分割&识别系统(源码&教程)_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1WB4y1n731/?vd_source=bc9aec86d164b67a7004b996143742dc)
# 4.准备YOLOv7格式车牌数据集(数据集文末链接提供下载)
![1.png](8acb599b95814ca405110b79b50e8e23.png)
![2.png](8f9801fc7183ee2f73b8fafa612000ee.png)
如果不懂yolo格式数据集是什么样子的,建议[先学习一下该博客](https://afdian.net/item?plan_id=c4805a4a5cde11eda8c452540025c377)。大部分CVer都会推荐用labelImg进行数据的标注,我也不例外,推荐大家用labelImg进行数据标注。不过这里我不再详细介绍如何使用labelImg,网上有很多的教程。同时,标注数据需要用到图形交互界面,远程服务器就不太方便了,因此建议在本地电脑上标注好后再上传到服务器上。
这里假设我们已经得到标注好的yolo格式数据集,那么这个数据集将会按照如下的格式进行存放。
![n.png](bb8e370f7208224069504aaae47082a8.png)
不过在这里面,train_list.txt和val_list.txt是后来我们要自己生成的,而不是labelImg生成的;其他的则是labelImg生成的。
接下来,就是生成 train_list.txt和val_list.txt。train_list.txt存放了所有训练图片的路径,val_list.txt则是存放了所有验证图片的路径,如下图所示,一行代表一个图片的路径。这两个文件的生成写个循环就可以了,不算难。
# 5.修改配置文件
总共有两个文件需要配置,一个是/yolov7/cfg/training/yolov7.yaml,这个文件是有关模型的配置文件;一个是/yolov7/data/coco.yaml,这个是数据集的配置文件。
## 第一步,复制yolov7.yaml文件到相同的路径下,然后重命名,我们重命名为yolov7-Helmet.yaml。
## 第二步,打开yolov7-Helmet.yaml文件,进行如下图所示的修改,这里修改的地方只有一处,就是把nc修改为我们数据集的目标总数即可。然后保存。
![b.png](a648dcd314f8343565adcad0ce3737d6.png)
## 第三步,复制coco.yaml文件到相同的路径下,然后重命名,我们命名为Helmet.yaml。
## 第四步,打开Helmet.yaml文件,进行如下所示的修改,需要修改的地方为5处。
第一处:把代码自动下载COCO数据集的命令注释掉,以防代码自动下载数据集占用内存;第二处:修改train的位置为train_list.txt的路径;第三处:修改val的位置为val_list.txt的路径;第四处:修改nc为数据集目标总数;第五处:修改names为数据集所有目标的名称。然后保存。
![k.png](c2ca8f93a1047342adf797df40dad6b1.png)
# 6.YOLOv7训练代码
```
import argparse
import logging
import math
import os
import random
import time
from copy import deepcopy
from pathlib import Path
from threading import Thread
import numpy as np
import torch.distributed as dist
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torch.optim.lr_scheduler as lr_scheduler
import torch.utils.data
import yaml
from torch.cuda import amp
from torch.nn.parallel import DistributedDataParallel as DDP
from torch.utils.tensorboard import SummaryWriter
from tqdm import tqdm
import test # import test.py to get mAP after each epoch
from models.experimental import attempt_load
from models.yolo import Model
from utils.autoanchor import check_anchors
from utils.datasets import create_dataloader
from utils.general import labels_to_class_weights, increment_path, labels_to_image_weights, init_seeds, \
fitness, strip_optimizer, get_latest_run, check_dataset, check_file, check_git_status, check_img_size, \
check_requirements, print_mutation, set_logging, one_cycle, colorstr
from utils.google_utils import attempt_download
from utils.loss import ComputeLoss, ComputeLossOTA
from utils.plots import plot_images, plot_labels, plot_results, plot_evolution
from utils.torch_utils import ModelEMA, select_device, intersect_dicts, torch_distributed_zero_first, is_parallel
from utils.wandb_logging.wandb_utils import WandbLogger, check_wandb_resume
logger = logging.getLogger(__name__)
def train(hyp, opt, device, tb_writer=None):
logger.info(colorstr('hyperparameters: ') + ', '.join(f'{k}={v}' for k, v in hyp.items()))
save_dir, epochs, batch_size, total_batch_size, weights, rank, freeze = \
Path(opt.save_dir), opt.epochs, opt.batch_size, opt.total_batch_size, opt.weights, opt.global_rank, opt.freeze
# Directories
wdir = save_dir / 'weights'
wdir.mkdir(parents=True, exist_ok=True) # make dir
last = wdir / 'last.pt'
best = wdir / 'best.pt'
results_file = save_dir / 'results.txt'
# Save run settings
with open(save_dir / 'hyp.yaml', 'w') as f:
yaml.dump(hyp, f, sort_keys=False)
with open(save_dir / 'opt.yaml', 'w') as f:
yaml.dump(vars(opt), f, sort_keys=False)
# Configure
plots = not opt.evolve # create plots
cuda = device.type != 'cpu'
init_seeds(2 + rank)
with open(opt.data) as f:
data_dict = yaml.load(f, Loader=yaml.SafeLoader) # data dict
is_coco = opt.data.endswith('coco.yaml')
# Logging- Doing this before checking the dataset. Might update data_dict
loggers = {'wandb': None} # loggers dict
if rank in [-1, 0]:
opt.hyp = hyp # add hyperparameters
run_id = torch.load(weights, map_location=device).get('wandb_id') if weights.endswith('.pt') and os.path.isfile(weights) else None
wandb_logger = WandbLogger(opt, Path(opt.save_dir).stem, run_id, data_dict)
loggers['wandb'] = wandb_logger.wandb
data_dict = wandb_logger.data_dict
if wandb_logger.wandb:
weights, epochs, hyp = opt.weights, opt.epochs, opt.hyp # WandbLogger might update weights, epochs if resuming
nc = 1 if opt.single_cls else int(data_dict['nc']) # number of classes
names = ['item'] if opt.single_cls and len(data_dict['names']) != 1 else data_dict['names'] # class names
assert len(names) == nc, '%g names found for nc=%g dataset in %s' % (len(names), nc, opt.data) # check
# Model
pretrained = weights.endswith('.pt')
if pretrained:
with torch_distributed_zero_first(rank):
attempt_download(weights) # download if not found locally
ckpt = torch.load(weights, map_location=device) # load checkpoint
model = Model(opt.cfg or ckpt['model'].yaml, ch=3, nc=nc, anchors=hyp.get('anchors')).to(device) # create
exclude = ['anchor'] if (opt.cfg or hyp.get('anchors')) and not opt.resume else [] # exclude keys
state_dict = ckpt['model'].float().state_dict() # to FP32
state_dict = intersect_dicts(state_dict, model.state_dict(), exclude=exclude) # intersect
model.load_st
hakesashou
- 粉丝: 7063
- 资源: 1708
最新资源
- 白色个性风格的3D博客网站模板下载.rar
- 白色个性风格的时尚纹身艺术网站模板下载.zip
- 白色极简的设计师简历模板下载.zip
- 白色个性风格的网络科技CSS网站模板.zip
- 白色简单的商务企业网站模板下载.rar
- 白色极致简洁的画册vi设计公司网页模板下载.zip
- 白色简单风格的商务企业网站模板下载.zip
- 白色简单精致的汽车行业网站模板下载.zip
- 白色简洁布局的云托管网站模板下载.zip
- 白色简洁大气的个人博客网站模板下载.rar
- 白色简洁大气风的博客网站模板下载.zip
- 白色简洁大气效果的智能机器人企业网站模板下载.zip
- 白色简洁的工作室企业网页模板下载.zip
- 白色简洁的IT数码产品网站模板下载.rar
- 白色简洁的服务企业网站模板下载.zip
- 白色简洁的商务企业网页模板下载.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈