基于YoloV11+PaddleOCR的车牌检测系统

文章目录

  • 一、CCPD数据集进行处理
    • 1.1 从文件夹构建txt格式数据集
    • 1.2 运行脚本按照8:2划分训练集,测试集
  • 二 、YOLOV11训练模型
    • 2.1 编写car_plate.yaml文件
    • 2.2 编写train脚本:
    • 2.3 训练过程
  • 三、PaddleOCR识别车牌号
    • 3.1 安装paddleocr,以及paddlepadddle-cpu还是gpu往下看,先勿操作
      • 3.1.1 安装paddlepadddle-gpu(CPU和GPU选一个就行)
      • 3.1.2 安装cpu版本的(CPU和GPU选一个就行)
      • 3.1.3 安装paddleocr
    • 3.2 安装过程
      • 3.2.1 paddleocr安装过程如下
      • 3.2.2 PaddlePaddle安装过程如下
    • **3.2 代码示例**

实现思路:yolov11提取车牌坐标,进行分割,然后使用PaddleOCR进行识别!

图片:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

完整源码获取方式关注底部wx公号,私信获得(有偿)

一、CCPD数据集进行处理

下载链接:https://github.com/detectRecog/CCPD

在这里插入图片描述

在这里插入图片描述

打开readme文件,查找百度网盘链接,在此不再赘述!

在这里插入图片描述

数据集比较大,

数据集说明:

CCPD2019车牌数据集是采集人员在合肥停车场采集、手工标注得来,采集时间在早7:30到晚10:00之间。且拍摄车牌照片的环境复杂多变,包括雨天、雪天、倾斜、模糊等。CCPD数据集包含将近30万张图片、图片尺寸为720x1160x3,共包含8种类型图片,每种类型、数量及类型说明如下表:

类型图片数说明
ccpd_base199996正常车牌
ccpd_challenge50003比较有挑战的车牌
ccpd_db10132光线较暗或较亮车牌
ccpd_fn20967距离摄像头较远或较近
ccpd_np3036没上牌的新车
ccpd_rotate10053水平倾斜20-50度,垂直倾斜-10-10度
ccpd_tilt30216水平倾斜15-45度,垂直倾斜-15-45度
ccpd_weather9999雨天、雪天或大雾的车牌
ccpd_blur20611模糊的车牌
cppd_newenergy11776新能源车牌

总共283037张车牌图像
图片命名:“025-95_113-154&383_386&473-386&473_177&454_154&383_363&402-0_0_22_27_27_33_16-37-15.jpg”

解释:

025:车牌区域占整个画面的比例;
95_113: 车牌水平和垂直角度, 水平95°, 竖直113°
154&383_386&473:标注框左上、右下坐标,左上(154, 383), 右下(386, 473)
86&473_177&454_154&383_363&402:标注框四个角点坐标,顺序为右下、左下、左上、右上
0_0_22_27_27_33_16:车牌号码映射关系如下: 第一个0为省份 对应省份字典provinces中的’皖’,;第二个0是该车所在地的地市一级代码,对应地市一级代码字典alphabets的’A’;后5位为字母和文字, 查看车牌号ads字典,如22为Y,27为3,33为9,16为S,最终车牌号码为皖AY339S
省份:[“皖”, “沪”, “津”, “渝”, “冀”, “晋”, “蒙”, “辽”, “吉”, “黑”, “苏”, “浙”, “京”, “闽”, “赣”, “鲁”, “豫”, “鄂”, “湘”, “粤”, “桂”, “琼”, “川”, “贵”, “云”, “藏”, “陕”, “甘”, “青”, “宁”, “新”]

地市:[‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’,‘X’, ‘Y’, ‘Z’]

车牌字典:[‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’,‘Y’, ‘Z’, ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’]

最新的CCPD2020又补充了1万多张新能源汽车数据,都在下面的官网,感兴趣的可以去下载。

由于数据量过大,我从各个类型里面随机抽取10%,最终重构以后得到最终的数据集!

