目标识别项目实战:基于Yolov7-LPRNet的动态车牌目标识别算法模型(二)

news2024/11/17 11:48:51

前言

目标识别如今以及迭代了这么多年,普遍受大家认可和欢迎的目标识别框架就是YOLO了。按照官方描述,YOLOv8 是一个 SOTA 模型,它建立在以前 YOLO 版本的成功基础上,并引入了新的功能和改进,以进一步提升性能和灵活性。从基本的YOLOv1版本到如今v8版本,完成了多次蜕变,现在已经相当成熟并且十分的亲民。我见过很多初学目标识别的同学基本上只花一周时间就可以参照案例实现一个目标检测的项目,这全靠YOLO强大的解耦性和部署简易性。初学者甚至只需要修改部分超参数接口,调整数据集就可以实现目标检测了。但是我想表达的并不是YOLO的原理有多么难理解,原理有多难推理。一般工作中要求我们能够运行并且能够完成目标检测出来就可以了,更重要的是数据集的标注。我们不需要完成几乎难以单人完成的造目标检测算法轮子的过程,我们需要理解YOLO算法中每个超参数的作用以及影响。就算我们能够训练出一定准确度的目标检测模型,我们还需要根据实际情况对生成结果进行一定的改写:例如对于图片来说一共出现了几种目标;对于一个视频来说,定位到具体时间出现了识别的目标。这都是需要我们反复学习再练习的本领。

完成目标检测后,我们应该输出定位出来的信息,YOLO是提供输出设定的超参数的,我们需要根据输出的信息对目标进行裁剪得到我们想要的目标之后再做上层处理。如果是车牌目标识别的项目,我们裁剪出来的车牌就可以进行OCR技术识别出车牌字符了,如果是安全帽识别项目,那么我们可以统计一张图片或者一帧中出现检测目标的个数做出判断,一切都需要根据实际业务需求为主。本篇文章主要是OCR模型对车牌进行字符识别,结合YOLO算法直接定位目标进行裁剪,裁剪后生成OCR训练数据集即可。开源项目地址,如果有帮助希望不吝点亮star~

基于Yolov7-LPRNet的动态车牌目标识别算法模型icon-default.png?t=N7T8https://github.com/Fanstuck/Yolov7-LPRNet

其中数据集的质量是尤为重要的,决定了模型的上限,因此想要搭建一个效果较好的目标识别算法模型,就需要处理流程较为完善的开源数据集。本篇文章采用的是CCPD数据集,上篇文章已经详细描述了整个项目的初步搭建过程,包括数据集准备和数据预处理,大体系统框架和数据标签聚合。现在开始正式YOLOv7搭建。


一、YOLOv7

YOLO算法作为one-stage目标检测算法最典型的代表,其基于深度神经网络进行对象的识别和定位,运行速度很快,可以用于实时系统。从近几年来看,模型结构重参化和动态标签分配已经成为了目标检测领域中的主要优化方向。针对于结构重参化,YOLOv7的作者是通过分析梯度的传播路径来为网络中的不同层进行结构重参化优化,作者还提出了扩展和复合缩放的方式,通过这种方式可以更高效利用参数量和计算量。这样不仅可以减少大量参数,还可以提高推理速度以及检测精度。

我们这里不作展开Yolov7详解,开源项目里面自带大家可直接克隆就好,省去了一些冗余功能。但是github上面的版本删去了训练模块,提供了已经训练完成的模型和推理模型,这样克隆方便展示直接效果,训练的权重并不是最优的,本身并没有迭代多次,想要精度更高的模型我将会在后续硬件支持下再训练,或者大家也可以去下载别人已经训练好的模型。大家如有需要可以通过网盘下载:

链接:https://pan.baidu.com/s/1rjkwqC0p5kp43WP8EnMwqw
提取码:40yu
我会在本篇文章详细介绍模型权重的具体训练过程。

二、训练步骤

1.安装环境

利用Yolo训练模型十分简单并没有涉及到很复杂的步骤,如果是新手的话注意下载的torch版本是否符合本身NVDIA GPU的版本,需要根据NVIDIA支持最高的cuda版本去下载兼容的Torch版本,查看cuda版本可以通过终端输入:nvidia-smi

确定requirements.txt没问题之后,直接通过pip下载环境即可:

pip install -r requirements.txt

 2.修改Yolo配置文件

