摘要:开发手写数字和符号识别对于智能交互系统具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个手写数字和符号识别,并提供了完整的实现代码。该系统基于强大的YOLOv8算法,并对比了YOLOv7YOLOv6YOLOv5,展示了不同模型间的性能指标,如mAPF1 Score等。文章深入解释了YOLOv8的原理,提供了相应的Python代码训练数据集,并集成了一个基于PySide6的界面。

系统能够精准检测和识别手写数字和符号,支持通过图片图片文件夹视频文件摄像头进行检测,包含柱状图分析标记框类别类别统计、可调ConfIOU参数结果可视化等功能。还设计了基于SQLite的用户管理界面,支持模型切换UI自定义。本文旨在为深度学习初学者提供实用指导,代码和数据集见文末。本文结构如下:

➷点击跳转至文末所有涉及的完整代码文件下载页☇

基于深度学习的手写数字和符号识别系统演示与介绍(YOLOv8/v7/v6/v5模型+PySide6界面+训练数据集)


前言

        手写数字和符号识别技术,作为计算机视觉和模式识别领域的一个重要分支,近年来在学术界和工业界均受到广泛关注。这项技术旨在通过计算机系统自动识别和解析手写的数字和符号,它在多个领域中有着广泛的应用,如自动表单处理、银行支票自动识别、智能交互系统等。随着人工智能技术的快速发展,手写识别技术已经从简单的模板匹配演进到利用深度学习方法,特别是卷积神经网络(CNN)和循环神经网络(RNN)等先进技术,极大地提高了识别的准确率和效率。

在这里插入图片描述

        研究手写数字和符号识别的意义不仅仅在于技术本身的提升,更在于它对推动自动化、智能化进程的贡献。在数字化时代,数据输入和处理的效率直接影响到信息技术的应用广度和深度。通过优化手写识别技术,我们不仅可以提升数据处理速度,还能够在一定程度上缓解人工输入的繁琐,为用户提供更加便捷的交互体验。此外,随着深度学习模型,尤其是YOLO1(You Only Look Once)系列模型的发展,我们见证了在实时处理和高准确度识别方面的显著进步。

        YOLO系列模型,从YOLOv1发展到最新的YOLOv82,不断在速度和准确性之间寻求最佳平衡。YOLOv5作为系列中的一个重要版本,已经被应用于多个手写识别任务中,展现了其强大的实时处理能力。随后,研究人员进一步提出YOLOv63和YOLOv74,这些版本在网络架构、训练策略和优化算法方面进行了显著改进,以适应更加复杂的图像识别场景。特别是,YOLOv8的推出,其通过引入更加先进的注意力机制和改进的损失函数,极大提高了对手写字符的识别精度。

        除了YOLO系列,其他深度学习模型如卷积递归神经网络(CRNN)和长短期记忆网络(LSTM)也在手写识别任务中发挥了重要作用。这些模型能够有效处理序列数据,使其特别适用于连续手写文字的识别。近期的研究表明,结合CNN和RNN的混合模型能够进一步提升识别性能,尤其是在处理具有复杂背景或不同书写风格的手写文字时。

        视觉变换器(ViT)作为一种基于自注意力机制的图像识别模型,也在手写识别任务中显示出其独特的优势。ViT通过将图像切割成多个小块并将它们作为序列输入到基于自注意力的网络中,能够捕捉到图像的全局依赖关系,从而在没有大量卷积层的情况下也能达到甚至超过传统CNN模型的性能。这种能力使ViT特别适合处理具有复杂背景和风格多样性的手写图像识别任务。

        MMDetection作为一个开源的目标检测工具箱,提供了包括YOLOv55、YOLOv6以及其他许多先进的目标检测算法的实现。它不仅为研究人员和开发者提供了一个灵活高效的平台来探索和实验不同的检测模型,也促进了手写数字和符号识别等领域的技术进步。通过MMDetection,研究人员能够轻松测试和比较不同算法的性能,加速新技术在实际应用中的落地。

        本博客所做的工作是基于YOLOv8算法构建一个手写数字和符号识别,展示系统的界面效果,详细阐述其算法原理,提供代码实现,以及分享该系统的实现过程。希望本博客的分享能给予读者一定的启示,推动更多的相关研究。本文的主要贡献如下:

  1. 采用最先进的YOLOv8算法进行手写数字和符号识别:本文详细介绍了YOLOv8算法在手写数字和符号识别中的应用,突出了其相较于YOLOv7、YOLOv6、YOLOv5等早期版本在效率和精准度方面的显著优势。通过对比分析,本文为读者展示了YOLOv8在处理复杂手写样本方面的强大能力,为相关领域的研究者和实践者提供了新的研究思路和实践手段。
  2. 利用PySide6实现用户友好的手写数字和符号识别系统:通过利用Python的PySide6库,本文成功开发了一个界面友好、操作直观的手写数字和符号识别系统。该系统不仅提高了用户的交互体验,还促进了YOLOv8算法的广泛应用,推动了手写数字和符号识别技术的实际应用进程。
  3. 集成登录管理功能,提升系统安全性:本文设计并实现了一个登录管理功能,要求用户在使用系统前进行身份验证。这一设计不仅增强了系统的安全性,也为未来引入更多个性化服务和功能奠定了基础。
  4. 对YOLOv8模型进行深入研究和评估:本文不仅介绍了YOLOv8算法在手写数字和符号识别任务中的应用,还对其性能进行了全面的评估,包括精度、召回率等关键指标的详细分析。这一部分的研究为理解和优化YOLOv8算法提供了宝贵的见解和数据支持。
  5. 提供完整的数据集和代码资源包:为了帮助读者更好地理解和应用本文介绍的技术和方法,本博客提供了一套完整的数据集和代码资源包。这些资源不仅包括用于训练和测试的详尽数据集,还有实现手写数字和符号识别的完整代码,使得读者能够轻松复现实验结果,并在此基础上进行进一步的研究和开发。