最终的数据集数据量如下:

类型图片数说明
ccpd_base19999正常车牌
ccpd_challenge5000比较有挑战的车牌
ccpd_db1013光线较暗或较亮车牌
ccpd_fn2096距离摄像头较远或较近
ccpd_np303没上牌的新车 没有坐标信息,忽略
ccpd_rotate1005水平倾斜20-50度,垂直倾斜-10-10度
ccpd_tilt3021水平倾斜15-45度,垂直倾斜-15-45度
ccpd_weather999雨天、雪天或大雾的车牌
ccpd_blur2061模糊的车牌
cppd_newenergy1177新能源车牌

1.1 从文件夹构建txt格式数据集

去除重复图片+未上牌新车,将所有图片放在一个datasets文件夹里面,共35885张图片,然后运行下述代码:

import os
import cv2def parse_filename(filename):"""解析CCPD文件名,提取车牌边界框坐标"""try:except Exception as e:print(f"解析文件名失败: {filename}, 错误: {e}")return Nonedef convert_to_yolo_format():"""将边界框转换为YOLO格式(归一化)"""def process_ccpd_dataset(image_dir, label_dir):"""处理CCPD数据集,生成YOLO格式的标签文件"""print("CCPD 数据集处理完成,标签已生成。")# 使用示例
image_dir = "datasets-car"  # 替换为CCPD图片目录
label_dir = "datasets-car_labels"  # 生成的YOLO标签目录
process_ccpd_dataset(image_dir, label_dir)

1.2 运行脚本按照8:2划分训练集,测试集

import os
import random
import shutil# 设置文件夹路径
source_images_dir = "car_plate/Image_Files"  # 原始图片目录
source_labels_dir = "car_plate/XML_Files"  # 原始标签目录
datasets_dir = "datasets-carplate"  # 输出数据集目录# 输出目录# 创建 datasets 文件夹路径# 设置划分比例
train_ratio = 0.8  # 80% 训练集
val_ratio = 0.2    # 20% 验证集# 获取所有图片文件和标签文件# 检查一致性
assert len(image_files) == len(label_files), "图片文件与标签文件数量不一致!"
for img_file, lbl_file in zip(image_files, label_files):assert os.path.splitext(img_file)[0] == os.path.splitext(lbl_file)[0], f"文件名不匹配:{img_file}{lbl_file}"# 随机打乱文件
combined = list(zip(image_files, label_files))
random.shuffle(combined)
image_files, label_files = zip(*combined)# 划分数据集# 复制文件
def copy_files(file_list, source_dir, target_dir):for file in file_list:shutil.copy(os.path.join(source_dir, file), os.path.join(target_dir, file))# 复制训练集
copy_files(train_images, source_images_dir, train_images_dir)
copy_files(train_labels, source_labels_dir, train_labels_dir)# 复制验证集
copy_files(val_images, source_images_dir, val_images_dir)
copy_files(val_labels, source_labels_dir, val_labels_dir)# 检查分割后的文件数量和一致性
def validate_dataset(images_dir, labels_dir):print(f"验证通过:{images_dir}{labels_dir} 完全匹配!")# 验证所有子集
print("Dataset splitting complete and validation passed!")

最终得到处理后的数据集!

二 、YOLOV11训练模型

2.1 编写car_plate.yaml文件

train: D:\Users\15204\Desktop\yolov11_car_plate_detection\datasets\images\train
val: D:\Users\15204\Desktop\yolov11_car_plate_detection\datasets\images\valnc: 1# Classes
names: ['car_plate']

2.2 编写train脚本:

基于yolov11n.pt预训练权重


开始训练!!在这里插入图片描述

拿一个训练了20轮的模型看了看,的确不错可以,

在这里插入图片描述

可以看出来模型结果挺不错的!!!

