yolov8+paddleocr的车牌识别
yolov8+ocr的车牌识别
·
车牌识别的数据集比较好找,有很多标注好的数据集,直接使用yolo训练。
训练之后我们就可以对图片中的车牌进行检测,将检测到的车牌依次给到ocr进行文字提取,就可以实现简洁的车牌识别了。
一、训练
下面代码是我的训练代码:
# -*- coding: utf-8 -*-
from ultralytics import YOLO
import torch
def safe_cuda_check():
"""安全获取CUDA信息避免触发断言错误"""
try:
return torch.cuda.is_available(), torch.cuda.current_device() if torch.cuda.is_available() else None
except AssertionError:
return False, None
def main():
# --------------------- 初始化设置 ---------------------
print(f"PyTorch版本: {torch.__version__}")
cuda_available, cuda_device = safe_cuda_check()
print(f"可用GPU: {cuda_available} | 当前设备: {cuda_device if cuda_available else 'CPU'}")
# --------------------- 模型加载 ---------------------
model = YOLO('yolov8n.pt') # 加载预训练模型
# --------------------- 训练配置(含数据增强) ---------------------
train_args = {
# 基础配置
'data': './data/data.yaml',
'epochs': 200,
'batch': 64,
'imgsz': 640,
'imgsz': [512, 768], # YOLOv8多尺度训练:512~768随机缩放(32的倍数)
'rect': False, # 关闭矩形训练,强制随机缩放
'device': '0' if cuda_available else 'cpu', # 自动适配设备
'workers': 16,
'optimizer': 'SGD',
'lr0': 0.01, # 冻结阶段初始lr(更高,加速收敛)
'lrf': 0.1, # 解冻后Backbone lr=0.001,不再近乎冻结
'weight_decay': 0.0005, # L2正则化系数
'momentum': 0.937, # SGD动量
'dropout': 0.1, # 防止过拟合,随机让模型中 10% 的神经元 “失活”
'patience': 15, # 早停耐心值
'freeze': 10, # 冻结Backbone前10层,先训练50epoch再解冻
'amp': True, # 混合精度训练,减少显存占用
'save_best': True, # 保存验证集最优模型,避免早停错过最佳效果
'label_smoothing': 0.1, # 标签平滑,防过拟合
# --------------------- 数据增强参数 ---------------------
# 色彩空间增强(HSV调整)
'hsv_h': 0.015, # 色相调整幅度(0-1),越大色彩变化越明显
'hsv_s': 0.7, # 饱和度调整幅度(0-1)
'hsv_v': 0.4, # 明度调整幅度(0-1)
# 几何变换增强
'degrees': 5.0, # 随机旋转角度(-5°到5°),车牌可适当减小(避免文字颠倒)
'translate': 0.1, # 随机平移比例(相对于图像宽高,0-1)
'shear': 1.0, # 随机剪切角度(-1°到1°)
# 翻转增强
'fliplr': 0.5, # 左右翻转概率(需注意车牌是否对称,如无方向性可设0.5)
# 高级混合增强
'mosaic': 0.5, # Mosaic增强概率(0-1,将4张图拼接,增强背景多样性)
}
# 启动训练
model.train(** train_args)
if __name__ == '__main__':
main()
二、paddleocr文字识别
ocr已经在python中有库函数了,可以直接调用,代码如下,使用训练好的best.pt进行检测车牌:
import os
os.environ['YOLO_VERBOSE'] = 'False'
os.environ['YOLO_DEBUG'] = 'False'
import warnings
warnings.filterwarnings('ignore') # 全局屏蔽所有警告
import cv2
import numpy as np
from ultralytics import YOLO
from paddleocr import PaddleOCR
import matplotlib.pyplot as plt
import matplotlib
# 解决 Matplotlib 中文乱码
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 黑体
matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 初始化 PaddleOCR
ocr = PaddleOCR(use_angle_cls=True, lang="ch", show_log=False)
# 车牌检测模型
path = 'runs/weights/best.pt'
img_path = "test_images/2.jpg"
model = YOLO(path)
# 读取原始图像
original_image = cv2.imread(img_path)
# 运行 YOLO 车牌检测
results = model(img_path, verbose=False, conf=0.7)
# 透视变换
def four_point_transform(image, pts):
rect = np.array(pts, dtype="float32")
width = int(np.linalg.norm(rect[1] - rect[0]))
height = int(np.linalg.norm(rect[3] - rect[0]))
dst = np.array([
[0, 0],
[width - 1, 0],
[width - 1, height - 1],
[0, height - 1]], dtype="float32")
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(image, M, (width, height))
return warped
a=1
# 遍历检测到的车牌
for result in results[0].boxes.xyxy:
x1, y1, x2, y2 = map(int, result[:4])
# 增加 padding
padding = 10
x1, y1 = max(x1 - padding, 0), max(y1 - padding, 0)
x2, y2 = min(x2 + padding, original_image.shape[1] - 1), min(y2 + padding, original_image.shape[0] - 1)
cropped_image = original_image[y1:y2, x1:x2]
# 透视变换
pts = np.array([
[x1, y1],
[x2, y1],
[x2, y2],
[x1, y2]
], dtype="float32")
warped_image = four_point_transform(original_image, pts)
# OCR 识别车牌
result = ocr.ocr(warped_image, cls=True)
print(result)
if result and result != [None]:
plate_text = "".join([word[1][0] for line in result for word in line])
# 显示结果
plt.figure(figsize=(8, 4))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(cropped_image, cv2.COLOR_BGR2RGB))
plt.title("检测到的车牌")
plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(warped_image, cv2.COLOR_BGR2RGB))
plt.title(f"识别结果: {plate_text}")
a+=1
plt.show()
else:
print(f"第{a}辆未检测到车牌文字。")
a+=1
continue
下面是paddleocr的介绍(我的理解就是一个训练好的文字检测+识别模型):
这个库在使用时,环境可以有点严格(反正我碰到了兼容问题),下面是我的版本(仅供参考):
python 3.10.19
numpy 1.23.0
opencv-python 4.6.0.66
paddleocr 2.7.3
PaddleOCR 是一个由百度 PaddlePaddle 团队开发的、开源的、功能丰富的 OCR(光学字符识别)工具库。它的文字识别功能是其核心能力之一,旨在准确地将图像中的文字内容转换为机器可读的文本。
主要功能模块:
-
文本检测:
- 这是文字识别的前提步骤。
- 目标是在输入图像中定位出包含文字的区域(通常用矩形框标出)。
- PaddleOCR 提供了多种先进的文本检测模型,例如 DB (Differentiable Binarization) 算法,它擅长处理各种复杂场景下的文本定位,如弯曲文本、密集文本等。
-
文本方向校正:
- 在实际应用中,图像中的文字可能不是水平排列的(例如旋转的文档、倾斜拍摄的照片)。
- 方向校正模块会自动检测文本行的方向角度,并将其旋转至水平方向,为后续的文字识别提供标准的输入。
-
文字识别:
- 这是核心功能模块。
- 接收经过检测和校正后的单个文本行图像(或整个文本区域)。
- 利用深度学习模型(如 CRNN - Convolutional Recurrent Neural Network,或基于 Transformer 的模型 SVTR)分析图像中的像素信息,识别出具体的字符序列。
- 支持多种语言:除了中文和英文,还支持其他多种语言的识别。
- 支持多种字体:能够识别印刷体、手写体(效果可能因手写质量而异)。
- 支持不同场景:对自然场景图像(街景招牌、菜单等)、扫描文档、手机拍摄的图片等都有较好的适应性。
技术特点:
- 高精度: 基于深度学习,在多个公开和内部数据集上达到了业界领先或极具竞争力的识别精度。
- 高性能: 模型经过优化,支持 CPU 和 GPU 推理,识别速度快。
- 轻量化模型: 提供不同大小的模型(如轻量级模型 PP-OCR、高精度模型 PP-OCRv2/v3),用户可以在速度和精度之间做权衡选择。
- 端到端训练与推理: 虽然检测、方向校正、识别是分开的步骤,但 PaddleOCR 提供了将这些步骤串联起来的端到端推理流程。
- 开源免费: 代码、预训练模型完全开放,方便研究和商用。
- 中文场景优化: 在中文文本识别方面表现尤为出色。
- 良好的扩展性: 支持用户使用自己的数据集进行微调训练,以满足特定场景的需求。
更多推荐
所有评论(0)