1. 数据集介绍

        在本研究中,我们采用了一个综合性的手写数字和符号识别数据集,总计包含7128张图像,具体分为4869张训练图像、1636张验证图像以及623张测试图像。这一划分确保了数据集在模型训练、验证和测试阶段的广泛覆盖,旨在通过不同的数据样本,从多角度验证模型的鲁棒性和泛化能力。

在这里插入图片描述

        所有的图像在送入模型进行训练之前,均经过了规范化处理,调整至统一的640x640像素分辨率。我们选择了拉伸方法来调整所有图像的尺寸,尽管这可能导致一定程度的形状变形,但可以保证图像的完整性,避免了因裁剪或填充操作而可能引起的信息丢失。这一预处理步骤对于后续模型的学习过程至关重要,因为它为模型提供了规格一致的输入数据。

        为了进一步增强模型的识别能力,数据集同样经过了丰富的增强处理。这包括对图像的尺寸、角度、光照等进行随机调整,以此来模拟实际应用中可能遇到的各种变化,增加模型训练的复杂度。通过这种方式,模型能够学习到更为泛化的特征,从而提升在实际应用中对于手写数字和符号的识别准确性。

在这里插入图片描述

        在数据集标注方面,我们对每张图像中的手写数字和符号进行了精确的边界框定位,并赋予了相应的类别标签。数据集中不仅包含了0到9的数字实例,还涵盖了常见的数学运算符,如加号、减号、乘号和除号。标注过程中的精细度确保了模型训练的高质量监督信号,为识别模型的训练奠定了坚实的基础。博主使用的类别代码如下:

Chinese_name = { "0": "0",  # 数字 0
    "1": "1",  # 数字 1
    "2": "2",  # 数字 2
    "3": "3",  # 数字 3
    "4": "4",  # 数字 4
    "5": "5",  # 数字 5
    "6": "6",  # 数字 6
    "7": "7",  # 数字 7
    "8": "8",  # 数字 8
    "9": "9",  # 数字 9
    "div": "除",  # 除法运算符
    "eqv": "等于",  # 等于运算符
    "minus": "减",  # 减法运算符
    "mult": "乘",  # 乘法运算符
    "plus": "加"  # 加法运算符}

        通过对数据集分布的分析,我们可以观察到不同类别的实例数量大致均衡,这有助于模型学习到均衡的特征表示,避免了某些类别过于主导最终的识别结果。同时,我们还可以看到边界框的位置分布相对集中在图像的中心区域,这可能是因为大多数人在书写时的习惯性偏好。此外,边界框的大小分布显示出一定的集中趋势,说明数据集中的手写数字和符号在尺寸上具有一定的一致性,而这一点对于训练尺寸不变性较强的模型特别有价值。

        综上所述,这个丰富且经过精心准备的数据集,不仅在数量上满足了深度学习模型的需求,而且在质量和多样性上也为开发出高性能的手写数字和符号识别系统提供了坚实的基础。预处理和增强处理的策略,精确的标注信息,以及对数据分布的深入分析,共同确保了数据集能够有效支撑本研究的目标。

2. 系统界面效果

        系统以PySide6作为GUI库,提供了一套直观且友好的用户界面。下面,我将详细介绍各个主要界面的功能和设计。

(1)系统提供了基于SQLite的注册登录管理功能。用户在首次使用时需要通过注册界面进行注册,输入用户名和密码后,系统会将这些信息存储在SQLite数据库中。注册成功后,用户可以通过登录界面输入用户名和密码进行登录。这个设计可以确保系统的安全性,也为后续添加更多个性化功能提供了可能性。

在这里插入图片描述

(2)在主界面上,系统提供了支持图片、视频、实时摄像头和批量文件输入的功能。用户可以通过点击相应的按钮,选择要进行手写数字和符号识别的图片或视频,或者启动摄像头进行实时检测。在进行检测时,系统会实时显示检测结果,并将检测记录存储在数据库中。

在这里插入图片描述

(3)此外,系统还提供了一键更换YOLOv8模型的功能。用户可以通过点击界面上的"更换模型"按钮,选择不同的YOLOv8模型进行检测。与此同时,系统附带的数据集也可以用于重新训练模型,以满足用户在不同场景下的检测需求。

在这里插入图片描述

(4)为了提供更个性化的使用体验,这里系统支持界面修改,用户可以自定义图标、文字等界面元素。例如,用户可以根据自己的喜好,选择不同风格的图标,也可以修改界面的文字描述。

在这里插入图片描述


3. YOLOv8算法原理

        YOLOv8的算法原理沿袭了YOLO系列一贯的设计哲学,同时引入了一系列创新性的技术以进一步提升模型的性能。首先,它的Neck部分采用了SPP(Spatial Pyramid Pooling)结构和FPN(Feature Pyramid Networks)技术。SPP通过在不同尺度上池化特征来增强模型的空间不变性,这意味着模型能够更好地处理不同大小和比例的目标对象。而FPN通过构建一个多尺度的特征金字塔,使得模型可以有效地检测到各种尺度的目标,这对于手写数字和符号识别来说尤其重要,因为它们在尺寸和形状上存在较大的变化。

        YOLOv8的Head部分则引入了自适应标签分配(adaptive label assignment)机制。在传统的目标检测算法中,标签通常是固定分配的,但YOLOv8通过自适应机制可以更智能地为每个预测框分配最合适的标签。这种方法有助于提升模型在复杂情境下的识别精度,降低模型对于背景噪声的敏感度,并优化整体的性能。

在这里插入图片描述

        此外,YOLOv8还融合了AutoML技术,自动化地调整网络结构和超参数,以寻找最优的模型配置。这意味着模型可以在训练过程中自我优化,不断改进其结构以适应手写数字和符号识别任务的具体需求。YOLOv8通过这种方法能够更加精细地捕捉到手写特征,提升模型在实际应用中的鲁棒性和准确性。

        YOLOv8的设计充分考虑了实时性的需求,不仅保留了YOLO系列一贯的快速检测能力,同时还引入了CSP(Cross Stage Partial networks)结构,进一步优化了网络中的信息流动和参数的利用效率。通过这些创新,YOLOv8在保持高速度处理的同时,也显著提升了检测的准确性。

        YOLOv8作为当前目标检测领域的前沿技术,其原理涵盖了多尺度特征提取、自适应标签分配、自动化网络结构和超参数优化等方面,体现了YOLOv8在手写数字和符号识别任务上的强大能力。通过这些技术的融合和应用,YOLOv8不仅在精度上得到了提升,同时在速度和效率上也做到了优化,确保了其在实际应用中的高效性。

4. 代码简介

        在本节中,我们将详细介绍如何使用YOLOv8进行手写数字和符号识别的代码实现。代码主要分为两部分:模型预测和模型训练。

4.1 模型预测

        在模型预测部分,首先导入了OpenCV库和YOLO模型。OpenCV库是一个开源的计算机视觉和机器学习软件库,包含了众多的视觉处理函数,使用它来读取和处理图像。YOLO模型则是要用到的目标检测模型。

import cv2  
from ultralytics import YOLO  

        接着,加载自行训练好的YOLO模型。这个模型是在大量的图像上预训练得到的,可以直接用于目标检测任务。

model.load_model(abs_path("weights/best-yolov8n.pt", path_type="current"))

        然后,使用OpenCV读取了一个图像文件,这个图像文件作为要进行目标检测的图像输入。

img_path = abs_path("test_media/1.jpg")
image = cv_imread(img_path)

        在读取了图像文件之后,将图像大小调整为850x500,并对图像进行预处理,就可以使用模型进行预测了。

image = cv2.resize(image, (850, 500))
pre_img = model.preprocess(image) 
pred, superimposed_img = model.predict(pre_img) 

在这里插入图片描述

4.2 模型训练

        在本博客中,我们将深入剖析如何利用YOLOv8,来训练一个高效的手写数字和符号识别系统。

        为了让机器学习模型理解我们的任务——识别手写数字和符号,我们需要提供大量标注好的数据。代码的起始部分是准备这些数据和设定训练环境。我们首先设定训练所需的资源,包括计算设备(是否有GPU支持),工作进程数以及批次大小。计算设备的选择会直接影响到训练速度,而工作进程数和批次大小则会影响数据加载的效率。

        首先,我们导入了必要的模块,并设置了训练设备。torch.cuda.is_available()是检查CUDA(GPU支持)是否可用的标准方法。如果可以利用GPU进行训练,我们将device设置为"cuda:0",这将大大加速我们的训练过程。如果不可用,则使用CPU进行训练。

import os

import torch
import yaml
from ultralytics import YOLO  # 导入YOLO模型
from QtFusion.path import abs_path
device = "cuda:0" if torch.cuda.is_available() else "cpu"

        接着,我们设定了数据集的名称,然后构建了配置文件的路径。为了确保路径在不同操作系统中的兼容性,我们将其转换为UNIX风格的路径。这是一个很小但很重要的细节,因为它避免了因路径错误而造成的问题。

workers = 1
batch = 8

data_name = "NumberOps"
data_path = abs_path(f'datasets/{data_name}/{data_name}.yaml', path_type='current')  # 数据集的yaml的绝对路径
unix_style_path = data_path.replace(os.sep, '/')

# 获取目录路径
directory_path = os.path.dirname(unix_style_path)')

        接下来,我们获取了YAML文件所在的目录路径,并且读取了YAML文件内容。如果配置数据中包含path,我们将其更新为目录路径。这是为了确保我们的模型训练可以定位到正确的数据路径。

# 读取YAML文件,保持原有顺序
with open(data_path, 'r') as file:
    data = yaml.load(file, Loader=yaml.FullLoader)
# 修改path项
if 'path' in data:
    data['path'] = directory_path
    # 将修改后的数据写回YAML文件
    with open(data_path, 'w') as file:
        yaml.safe_dump(data, file, sort_keys=False)

        在加载预训练模型的部分,我们加载了预训练模型,随后启动了训练过程。这部分代码通过指定数据集配置文件路径、训练设备、工作进程数、图像尺寸、训练周期和批次大小等参数,调用了model.train方法来开始训练。

model = YOLO(abs_path('./weights/yolov5nu.pt', path_type='current'), task='detect')  # 加载预训练的YOLOv8模型
# model = YOLO('./weights/yolov5.yaml', task='detect').load('./weights/yolov5nu.pt')  # 加载预训练的YOLOv8模型
# Training.
results = model.train(  # 开始训练模型
    data=data_path,  # 指定训练数据的配置文件路径
    device=device,  # 自动选择进行训练
    workers=workers,  # 指定使用2个工作进程加载数据
    imgsz=640,  # 指定输入图像的大小为640x640
    epochs=120,  # 指定训练100个epoch
    batch=batch,  # 指定每个批次的大小为8
    name='train_v5_' + data_name  # 指定训练任务的名称
)

model = YOLO(abs_path('./weights/yolov8n.pt'), task='detect')  # 加载预训练的YOLOv8模型
results2 = model.train(  # 开始训练模型
    data=data_path,  # 指定训练数据的配置文件路径
    device=device,  # 自动选择进行训练
    workers=workers,  # 指定使用2个工作进程加载数据
    imgsz=640,  # 指定输入图像的大小为640x640
    epochs=120,  # 指定训练100个epoch
    batch=batch,  # 指定每个批次的大小为8
    name='train_v8_' + data_name  # 指定训练任务的名称
)

        在手写数字和符号识别领域,对训练过程的损失函数进行分析是至关重要的。它不仅反映了模型学习的状况,还指示了模型的性能可能存在的问题。

        首先,训练损失(包括边界框损失train/box_loss,类别损失train/cls_loss,以及目标函数损失train/obj_loss)和验证损失(val/box_loss,val/cls_loss,val/obj_loss)随着训练周期的增加而逐渐下降,并且训练损失和验证损失的曲线都相当平滑,这表明模型在学习过程中稳定提升,未出现明显的过拟合或欠拟合现象。在训练的初期,损失迅速下降,这通常表明模型能够迅速从数据中学习。随着时间的推移,损失下降的速度减缓,说明模型开始达到它的学习能力极限。

        精确度(Precision)和召回率(Recall)的图表显示出模型在这两个方面都取得了极高的表现,特别是召回率接近于1的值,这意味着模型能够几乎检测到所有的正类别实例。然而,我们也需要注意精确度和召回率之间的平衡,因为模型倾向于召回更多的实例有时会牺牲精确度,导致更多的误报。

在这里插入图片描述

        mAP(平均精确度均值)指标为我们提供了模型性能的综合视图。从metrics/mAP50和metrics/mAP50-95可以看出,模型的mAP值在训练过程中稳步提升,这说明模型的整体识别性能随着训练的进行而提高。特别是mAP50-95的提升更为显著,这个指标计算了在不同IoU(交并比)阈值下的mAP,能更全面地反映模型对目标检测任务的准确性。

        在深度学习模型的评估过程中,精确度-召回率(Precision-Recall,简称PR)曲线是衡量模型性能的重要工具,特别是在目标检测任务中,它能够揭示模型对于不同类别目标检测能力的细致情况。根据提供的PR曲线图,我们可以对YOLOv8模型在手写数字和符号识别任务上的性能进行专业分析。

在这里插入图片描述

        从图中我们可以看到,不同类别的准确率普遍非常高,几乎都接近或达到了1.0。这意味着模型在识别手写数字和符号时的精确性非常高,当它判断某个检测到的对象属于特定类别时,这个判断几乎总是正确的。同时,召回率也几乎为1.0,这表明模型能够检测到几乎所有的正类别实例。

        具体来看,数字类别的准确率和召回率都非常接近1.0,显示出模型对于手写数字的识别能力极强,几乎没有出现漏检或误检。对于符号类别('div’表示除号,'minus’表示减号,'mult’表示乘号,'plus’表示加号),尽管准确率和召回率略低于数字类别,但仍然在0.975到0.989之间,这同样表现出模型在符号识别上的优秀能力。一般来说,符号识别可能会比数字识别更加复杂,因为符号的形状和大小差异通常比数字大,但这里的高准确率和召回率表明模型同样在这一任务上表现出色。

         所有类别的平均准确率(mAP@0.5)达到了0.991,这个指标是在IoU阈值为0.5时计算的,也就是说,只要预测框和真实框的交并比达到0.5,就认为是正确的检测。这一高值表明,模型在大多数情况下能够准确地定位和识别对象。

         综上所述,这幅PR曲线图清楚地展示了我们的模型在手写数字和符号识别任务上的出色表现。这种高水平的性能意味着模型在实际应用中,如自动表单读取、智能文档分析等场景中,有望实现高效准确的自动识别功能。

4.3 YOLOv5、YOLOv6、YOLOv7和YOLOv8对比

(1)实验设计
在这里插入图片描述

        本实验旨在评估和比较YOLOv5、YOLOv6、YOLOv7和YOLOv8几种模型在手写数字和符号识别任务上的性能。为了实现这一目标,博主分别使用使用相同的数据集训练和测试了这四个模型,从而可以进行直接的性能比较。本文将比较分析四种模型,旨在揭示每种模型的优缺点,探讨它们在工业环境中实际应用的场景选择。

模型图像大小 (像素)mAPval 50-95CPU ONNX 速度 (毫秒)A100 TensorRT 速度 (毫秒)参数数量 (百万)FLOPs (十亿)
YOLOv5nu64034.373.61.062.67.7
YOLOv8n64037.380.40.993.28.7
YOLOv6N64037.5--4.711.4
YOLOv7-tiny64037.4--6.0113.1

(2)度量指标

  • F1-Score:F1-Score是精确率(Precision)和召回率(Recall)的调和平均值。精确率是指模型正确识别的正例与所有识别为正例的案例之比,而召回率是指模型正确识别的正例与所有实际正例之比。F1-Score对于不平衡的数据集或者需要同时考虑精确率和召回率的任务特别重要。
  • mAP(Mean Average Precision):mAP是衡量模型在多个类别上平均检测准确度的指标。它计算了模型在所有类别上的平均精度,是目标检测领域中常用的性能度量。
名称YOLOv5nuYOLOv6nYOLOv7-tinyYOLOv8n
mAP0.9910.9930.9920.992
F1-Score0.990.990.990.99

(3)实验结果分析

        在深度学习领域,持续的算法迭代和更新是提升模型性能的关键途径。我们通过在相同的数据集上实施一系列实验,旨在比较和评估不同版本的YOLO模型——包括YOLOv5nu、YOLOv6n、YOLOv7-tiny以及YOLOv8n——在手写数字和符号识别任务上的性能。实验的设计和目的是为了明确各版本模型在准确性和检测效率上的差异,以便为实际应用提供更具指导性的见解。

        在我们的实验中,YOLOv5nu达到了0.991的mAP,这表明它在检测任务上具有极高的准确度。YOLOv6n则略有提升,mAP为0.993,这可能是由于算法改进和更优化的网络结构。YOLOv7-tiny的mAP为0.992,与YOLOv5nu相近,但鉴于其为"tiny"版本,这一结果说明在保持较小模型大小的同时依然保持了很高的准确度。而YOLOv8n的mAP也为0.992,这与YOLOv7-tiny相同,意味着最新版本的模型在保持高准确度的同时,可能在其他方面有所改进,例如推理速度或模型大小。

        接下来,我们关注F1-Score,这是精确度和召回率的调和平均,能够综合反映模型的性能。在这项指标上,所有模型都达到了0.99的F1-Score,这表明不仅每个模型的精确度都非常高,而且它们能够成功地检测到大部分正类别实例。

在这里插入图片描述

        通过这些数据,我们可以观察到YOLO系列各版本之间在性能上的微小差异。尽管在F1-Score上表现一致,但mAP指标显示了YOLOv6n在这组实验中略胜一筹。这可能归因于算法上的细微改进或是对特定数据集特征的更好利用。值得注意的是,这些模型版本之间的性能差异非常小,这表明YOLO算法在其迭代中保持了稳定的性能提升,即便是在极为挑战性的手写数字和符号识别任务上。

        总结来说,这些实验结果向我们展示了YOLO系列模型强大而稳定的性能。随着版本的迭代更新,我们看到了算法的逐步优化和微调,而这些变化虽细微,但却是模型性能提升的体现。对于未来的研究者和开发者来说,这些结果提供了宝贵的参考,帮助他们根据自己的应用场景和需求选择合适的模型版本。

4.4 代码实现

        在深度学习的实践应用中,构建一个有效的图像识别系统不仅要依赖强大的模型,还需要将模型嵌入到能与用户互动的前端应用中。本博客将介绍如何将YOLOv8模型集成到一个基本的图像识别应用中,该应用能够在用户界面中实时显示检测结果。我们的目标是创建一个用户友好的窗口界面,该界面可以展示模型在处理实时图像时的性能,包括识别出的对象及其置信度。

(1)引入必要的库
        首先,我们需要导入一系列Python库,以支持图像处理、模型操作和用户界面的构建。random库用于生成随机颜色以区分不同的识别对象,sys用于接入系统相关的接口,time用于记录操作的时间,cv2即OpenCV库,是处理图像的强大工具,PySide6则是用于构建图形用户界面的库。

import random  # 导入random模块,用于生成随机数
import sys  # 导入sys模块,用于访问与Python解释器相关的变量和函数
import time  # 导入time模块,用于处理时间
from QtFusion.config import QF_Config
import cv2  # 导入OpenCV库,用于处理图像
from QtFusion.widgets import QMainWindow  # 从QtFusion库中导入FBaseWindow类,用于创建窗口
from QtFusion.utils import cv_imread, drawRectBox  # 从QtFusion库中导入cv_imread和drawRectBox函数,用于读取图像和绘制矩形框
from PySide6 import QtWidgets, QtCore  # 导入PySide6库中的QtWidgets和QtCore模块,用于创建GUI
from QtFusion.path import abs_path
from YOLOv8Model import YOLOv8Detector  # 从YOLOv8Model模块中导入YOLOv8Detector类,用于加载YOLOv8模型并进行目标检测
from datasets.NumberOps.label_name import Label_list

QF_Config.set_verbose(False)

(2)初始化模型
        接下来,代码初始化了一个YOLOv8模型实例,并加载了预先训练好的模型权重。这个步骤对于后续的图像识别至关重要,因为没有加载正确的模型权重,我们将无法利用YOLOv8的强大功能来识别图像中的对象。

cls_name = Label_list  # 定义类名列表
colors = [[random.randint(0, 255) for _ in range(3)] for _ in range(len(cls_name))]  # 为每个目标类别生成一个随机颜色

model = YOLOv8Detector()  # 创建YOLOv8Detector对象
model.load_model(abs_path("weights/best-yolov8n.pt", path_type="current"))  # 加载预训练的YOLOv8模型

(3)设置主窗口
        为了能够有效地与用户交互,我们创建了一个名为MainWindow的类,它继承自QMainWindow。这个类的构造函数中定义了窗口的大小,并初始化了一个用于显示图像的QLabel。此外,还有一个处理键盘事件的函数,允许用户通过按下Q键来退出应用程序。

class MainWindow(QMainWindow):  # 定义MainWindow类,继承自FBaseWindow类
    def __init__(self):  # 定义构造函数
        super().__init__()  # 调用父类的构造函数
        self.resize(640, 640)  # 设置窗口的大小
        self.label = QtWidgets.QLabel(self)  # 创建一个QLabel对象
        self.label.setGeometry(0, 0, 640, 640)  # 设置QLabel的位置和大小

    def keyPressEvent(self, event):  # 定义keyPressEvent函数,用于处理键盘事件
        if event.key() == QtCore.Qt.Key.Key_Q:  # 如果按下的是Q键
            self.close()  # 关闭窗口

(4)主程序流程
        在主函数中,我们实例化了之前定义的MainWindow类,并准备了图像文件的路径。使用OpenCV的函数读取图像,并调整到合适的大小以供模型处理。此外,我们还对图像进行了预处理,这是将图像转换成模型能够理解和处理的格式的必要步骤。

app = QtWidgets.QApplication(sys.argv)  # 创建QApplication对象
window = MainWindow()  # 创建MainWindow对象

img_path = abs_path("test_media/NumberOps_SIXU_A00028.jpg")  # 定义图像文件的路径
image = cv_imread(img_path)  # 使用cv_imread函数读取图像

image = cv2.resize(image, (850, 500))  # 将图像大小调整为850x500
pre_img = model.preprocess(image)  # 对图像进行预处理

        为了评估模型处理图像的时间效率,我们记录了预测开始和结束的时间,并打印出耗时。最后,我们将预测的结果以图形方式展示给用户。如果模型在图像中识别出了对象,就在对象周围绘制一个彩色的边界框,并在框上显示类别名称和置信度。这为用户提供了一种直观的方式来看到模型的识别结果。

t1 = time.time()  # 获取当前时间(开始时间)
pred = model.predict(pre_img)  # 使用模型进行预测
t2 = time.time()  # 获取当前时间(结束时间)
use_time = t2 - t1  # 计算预测所用的时间

det = pred[0]  # 获取预测结果的第一个元素(检测结果)

# 如果有检测信息则进入
if det is not None and len(det):
    det_info = model.postprocess(pred)  # 对预测结果进行后处理
    for info in det_info:  # 遍历检测信息
        # 获取类别名称、边界框、置信度和类别ID
        name, bbox, conf, cls_id = info['class_name'], info['bbox'], info['score'], info['class_id']
        label = '%s %.0f%%' % (name, conf * 100)  # 创建标签,包含类别名称和置信度
        # 画出检测到的目标物
        image = drawRectBox(image, bbox, alpha=0.2, addText=label, color=colors[cls_id])  # 在图像上绘制边界框和标签

print("推理时间: %.2f" % use_time)  # 打印预测所用的时间
window.dispImage(window.label, image)  # 在窗口的label上显示图像
# 显示窗口
window.show()
# 进入 Qt 应用程序的主循环
sys.exit(app.exec())

        通过这些代码,我们展示了如何构建一个完整的图像识别应用,它不仅能够利用YOLOv8的深度学习模型进行准确的对象识别,还能通过图形用户界面与用户进行交互。


5. 手写数字和符号识别实现

        在实现一款实时手写数字和符号识别系统时,我们的核心设计思路是提供一个直观、易用的用户界面(UI),同时背后有强大的图像处理和机器学习模型支持。这种设计不仅使用户可以轻松地与系统交互,还确保了系统的响应速度和准确性能够满足实时识别的需求。

5.1 系统设计思路

        MainWindow类的主要目标是提供一个用户友好的交互式手写数字和符号识别。为了实现这一目标,我们开发了MainWindow类,它是整个应用的中心。在这个类中,我们整合了界面层、处理层和控制层,使得从图像的输入到识别结果的输出,整个流程可以无缝进行。

在这里插入图片描述

架构设计
        我们的系统设计思路以三层架构为核心:处理层、界面层和控制层。在我们的系统设计中,重点放在了确保各个组件能够协同工作,同时保持足够的模块独立性,以便于未来的维护和升级。

  • 处理层(Processing Layer):处理层是系统的核心,负责图像的读取、预处理以及使用YOLOv8Detector进行目标检测和识别。这一层将最新的深度学习技术和算法封装起来,为用户提供了一个强大的后端支持。通过预先训练的模型,系统可以准确快速地识别出图像中的手写数字和符号。
  • 界面层(UI Layer):界面层是用户与系统交互的前端,我们利用了Qt框架强大的UI构建能力,创建了一个简洁而直观的界面。这个界面包括了必要的操作提示和实时显示处理结果的区域。用户可以通过这个界面上传图片,启动识别过程,并在同一界面中获得反馈结果。
  • 控制层(Control Layer):控制层则承担着协调界面层和处理层的任务,确保用户指令能够被正确解释,并触发相应的处理流程。同时,控制层还负责处理模型返回的数据,并将结果展示到界面层,完成用户交互的闭环。

在这里插入图片描述

        此外,我们还引入了信号和槽机制,这是Qt框架中用于不同组件间通信的一种机制。通过信号和槽,我们可以将用户界面中的事件,如按钮点击,与后端处理逻辑相连接,使得用户的每一次操作都能够得到及时且准确的响应。

        通过这样的系统设计,我们保证了用户操作的简便性,处理流程的高效性,以及结果显示的直观性。整个系统设计旨在为用户提供一个高效、准确、易于使用的手写数字和符号识别工具,无论是对于技术和非技术背景的用户都能够轻松上手。

系统流程
        在本博客中,我们将详细探讨构建一个基于YOLOv8模型的交互式手写数字和符号识别的流程。从用户的角度出发,我们着手打造了一个既直观又强大的应用程序,以实现手写内容的自动识别和分类。

在这里插入图片描述

  1. 当用户启动应用程序时,背后发生的第一件事是实例化MainWindow类。这个类是整个应用的核心,负责初始化用户界面、设置参数以及准备系统进行后续的媒体处理任务。它为用户提供了一个操作界面,这个界面是用户与应用程序交互的第一接口,用户可以通过它选择他们的输入源,无论是实时摄像头捕获的图像,还是本地的视频文件和图片。
  2. 选择输入源后,应用程序调用内置的媒体处理器来准备和处理这些输入。对于实时图像,这可能意味着配置摄像头设置;对于视频和图片文件,这涉及到文件的读取和图像的加载。这些步骤确保了无论用户提供何种类型的输入,系统都能够正确地处理和识别。
  3. 在媒体输入源准备就绪之后,系统进入一个连续的处理循环。在这个循环中,每一帧图像都经过一系列预处理步骤,这包括调整大小、转换色彩空间以及进行归一化,以确保图像数据满足YOLOv8模型的输入需求。接着,这些预处理后的图像被送入训练有素的YOLOv8模型进行检测和识别,模型输出包含了手写数字和符号的位置以及识别类别。
  4. 随着检测结果的不断产出,应用程序的界面会实时更新,以图形方式向用户展示检测结果。不仅仅是在图像上绘制检测框和标注类别,系统还会在界面的表格或者图表中展示累计的检测和识别统计数据,为用户提供直观的反馈。
  5. 除了被动地接收来自系统的信息更新,用户还可以通过界面中的按钮进行交互式操作。例如,保存检测结果的快照、获取更多关于应用程序的信息,以及使用下拉菜单来过滤和深入分析特定的识别结果。此外,应用程序还允许用户控制媒体的播放状态,如开始或停止视频的播放,启动或暂停图像分析,从而使用户能够按照自己的节奏进行识别任务。

        总而言之,这个系统的设计思路在于提供一个无缝的用户体验,从轻松选择媒体源,到实时展示精准的识别结果,每个环节都经过深思熟虑,以确保用户在使用应用程序时感到直观和高效。

5.2 登录与账户管理

        在当今的软件应用中,为用户提供安全且个性化的服务体验已经成为一项基本要求。这不仅涉及到用户数据的保护,也关系到如何让用户在使用软件时感到方便、舒适。在我们的交互式手写数字和符号识别系统中,我们深刻理解到这一点,并据此设计了一套完整的用户登录与账户管理功能。

在这里插入图片描述

        此功能的实现基于强大的PySide6框架和可靠的SQLite数据库,不仅确保了界面的友好性和数据处理的安全性,还为用户提供了一系列个性化选项,如账户注册、密码修改、头像设置等。用户在第一次使用系统时,会被引导进行简单的注册流程,创建属于自己的账户。账户创建后,用户可以通过登录界面进入系统,开始他们的手写数字和符号识别任务。

        账户管理功能不仅停留在基本的登录和注册。我们允许用户随时修改自己的密码,增加了账户的安全性。此外,用户还可以设置个人头像,这一小巧思增加了应用的亲和力,也让用户在使用过程中感到更加个性化。如果用户希望注销账户,系统也提供了简单的操作流程,保障用户的数据安全和隐私。

在这里插入图片描述

        此外,我们的系统还为每个用户提供了独立的空间,让他们可以保存和管理自己的检测结果。这些结果不仅可以保存在本地,还可以根据需要进行进一步的分析和共享。在主界面中,用户不仅可以实时看到检测框、类别和置信度等信息,还可以通过简单的操作来处理图片、视频、实时摄像头捕获的图像,以及批量文件。

        这种设计和实现方式,确保了我们的手写数字和符号识别系统不仅仅是一个功能强大的工具,更是一个易于使用、安全且个性化的应用。用户在实时目标检测场景下的各种需求,如数据管理、隐私保护和个性化设置,都可以在这一平台上得到满足。通过不断优化用户体验,我们的系统旨在为用户提供一个既高效又愉悦的使用环境。

下载链接

    若您想获得博文中涉及的实现完整全部资源文件(包括测试图片、视频,py, UI文件,训练数据集、训练代码、界面代码等),这里已打包上传至博主的面包多平台,见可参考博客与视频,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:

在这里插入图片描述

完整资源中包含数据集及训练代码,环境配置与界面中文字、图片、logo等的修改方法请见视频,项目完整文件下载请见演示与介绍视频的简介处给出:➷➷➷

演示与介绍视频:https://www.bilibili.com/video/BV1AW421c7zo/

在这里插入图片描述

    在文件夹下的资源显示如下,下面的链接中也给出了Python的离线依赖包,读者可在正确安装Anaconda和Pycharm软件后,复制离线依赖包至项目目录下进行安装,另外有详细安装教程:(1)Pycharm软件安装教程;(2)Anaconda软件安装教程;(3)Python环境配置教程

离线依赖安装教程:https://www.bilibili.com/video/BV1hv421C7g8/
离线依赖库下载链接:https://pan.baidu.com/s/1y6vqa9CtRmC72SQYPh1ZCg?pwd=33z5 (提取码:33z5)

6. 总结与展望

        在本博客中,我们详细介绍了一个基于YOLOv8模型的实时手写数字和符号识别。系统以模块化的方式设计,充分采用了合理的架构设计,带来良好的可维护性和可扩展性。其用户界面友好,能够提供实时的手写数字和符号识别和识别结果展示,同时支持用户账户管理,以便于保存和管理检测结果和设置。

        该系统支持摄像头、视频、图像和批量文件等多种输入源,能够满足用户在不同场景下的需求。在后面可以添加更多预训练模型,增加检测和识别的种类;优化用户界面,增强个性化设置;并积极聆听用户反馈,以期不断改进系统,以更好地满足用户的需求。


结束语

        由于博主能力有限,博文中提及的方法即使经过试验,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。


  1. Fang W, Wang L, Ren P. Tinier-YOLO: A real-time object detection method for constrained environments[J]. IEEE Access, 2019, 8: 1935-1944. ↩︎

  2. Terven J, Cordova-Esparza D. A comprehensive review of YOLO: From YOLOv1 to YOLOv8 and beyond[J]. arXiv preprint arXiv:2304.00501, 2023. ↩︎

  3. Li C, Li L, Jiang H, et al. YOLOv6: A single-stage object detection framework for industrial applications[J]. arXiv preprint arXiv:2209.02976, 2022. ↩︎

  4. Wang C Y, Bochkovskiy A, Liao H Y M. YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2023: 7464-7475. ↩︎

  5. Wu W, Liu H, Li L, et al. Application of local fully Convolutional Neural Network combined with YOLO v5 algorithm in small target detection of remote sensing image[J]. PloS one, 2021, 16(10): e0259283. ↩︎

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