2.3 训练过程

  Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size40/50      2.39G      0.808     0.3246     0.9742          5        640: 100%|██████████| 1795/1795 [05:45<00:00,  5.19it/s]Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 225/225 [00:37<00:00,  6.04it/s]all       7177       7177      0.998      0.998      0.994      0.836Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size45/50      2.38G     0.7623     0.2749     0.9641          4        640: 100%|██████████| 1795/1795 [05:39<00:00,  5.28it/s]Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 225/225 [00:38<00:00,  5.85it/s]all       7177       7177      0.998      0.998      0.994      0.837Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size46/50      2.41G     0.7575     0.2714     0.9656          4        640: 100%|██████████| 1795/1795 [05:43<00:00,  5.22it/s]Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 225/225 [00:37<00:00,  6.00it/s]all       7177       7177      0.998      0.998      0.994      0.837Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size47/50      2.38G     0.7532     0.2661     0.9609          4        640: 100%|██████████| 1795/1795 [05:43<00:00,  5.23it/s]Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 225/225 [00:39<00:00,  5.75it/s]all       7177       7177      0.998      0.998      0.994      0.838Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size48/50      2.39G     0.7472     0.2633     0.9582          4        640: 100%|██████████| 1795/1795 [05:40<00:00,  5.27it/s]Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 225/225 [00:38<00:00,  5.89it/s]all       7177       7177      0.998      0.998      0.994      0.838Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size50/50      2.41G     0.7383     0.2556     0.9533          4        640: 100%|██████████| 1795/1795 [05:41<00:00,  5.26it/s]Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 225/225 [00:37<00:00,  6.06it/s]all       7177       7177      0.998      0.998      0.994      0.838

三、PaddleOCR识别车牌号

选择百度的paddleocr进行识别,理由如下:
在这里插入图片描述

3.1 安装paddleocr,以及paddlepadddle-cpu还是gpu往下看,先勿操作

3.1.1 安装paddlepadddle-gpu(CPU和GPU选一个就行)

我的电脑支持gpu就安装了gpu版本的,

如果你使用的是 GPU,需要安装 PaddlePaddle 的 GPU 版本:

使用下述代码:

python
import torch #导入pytorch库
print(torch.cuda.is_available()) #查看是否有cuda
print(torch.backends.cudnn.is_available()) #查看是否有cudnn
print(torch.version.cuda) #打印cuda的版本
print(torch.backends.cudnn.version()) #打印cudnn的版本

输出结果如下:

在这里插入图片描述

可以直到CUDA版本为12.1

需要查看对应的关系如下:

CUDA 11.2paddlepaddle-gpu==2.4.2
CUDA 11.6paddlepaddle-gpu==2.5.0
CUDA 11.7paddlepaddle-gpu==2.6.0
CUDA 12.xpaddlepaddle-gpu==2.6.0
pip install paddlepaddle-gpu==2.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

3.1.2 安装cpu版本的(CPU和GPU选一个就行)

pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple  # 安装 PaddlePaddle

3.1.3 安装paddleocr

pip install paddleocr

3.2 安装过程

3.2.1 paddleocr安装过程如下

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.2.2 PaddlePaddle安装过程如下

在这里插入图片描述
在这里插入图片描述

3.2 代码示例

测试了一个demo.py程序,将前面的图片传过去看看效果:

from paddleocr import PaddleOCR, draw_ocr
import cv2
import matplotlib.pyplot as plt# 初始化 PaddleOCR(lang="ch" 表示支持中文)
ocr = PaddleOCR(use_angle_cls=True, lang="ch")  # 读取车牌图片
image_path = "license_plate.jpg"  # 替换成你的车牌图片路径
image = cv2.imread(image_path)# 进行 OCR 识别
results = ocr.ocr(image, cls=True)# 解析识别结果
for line in results:for word_info in line:text, confidence = word_info[1][0], word_info[1][1]print(f"识别结果: {text}, 置信度: {confidence:.4f}")# 可视化结果
boxes = [word[0] for line in results for word in line]  # 文字框
txts = [word[1][0] for line in results for word in line]  # 文字内容
scores = [word[1][1] for line in results for word in line]  # 置信度# 绘制检测结果
image_with_boxes = draw_ocr(image, boxes, txts, scores, font_path="path/to/chinese.ttf")  # 需要指定中文字体路径
plt.imshow(image_with_boxes)
plt.axis("off")
plt.show()

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

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