首先增加cfg/training/yolov7-e6e-ccpd.yaml文件,此配置文件可以参数动态调整网络规模,这里也不展开细讲,以后会有Yolov7源码详解系列,敬请期待,我们需要根据我们用到的官方yolo模型选择对于的yaml文件配置,我这里用的的yolov7-e6e模型训练,所以直接拿yolov7-e6e.yaml改写:

# parameters
nc: 1  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple

其中nc是检测个数,depth_multiple是模型深度,width_multiple表示卷积通道的缩放因子,就是将配置里面的backbone和head部分有关Conv通道的设置,全部乘以该系数。通过这两个参数就可以实现不同复杂度的模型设计。然后是添加数据索引文件data/license.yaml:

train: ./split_dataset/images/train  
val: ./split_dataset/images/val 
test: ./split_dataset/images/test 

# number of classes
nc : 1

#class names
names : ['license']

3.训练模型

前面train,val,test都对应着目录存放的训练数据集。之后修改train.py中的参数或者是直接在终端输入对应的参数自动目录,我一般是习惯直接在defalut下面修改,parser的各类参数功能为:

#weight:指定预训练权重路径;如果这里设置为空的话,就是自己从头开始进行训练;官方有提供预训练权重
#cfg:指定模型配置文件路径的;源码里面提供了几个配置文件,配置文件里面指定了一些参数信息和backbone的结构信息。
#data:数据集对应的参数文件;里面主要存放数据集的类别和路径信息。
#hyp:指定超参数文件的路径;超参数里面包含了大量的参数信息。
#epochs:训练的轮数;默认为300轮,显示效果是0-299
#batch-size:每批次的输入数据量;default=-1将时自动调节batchsize大小
#img-size:训练集和测试集图片的像素大小;输入默认640*640,可以进行适当的调整,这样才能达到好的效果。
#rect:是否采用矩阵推理的方式去训练模型。
#resume:断点续训:即是否在之前训练的一个模型基础上继续训练,default 值默认是 false;
#nosave:是否只保存最后一轮的pt文件;我们默认是保存best.pt和last.pt两个的;
#notest:只在最后一轮测试;正常情况下每个epoch都会计算mAP,但如果开启了这个参数,那么就只在最后一轮上进行测试,不建议开启。
#noautoanchor:是否禁用自动锚框;默认是开启的,自动锚点的好处是可以简化训练过程。
#evolve:遗传超参数进化;yolov7使用遗传超参数进化,提供的默认参数是通过在COCO数据集上使用超参数进化得来的。由于超参数进化会耗费大量的资源和时间,所以建议不要动这个参数。
#bucket:谷歌云盘;通过这个参数可以下载谷歌云盘上的一些东西,但是现在没必要使用了。
#cache:是否提前缓存图片到内存,以加快训练速度,默认False;开启这个参数就会对图片进行缓存,从而更好的训练模型。
#image-weights:是否启用加权图像策略,默认是不开启的;主要是为了解决样本不平衡问题;开启后会对上一轮训练效果不好的图片,在下一轮中增加一些权重;
#device:设备选择;这个参数就是指定硬件设备的,系统会自己判断。
#multi-scale:是否启用多尺度训练,默认是不开启的;多尺度训练是指设置几种不同的图片输入尺度,训练时每隔一定iterations随机选取一种尺度训练,这样训练出来的模型鲁棒性更强。
#single-cls:设定训练数据集是单类别还是多类别;默认为 false多类别。
#optimizer:选择使用 Adam 优化器
#sync-bn:是否开启跨卡同步BN;开启参数后即可使用 SyncBatchNorm多 GPU 进行分布式训练。
#local_rank:DDP参数,请勿修改
#workers:最大worker数量。
#project:指定训练好的模型的保存路径;默认在runs/train。
#entity:wandb 库对应的东西。
#name:设定保存的模型文件夹名,默认在exp;
#exist-ok:每次预测模型的结果是否保存在原来的文件夹;如果指定了这个参数的话,那么本次预测的结果还是保存在上一次保存的文件夹里;如果不指定就是每次预测结果保存一个新的文件夹下。
#quad:官方给出的开启这个功能后的实际效果:

    #好处是在比默认 640 大的数据集上训练效果更好
    #副作用是在 640 大小的数据集上训练效果可能会差一些
#linear-lr:用于调整学习率;含义是通过余弦函数来降低学习率。使用梯度下降算法来优化目标函数的时候,当越来越接近Loss值的全局最小值时,学习率应该变得更小来使得模型尽可能接近这一点,而余弦退火可以通过余弦函数来降低学习率。
#label-smoothing:是否对标签进行平滑处理,默认是不启用的;
#upload_dataset:wandb 库对应的东西。是否上传dataset到wandb tabel(将数据集作为交互式 dsviz表 在浏览器中查看、查询、筛选和分析数据集) 默认False
#bbox_interval:wandb 库对应的东西,可以忽略。设置界框图像记录间隔 Set bounding-box image logging interval for W&B 默认-1
#save-period:用于设置多少个epoch保存一下checkpoint,int 型,默认为 -1。
#artifact_alias:表示还未实现的内容,忽略即可


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default='yolo7.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='', help='model.yaml path')
    parser.add_argument('--data', type=str, default='data/coco.yaml', help='data.yaml path')
    parser.add_argument('--hyp', type=str, default='data/hyp.scratch.p5.yaml', help='hyperparameters path')
    parser.add_argument('--epochs', type=int, default=300)
    parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')
    parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='[train, test] image sizes')
    parser.add_argument('--rect', action='store_true', help='rectangular training')
    parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
    parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
    parser.add_argument('--notest', action='store_true', help='only test final epoch')
    parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
    parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
    parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
    parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
    parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
    parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')
    parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')
    parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
    parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')
    parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')
    parser.add_argument('--project', default='runs/train', help='save to project/name')
    parser.add_argument('--entity', default=None, help='W&B entity')
    parser.add_argument('--name', default='exp', help='save to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--quad', action='store_true', help='quad dataloader')
    parser.add_argument('--linear-lr', action='store_true', help='linear LR')
    parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')
    parser.add_argument('--upload_dataset', action='store_true', help='Upload dataset as W&B artifact table')
    parser.add_argument('--bbox_interval', type=int, default=-1, help='Set bounding-box image logging interval for W&B')
    parser.add_argument('--save_period', type=int, default=-1, help='Log model after every "save_period" epoch')
    parser.add_argument('--artifact_alias', type=str, default="latest", help='version of dataset artifact to be used')
    parser.add_argument('--freeze', nargs='+', type=int, default=[0], help='Freeze layers: backbone of yolov7=50, first3=0 1 2')
    parser.add_argument('--v5-metric', action='store_true', help='assume maximum recall as 1.0 in AP calculation')

对应参数修改,一般来说修改这些就足够了:

parser.add_argument('--weights', type=str, default='weights/yolo7-e6e.pt', help='initial weights path')
parser.add_argument('--cfg', type=str, default='cfg/yolov7-e6e-ccpd', help='model.yaml path')
parser.add_argument('--data', type=str, default='data/license.yaml', help='data.yaml path')

当然也可能出现内存溢出等问题,需要修改:

arser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')
parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')

 这两个参数,具体参数根据自己硬件条件修改。

然后直接终端输入:

python train.py

 训练即可。生成的模型会自动保存到run/目录里面。之后在run/train/exp/weights目录下会产生两个权重文件,一个是最后一轮的权重文件,一个是最好的权重文件,一会我们就要利用这个最好的权重文件来做推理测试。除此以外还会产生一些验证文件的图片等一些文件。

4.推理

 然后修改detect.py:

f __name__ == '__main__':
"""
--weights:权重的路径地址
--source:测试数据,可以是图片/视频路径,也可以是'0'(电脑自带摄像头),也可以是rtsp等视频流
--output:网络预测之后的图片/视频的保存路径
--img-size:网络输入图片大小
--conf-thres:置信度阈值
--iou-thres:做nms的iou阈值
--device:是用GPU还是CPU做推理
--view-img:是否展示预测之后的图片/视频,默认False
--save-txt:是否将预测的框坐标以txt文件形式保存,默认False
--classes:设置只保留某一部分类别,形如0或者0 2 3
--agnostic-nms:进行nms是否也去除不同类别之间的框,默认False
--augment:推理的时候进行多尺度,翻转等操作(TTA)推理
--update:如果为True,则对所有模型进行strip_optimizer操作,去除pt文件中的优化器等信息,默认为False
--project:推理的结果保存在runs/detect目录下
--name:结果保存的文件夹名称
"""
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')
    parser.add_argument('--source', type=str, default='data/images', help='source')  # file/folder, 0 for webcam
    parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
    parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--view-img', action='store_true', help='display results')
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
    parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
    parser.add_argument('--augment', action='store_true', help='augmented inference')
    parser.add_argument('--update', action='store_true', help='update all models')
    parser.add_argument('--project', default='runs/detect', help='save results to project/name')
    parser.add_argument('--name', default='exp', help='save results to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    opt = parser.parse_args()

 这里需要将刚刚训练好的最好的权重传入到推理函数中去。然后就可以对图像视频进行推理了。

主要需要修改的参数是:

parser.add_argument('--weights', nargs='+', type=str, default='runs/train/exp/weights/best.pt', help='model.pt path(s)')
 parser.add_argument('--source', type=str, default='测试数据集目录或者图片', help='source') 

 推理测试结束以后,在run下面会生成一个detect目录,推理结果会保存在exp目录下。

 


备注

有问题的私信博主或者直接评论就可以了博主会长期维护此开源项目,目前此项目运行需要多部操作比较繁琐,我将不断更新版本优化,下一版本将加入UI以及一键部署环境和添加sh指令一键运行项目代码。下篇文章将详细解读LPRNet模型如何进行OCR识别, 再次希望对大家有帮助不吝点亮star~

基于Yolov7-LPRNet的动态车牌目标识别算法模型icon-default.png?t=N7T8https://github.com/Fanstuck/Yolov7-LPRNet

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1065556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全平台高速下载器Gopeed

什么是 Gopeed ? Gopeed (全称 Go Speed)是一款支持全平台的高速下载器,开源、轻量、原生,采用 Golang Flutter 开发,支持(HTTP、BitTorrent、Magnet 等)协议,并支持所有平台。 已…

linearlayout中使用多个weight导致部分子控件消失异常

问题描述: 在一个linearlayout中写了两个用到weight的布局,在androidstudio中显示正常 但是代码跑起来之后最下面哪一行都消失了; 解决办法1 把两个用到weight的改成一个了,外面那层的weight写成固定宽度就能正常显示出丢失的…

【C++】vector的模拟实现 | 使用memcpy拷贝时的问题 | 实现深拷贝

目录 基本框架及接口 构造函数 无参构造 迭代器区间构造 初始化构造 析构函数 size() | capacity() 扩容的reserve() 使用memcpy拷贝的问题 改变大小的resize() operator[] 迭代器的实现 vector的增删 尾插push_back() 尾删pop_back() 在指定位置插入insert() …

【prism】prism 框架代码

前言 这个是针对整个专栏的一个示例程序,应用了专栏里讲的一些知识点,他是一个小而美的Prism的框架代码,一个模板,方便大家去扩展一个prism工程。 下面是一些代码片段,最后我给出整个工程的下载链接~~~ 代码片段 主界面代码 <Window x:Class="PrismTest.View…

企业加密软件哪个最好用?

天锐绿盾是一款专业的企业级加密软件&#xff0c;提供专业版、行业增强版和旗舰版&#xff0c;分别针对不同的用户需求。 PC访问地址&#xff1a; 首页 天锐绿盾专业版主要面向企事业单位的通用需求&#xff0c;以"让防泄密的管理更简单有效"为核心理念&#xff0c;…

ipv6跟ipv4如何通讯

IPv6的128位地址通常写成8组&#xff0c;每组为四个十六进制数的形式。比如:AD80:0000:0000:0000:ABAA:0000:00C2:0002 是一个合法的IPv6地址。这个地址比较长&#xff0c;看起来不方便也不易于书写。零压缩法可以用来缩减其长度。如果几个连续段位的值都是0&#xff0c;那么这…

从本地到全球:跨境电商的壮丽崛起

跨境电商&#xff0c;作为数字时代的商业现象&#xff0c;正在以惊人的速度改变着全球贸易的面貌。它不仅仅是一种商业模式&#xff0c;更是一场无国界的革命&#xff0c;使商业不再受限于地理位置&#xff0c;而是全面融入全球市场。 本文将深入探讨跨境电商的崛起&#xff0…

Ansys Speos | 将Rayfile光源转换为面光源

概览 本文将讲述如何rayfile转换为面光源&#xff0c;Rayfile光源文件包含有限数量的光线&#xff0c;表面光源有无限量的光线&#xff0c;这使得表面源对于使用逆模拟&#xff0c;得到清晰可视化仿真特别有用。 表面光源均匀地从几何形状表面的每个点发射光&#xff0c;这种简…

Ansys Optics Launcher 提升客户体验

概述 为了改善用户体验&#xff0c;Ansys Optics 团队开发了一个新的一站式启动应用程序&#xff0c;简化了工作流程并提高了效率。随着Ansys 2023 R2的最新更新&#xff0c;Ansys Optics Launcher 现已安装在Ansys Speos, Ansys Lumerical和Ansys Zemax OpticStudio中。作为一…

DVWA -xss

什么是XSS 跨站点脚本(Cross Site Scripting,XSS)是指客户端代码注入攻击&#xff0c;攻击者可以在合法网站或Web应用程序中执行恶意脚本。当wb应用程序在其生成的输出中使用未经验证或未编码的用户输入时&#xff0c;就会发生XSS。 跨站脚本攻击&#xff0c;XSS(Cross Site S…

Docker之Dockerfile搭建lnmp

目录 一、搭建nginx ​编辑 二、搭建Mysql&#xff08;简略版&#xff09; 三、搭建PHP 五、补充 主机名ip地址主要软件mysql2192.168.11.22Docker 代码示例 systemctl stop firewalld systemctl disable firewalld setenforce 0docker network create --subnet172.18.…

C#封装、继承和多态的用法详解

大家好&#xff0c;今天我们将来详细探讨一下C#中封装、继承和多态的用法。作为C#的三大面向对象的特性&#xff0c;这些概念对于程序员来说非常重要&#xff0c;因此我们将对每个特性进行详细的说明&#xff0c;并提供相应的示例代码。 目录 1. 封装&#xff08;Encapsulati…

009:获取20日均线数据

再《005》中我们获得了K线数据&#xff0c;现在我们要把他的20日均线数据也获取出来。然后通过计算后&#xff0c;保存在新的一列中&#xff1a; import pandas as pd import tkinter as tk from tkinter import filedialog import ospathdef open_file():global pathpath fi…

基于Springboot的漫画网站springboot022

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…

代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数

以下题解的更详细思路来自于:代码随想录 (programmercarl.com) 前言 二叉树的高度与深度 这里先补充一下二叉树深度和高度的概念 高度:二叉树中任意一个节点到叶子结点的距离 深度:二叉树中任意一个节点到根节点的距离 下面给出一个图便于理解 获取高度与深度的遍历方式 高度:…

python scanpy spatial空转全流程

Spatial mapping of cell types across the mouse brain (1/3) - estimating reference expression signatures of cell types — cell2location documentation Spatial mapping of cell types across the mouse brain (2/3) - cell2location — cell2location documentation #…

文件扫描模块

文章目录 前言文件扫描模块设计初级扫描方案一实现单线程扫描整合扫描步骤 设计初级扫描方案二周期性扫描 总结 前言 我们这个模块考虑的是数据库里面的内容从哪里获取。 获取完成后&#xff0c;这时候,我们就需要把目录里面文件/子文件都获取出来,并存入数据库。 文件扫描模…

Flask-[项目]-搭建短网址系统:flask实现短网址系统,短网址系统,构建短网址系统

一、项目下载地址 https://gitee.com/liuhaizhang/short-url-systemhttps://gitee.com/liuhaizhang/short-url-system 二、项目搭建 2.1、基本环境安装 1、安装好mysql数据库 2、安装好redis数据 3、安装好python解释器 2.2、项目依赖安装 1、切换到python解释器环境中 …

MES管理系统在制造业中的应用及其核心构成

在制造业的信息化进程中&#xff0c;车间级的信息化一直是其薄弱环节。为了提升车间的自动化水平&#xff0c;发展MES数字化技术成为了有效的途径。MES管理系统强调车间级的过程集成、控制和监控&#xff0c;合理地配置和组织所有资源&#xff0c;以满足车间的信息化需求。它提…

5G商企专网,助力打造城市生命线“安徽样板”

为扎实抓好重点领域安全监管&#xff0c;防范各类生产突发事故发生&#xff0c;近年来&#xff0c;安徽芜湖启动了城市生命线工程项目&#xff0c;致力于打造城市生命线“安徽样板”。 项目建设如火如荼&#xff0c;一些难题也不断涌现。比如&#xff0c;为提升城市安全保障能…