相关文章

2月12日鸿蒙生态日日新PLOG,多款应用上架

2月12日鸿蒙生态日日新PLOG &#xff1a;北京医院挂号通、有度、远光商旅等多款应用上架&#xff1b;钉钉、得到、航班管家等多款重点应用功能更新。 ​​​

Python----PyQt开发(PyQt高级:手搓一个简单的记事本)

一、效果展示 二、设计PyQt界面 2.1、设置图标 self.setWindowIcon(QIcon(./images/icon/1.png)) # 窗口图标 2.2、设置标题 self.file_name 无标题-新建文本文档 # 默认文件名 self.setWindowTitle(self.file_name) # 窗口标题 2.3、添加菜单栏、工具栏、状态栏 # 创…

Java 大视界 -- 大数据伦理与法律:Java 技术在合规中的作用与挑战(87)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

什么是AI Agent、Chat、RAG、MoE

什么是AI Agent、Chat、RAG、MoE 目录 什么是AI Agent、Chat、RAG、MoE定义与原理功能特点应用场景AI Agent有哪些关键组成部分感知模块决策模块知识模块行动模块学习模块AI Agent、Chat、RAG、MoE是人工智能领域中不同的概念和技术,它们在功能、原理和应用等方面存在一些区别…

在 debian 12 上安装 mysqlclient 报错

报错如下 Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting mysqlclientUsing cached https://pypi.tuna.tsinghua.edu.cn/packages/61/68/810093cb579daae426794bbd9d88aa830fae296e85172d18cb0f0e5dd4bc/mysqlclient-2.2.7.tar.gz (91 kB)Installi…

自反馈与流量震荡:从 TCP/IP 路由到交通导航

为什么不能基于流量或时延做路由度量&#xff0c;而不仅仅基于跳数。原因在于这里存在一个自反馈&#xff1a; 路由决策导致流量变化&#xff1b;时延由流量变化而变化&#xff1b;流量时延影响路由决策。 当某条链路流量减少时&#xff0c;路由协议会将其度量调低&#xff0…

Jtti:centos主机如何搭建lnmp环境

在 CentOS 主机上搭建 LNMP(Linux Nginx MySQL/MariaDB PHP)环境是构建高性能 Web 服务器的常见选择。以下是搭建 LNMP 环境的详细步骤&#xff1a; 步骤 1: 更新系统 首先&#xff0c;更新系统的包列表和安装的包&#xff0c;以确保你的系统是最新的&#xff1a; sudo y…

如果需要保护多个域名怎么办?

随着企业和个人在网上的存在越来越重要&#xff0c;管理和保护多个域名变得尤为关键&#xff0c;那么如果需要保护这些域名&#xff0c;应该采取什么样的措施呢&#xff1f; 许多企业会选择注册与其品牌相关的不同后缀&#xff0c;或者与其产品、服务相关的域名。这不仅可以防…

从Sora到有言:3D视频生成技术的突破与应用

近年来&#xff0c;AIGC领域飞速发展&#xff0c;这个词也越来越高频地出现在了大家的生活中。AIGC 能完成的任务也越来越多&#xff0c;大模型的能力飞速增长 —— 从Deepseek生成文字&#xff0c;到StableDiffusion生成图像&#xff0c;再到Sora可以生成视频。 而现在&#x…

Apollo 9.0 控制算法 -- lon based pid controller

文章目录 1. 纵向控制算法1.1 算法结构1.1.1 外环&#xff1a;位置环1.1.2 内环&#xff1a;速度环 1.2 参数整定 2. 代码解析2.1 控制器初始化 LonController::Init()2.1.1 PID控制参数和标定表参数加载2.1.2 PID控制器初始化2.1.3 超前/滞后控制器初始化2.1.4 俯仰角滤波器初…

【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter12-BOM

十二、BOM 虽然 ECMAScript 把浏览器对象模型&#xff08;BOM&#xff0c;Browser Object Model&#xff09;描述为 JavaScript 的核心&#xff0c;但实际上 BOM 是使用 JavaScript 开发 Web 应用程序的核心。BOM 提供了与网页无关的浏览器功能对象。 HTML5 规范中有一部分涵盖…

Qt信号槽调用出错:Qt: Dead lock detected while activating a BlockingQueuedConnection

目录 1.现象和原因分析 2. 总结 1.现象和原因分析 就在最近的开发过程中&#xff0c;程序一运行在控制台就打印&#xff1a; Qt: Dead lock detected while activating a BlockingQueuedConnection&#xff1a; 咋一看&#xff0c;怎么出现死锁了呢&#xff1f;仔细看下…

Jenkins项目CICD流程

Jenkins项目流程:1.配置git环境 git config --...2.把前后端的目录初始化位本地工作目录 #git init3.提交到本地git #git add ./ git commit -m "" git tag v14.然后提交到远程git(通过,用户,群组,项目,管理项目)git remote add origin http://...git push -…

Springboot_实战

项目开发 lombok使用 自动为实体类提供get、set、toString方法 引入依赖 实体类上添加注解 统一响应结果 注意要写get、set方法&#xff1b;下面是错误的&#xff0c;因此要加上Data注解 一个注册的接口的示例 Controller层 Service层 Mapper层 参数校验 但是同样存在一…

C++自研游戏引擎-碰撞检测组件-八叉树AABB检测算法实现

八叉树碰撞检测是一种在三维空间中高效处理物体碰撞检测的算法&#xff0c;其原理可以类比为一个管理三维空间物体的智能系统。这个示例包含两个部分&#xff1a;八叉树部分用于宏观检测&#xff0c;AABB用于微观检测。AABB可以更换为均值或节点检测来提高检测精度。 八叉树的…

Spring框架中都用到了哪些设计模式?

大家好&#xff0c;我是锋哥。今天分享关于【Spring框架中都用到了哪些设计模式&#xff1f;】面试题。希望对大家有帮助&#xff1b; Spring框架中都用到了哪些设计模式&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring框架中使用了大量的设计模…

Day1 25/2/14 FRI

【一周刷爆LeetCode&#xff0c;算法大神左神&#xff08;左程云&#xff09;耗时100天打造算法与数据结构基础到高级全家桶教程&#xff0c;直击BTAJ等一线大厂必问算法面试题真题详解&#xff08;马士兵&#xff09;】https://www.bilibili.com/video/BV13g41157hK?p3&v…

软考高级《系统架构设计师》知识点(一)

计算机硬件 校验码 码距&#xff1a;就单个编码A:00而言&#xff0c;其码距为1&#xff0c;因为其只需要改变一位就变成另一个编码。在两个编码中&#xff0c;从A码到B码转换所需要改变的位数称为码距&#xff0c;如A:00要转换为B:11&#xff0c;码距为2。一般来说&#xff0c;…

DeepSeek免费部署到WPS或Office

部署到WPS - 通过OfficeAI插件接入&#xff1a; - 准备工作&#xff1a;安装最新版本的WPS Office软件&#xff1b;访问DeepSeek官网&#xff0c;点击右上角的“API开放平台”&#xff0c;登录账号&#xff08;若无账号需先注册&#xff09;&#xff0c;登录成功后&#xff0c;…

基于vue3实现的课堂点名程序

设计思路 采用vue3实现的课堂点名程序&#xff0c;模拟课堂座位布局&#xff0c;点击开始点名按钮后&#xff0c;一朵鲜花在座位间传递&#xff0c;直到点击结束点名按钮&#xff0c;鲜花停留的座位被点名。 课堂点名 座位组件 seat.vue <script setup>//组合式APIimpo…