摘要:开发手势识别系统对于增强人机交互和智能家居控制领域的体验非常关键。本博客详尽阐述了通过深度学习技术构建手势识别系统的过程,并附上了全套实施代码。系统采用了先进的YOLOv8算法,并通过与YOLOv7、YOLOv6、YOLOv5的性能对比,分析了各模型的关键性能指标,如mAP和F1 Score。文章详细解释了YOLOv8的基本原理,提供了相关的Python代码和训练数据集,并配备了基于PySide6的直观用户界面。
该系统能够准确识别和分类图像中的手势,支持从静态图片、图像文件夹、视频文件和实时摄像头等多种来源进行手势检测。功能包括热力图分析、检测框内手势类别显示、手势类别统计、可调节的置信度和IOU阈值,以及结果的直观展示。系统还包含了一个基于SQLite的用户管理界面,允许用户注册和登录、切换模型和自定义UI界面。本文旨在为深度学习初学者提供一个实用的参考,文末包含了代码和数据集的下载链接,方便读者下载应用。本文结构如下:
文章目录
- 前言
- 1. 数据集介绍
- 2. 系统界面效果
- 3. YOLOv8算法原理
- 4. 代码简介
- 4.1 模型预测
- 4.2 模型训练
- 4.3 YOLOv5、YOLOv6、YOLOv7和YOLOv8对比
- 4.4 代码实现
- 5. 常见手势识别系统实现
- 5.1 系统设计思路
- 5.2 登录与账户管理
- 下载链接
- 6. 总结与展望
- 结束语
➷点击跳转至文末所有涉及的完整代码文件下载页☇
基于深度学习的常见手势识别系统演示与介绍(YOLOv8/v7/v6/v5模型+PySide6界面+训练数据集)
前言
在当今数字化时代,手势识别技术因其直观、自然的交互方式而日益受到关注,尤其是在人机交互、智能家居控制、增强现实、虚拟现实以及辅助驾驶等领域具有广泛的应用前景。手势识别技术的研究意义不仅仅体现在提高交互的自然性和便捷性上,更在于其对于促进无障碍技术的发展,使得身体障碍人士能够更加便捷地与智能设备进行交互,极大地提高了他们的生活质量。此外,随着智能设备性能的不断提升和深度学习技术的不断进步,手势识别系统的应用场景也在不断扩展,如可用于公共安全中的暗示识别、社交互动中的非言语表达等。
近年来,国内外在基于深度学习的手势识别领域已取得了一系列进展。从算法层面,YOLO系列的不断更新为手势识别提供了新的解决方案,例如YOLOv5的轻量化设计使得在移动设备上运行成为可能,而YOLOv81的引入更是在精度和速度上实现了新的突破。在数据集和性能改进方面,通过引入更多样化的数据集和采用数据增强技术,研究者们成功提升了模型的泛化能力和识别准确率。这些进展不仅推动了手势识别技术的研究,也为相关应用的实际部署奠定了基础。
在手势识别技术领域,除了YOLO2系列算法的持续迭代与优化,其他深度学习算法如卷积神经网络(CNN)、循环神经网络(RNN)、以及长短期记忆网络(LSTM)等也在不断地被研究和改进,以适应手势识别的复杂需求。特别是在处理视频序列和动态手势识别方面,结合CNN和RNN的混合模型展现了出色的性能,能够有效捕捉手势的时空特征。此外,Transformer模型因其强大的自注意力机制,在处理序列数据上的优势显著,已开始被应用于手势识别领域,展现了与传统算法不同的新路径和可能性。
数据集的发展对手势识别算法的性能提升同样至关重要。传统手势识别研究多依赖于较小的、特定场景下的数据集,这限制了算法的泛化能力和实际应用范围。近年来,随着数据采集技术的进步和多源数据的整合,大规模、多样化的手势识别数据集逐渐出现,如MSRA手势数据集、CHALET(Cornell Hand Activity through Language and Embodied Transfer)数据集等,这些数据集覆盖了更多的手势类型、更复杂的背景以及不同的光照条件,为手势识别算法的训练和验证提供了丰富的资源。
然而,尽管手势识别技术已取得了显著的进展,但仍面临一系列挑战,如手势多样性大、背景复杂干扰、光照变化、实时性要求高等问题。此外,现有的公开手势识别数据集往往规模有限、多样性不足,限制了算法的泛化能力和性能的进一步提升。因此,研究和开发更高效、更准确、更鲁棒的手势识别系统,不仅对推动人机交互技术的发展具有重要意义,也对智能系统的实用性和普及率的提升具有深远影响。
本博客通过详尽地探讨YOLOv8算法在常见手势识别系统中的应用,为相关领域的研究者和技术实践者提供了一份宝贵的资源和深入的见解。本文的贡献不仅体现在采用先进的深度学习算法进行精确检测,还在于为读者呈现了一个结合了技术深度与实用性的全面研究。具体贡献如下:
- 采用最先进的YOLOv8算法:本研究通过采用YOLOv8算法,展现了在常见手势识别系统中相较于YOLOv73、YOLOv64、YOLOv5等早期版本的显著优势,为读者提供了一种新的、更有效的手势识别方法。
- 利用PySide6实现用户友好的界面设计: 在系统开发中,采用了PySide6库来设计和实现了一个直观、易用的用户界面。这使得用户能够方便快捷地进行手势识别操作,极大地提高了系统的可用性和互动性,同时也体现了将先进算法与友好界面设计结合的重要性。
- 集成登录管理功能以提升系统安全性: 通过设计登录管理功能,本系统在保证用户便捷使用的同时,也加强了数据安全和隐私保护。这一功能的添加,为后续进一步扩展系统功能、实现个性化服务提供了基础。
- 对YOLOv8模型进行深入研究并全面评估其性能: 除了应用YOLOv8于手势识别任务外,本文还深入分析了该模型的性能,包括精度、召回率等关键指标的评估,以及在不同条件下的表现分析。这一部分的内容不仅加深了对YOLOv8算法的理解,也为未来的优化提供了有价值的参考。
- 提供完整的数据集和代码资源包: 为了便于读者理解、应用并进一步研究YOLOv8算法在手势识别领域的应用,本文提供了包含详细数据集和完整代码的资源包。这些资源的分享,不仅方便了读者复现和验证本文的研究成果,也鼓励了更多的实践和探索。
1. 数据集介绍
在这个博客章节中,我们将详细介绍为常见手势识别系统构建的专用数据集。这个由5502张图像构成的数据集不仅在数量上符合深度学习模型的训练需求,而且在质量上也经过了严格筛选和预处理,以确保提供给模型的数据是最优质的。数据集分为三个部分:3400张训练图像用于模型的学习,1316张验证图像用于调优模型参数,以及786张测试图像用于最终评估模型的性能。
每张图像在预处理过程中都经过了细致的调整,包括自动校正方向和尺寸调整至统一的640x640像素。这些步骤对于保证模型输入的一致性和减少变异性至关重要,尤其是在处理多样化的手势图像时。此外,为了提高模型的泛化能力,图像经过了增强处理,以模拟不同的光照和背景条件,增强模型在各种环境下的识别能力。
从数据集分布的分析中,我们观察到手势实例在类别上的分布不均。这意味着我们可能需要通过技术手段平衡数据集,如过采样少数类别或者合成新的训练样本,以避免模型偏向于频繁出现的手势类别。同时,数据集中手势的位置分布表明了手势在图像中出现的多样性,这有助于模型学会在不同位置识别手势。尽管手势位置的集中趋势对于确保手势被清晰捕捉是有益的,但也需要通过数据增强策略,比如随机裁剪和平移变换,来让模型适应更广泛的情况。
图像中手势大小的多样性也对模型提出了挑战,因为它需要识别从小到大的各种尺寸的手势。我们的数据集在边界框的高度和宽度上展示了广泛的变化,这有助于模型学习如何处理不同尺寸的目标。为了进一步提高模型的准确性,我们还需要考虑引入多尺度训练或其他技术来提高模型对尺寸变化的适应性。博主使用的类别代码如下:
Chinese_name = { 'A': 'A','B': 'B', 'C': 'C', 'D': 'D', 'E': 'E','F': 'F','G': 'G', 'H': 'H', 'I': 'I', 'J': 'J','K': 'K',
'L': 'L','M': 'M','N': 'N', 'O': 'O','P': 'P','Q': 'Q','R': 'R','S': 'S','T': 'T','U': 'U','V': 'V','W': 'W','X': 'X',
'Y': 'Y', 'Z': 'Z'}
总之,我们的数据集经过了精心设计和预处理,以满足手势识别模型的复杂需求。通过不断的更新和优化,这个数据集将支持我们的系统不断进步,实现更准确、更可靠的手势识别能力。随着技术的发展和用户需求的变化,我们的数据集也会继续扩展和完善,以确保我们的系统能够在未来的应用中保持领先地位。
2. 系统界面效果
系统以PySide6作为GUI库,提供了一套直观且友好的用户界面。下面,我将详细介绍各个主要界面的功能和设计。
(1)系统提供了基于SQLite的注册登录管理功能。用户在首次使用时需要通过注册界面进行注册,输入用户名和密码后,系统会将这些信息存储在SQLite数据库中。注册成功后,用户可以通过登录界面输入用户名和密码进行登录。这个设计可以确保系统的安全性,也为后续添加更多个性化功能提供了可能性。
(2)在主界面上,系统提供了支持图片、视频、实时摄像头和批量文件输入的功能。用户可以通过点击相应的按钮,选择要进行常见手势识别的图片或视频,或者启动摄像头进行实时检测。在进行检测时,系统会实时显示检测结果,并将检测记录存储在数据库中。
(3)此外,系统还提供了一键更换YOLOv8\YOLOv5模型的功能。用户可以通过点击界面上的"更换模型"按钮,选择不同的YOLOv8模型进行检测。与此同时,系统附带的数据集也可以用于重新训练模型,以满足用户在不同场景下的检测需求。
(4)为了提供更个性化的使用体验,这里系统支持界面修改,用户可以自定义图标、文字等界面元素。例如,用户可以根据自己的喜好,选择不同风格的图标,也可以修改界面的文字描述。
3. YOLOv8算法原理
YOLOv8继续沿用了YOLO系列的核心设计理念,即“只看一次”(You Only Look Once),通过单次前向传播就实现对图像中所有目标的检测。这一设计极大地提高了目标检测任务的实时性,使得YOLOv8非常适合需要快速响应的应用场景,如实时手势识别。
在网络架构方面,YOLOv8进一步优化了特征提取器。传统的YOLO模型使用单一的特征提取网络,而YOLOv8可能引入了类似于特征金字塔网络(FPN)和路径聚合网络(PAN)的结构,这些结构能够更有效地聚合不同尺度的特征信息,增强模型对于不同尺寸目标的检测能力。这对于手势识别尤为重要,因为手势的大小在图像中可能会有很大的变化。
YOLOv8在损失函数的设计上也可能进行了创新。根据提供的信息,YOLOv8可能采用了Distribution Focal Loss,这是对传统Focal Loss的改进。Focal Loss是为了解决类别不平衡问题,通过调整正负样本的权重来提高少数类别样本的训练效果。Distribution Focal Loss则可能进一步考虑了不同类别样本分布的特性,使得模型在学习时更加注重于那些难以区分的样本,从而提高模型对于复杂或相似手势的识别准确率。
YOLOv8在锚框(Anchor Boxes)的使用上做了重要的改进。它采用了TaskAlignedAssigner,这是一种新颖的锚框分配策略,该策略旨在将锚框更准确地分配给对应的真实标签。这种策略通过评估预测框与真实标签之间的对齐度来优化锚框的分配,从而使得锚框分配更为精确,进而提高模型对目标的识别精度。这与传统的锚框分配方法相比,更能准确地捕捉目标的形状和位置,特别是在复杂的手势识别任务中,这种精确的分配机制显得尤为重要。
YOLOv8还提升了算法的整体结构设计。在网络架构方面,可能包含了更先进的特征提取器和特征融合模块,例如集成了特征金字塔网络(FPN)和路径聚合网络(PAN)的元素,优化了特征在不同尺度之间的传递和融合。这些设计不仅提升了模型对于复杂场景中手势的识别能力,也使得模型能够更好地处理手势的尺寸变化,增强了模型对小目标手势的识别能力。
这些技术的结合使得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/178.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 模型训练
在这一段博客内容中,我们将深入探讨如何使用Python和PyTorch框架来训练一个基于YOLOv8算法的手势识别模型。本篇博客旨在向读者详细介绍训练过程中的关键步骤和代码解析,以便读者能够清晰理解模型训练的内部机制,并能够自行实现和优化。
我们的代码首先导入了必要的模块,包括操作系统接口模块os、PyTorch深度学习框架以及yaml模块,用于处理配置文件。我们使用了ultralytics中的YOLO类,这是一个用于构建、训练和部署YOLO模型的强大工具。在开始编写主要的训练脚本之前,代码首先设置了训练所需的一些参数,如工作进程数和批处理大小,并且确定了数据集的路径。我们检测了CUDA(一种由NVIDIA推出的GPU计算平台)是否可用,如果可用,我们将使用GPU进行训练,否则使用CPU。这是因为GPU可以大幅加速模型的训练过程。
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"
abs_path函数用于获取数据集配置文件的绝对路径,这是为了确保无论脚本在何处执行,路径都能正确指向。通过yaml模块,我们能够加载和更新YAML文件,这是为了保证模型训练时能够正确找到数据集的路径。
data_name = "Gesture"
data_path = abs_path(f'datasets/{data_name}/{data_name}.yaml', path_type='current')
unix_style_path = data_path.replace(os.sep, '/')
# 获取目录路径
directory_path = os.path.dirname(unix_style_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)
随后,代码初始化了YOLO模型并开始了训练过程。首先加载了预训练的权重,然后调用train方法开始训练模型。这里指定了许多重要的训练参数,例如数据集路径、设备类型、工作进程数、图像尺寸、训练周期和批次大小。每个参数都对训练过程和最终模型的性能有着直接的影响。
workers = 1
batch = 8
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='0', # 指定使用CPU进行训练
workers=workers, # 指定使用2个工作进程加载数据
imgsz=640, # 指定输入图像的大小为640x640
epochs=100, # 指定训练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='0', # 指定使用CPU进行训练
workers=workers, # 指定使用2个工作进程加载数据
imgsz=640, # 指定输入图像的大小为640x640
epochs=100, # 指定训练100个epoch
batch=batch, # 指定每个批次的大小为8
name='train_v8_' + data_name # 指定训练任务的名称
)
YOLO类被用来加载预训练模型并设置为检测任务模式。train方法是启动训练过程的核心,其中data参数是数据集配置文件的路径,device指定了训练使用的设备(GPU或CPU),workers设置了数据加载时的工作进程数量,imgsz指定了输入图像的大小,epochs定义了训练周期。整个代码块的设计显示了一个明确的训练流程:从数据准备到模型初始化,再到训练过程的执行。每一步都紧密相扣,确保了模型训练的稳健性和高效性。
在深度学习模型的训练过程中,损失函数的趋势和最终评价指标是评估模型性能的关键。通过对YOLOv8模型训练过程中的各项损失和性能指标的分析,我们可以深入理解模型的学习效果和优化空间。
首先,观察损失函数图像,我们看到训练和验证阶段的损失值(box_loss、cls_loss、df1_loss)都随着训练周期的增加而稳步下降,这表示模型在识别任务上的性能逐渐提升。具体来说,训练阶段的边界框损失(box_loss)和分类损失(cls_loss)显示出了明显的下降趋势,并趋于平稳,这意味着模型在定位手势的边界框以及分类手势类型方面越来越准确。df1_loss损失的下降也表明了模型在整体检测性能上的提高。验证阶段的损失值虽然波动性较大,但整体趋势也呈现下降,这表明模型在未见过的数据上同样具备良好的泛化能力。
接下来,看到精确度(precision)和召回率(recall)这两个性能指标在训练过程中维持在较高水平,且随着训练进展波动减小并趋于稳定。这表明模型在不断地学习,并在保持高召回率的同时,也能保持较高的精确度,这对于手势识别系统来说是非常重要的。
在平均精确度均值(mAP)指标方面,我们可以看到mAP和mAP50-95两个指标在训练过程中表现出稳步提升的趋势,最终稳定在较高的水平。mAP50-95是一个更严格的评价指标,因为它考虑了不同IoU阈值下的平均精确度,而该指标的提升表明模型在不同重叠程度下都能保持较高的检测准确性。
F1得分是一个重要的统计指标,用于衡量模型的精确度和召回率的平衡,特别是在数据集类别分布不均时。它是精确度和召回率的调和平均数,最高可能的F1得分为1(完美精确度和召回率),最低可能为0。通常,随着置信度阈值的增加,精确度会上升而召回率下降,F1得分则反映了这两个指标之间的平衡。
我们可以观察到随着置信度阈值的增加,F1分数呈现出先升高后降低的趋势,这是因为在较低的置信度阈值下,模型可能会产生更多的假阳性检测,从而降低了精确度;而当置信度阈值过高时,模型可能会错过一些正类别的检测,导致召回率下降。F1分数在曲线上的某点达到最大值,该点即是模型在选择的置信度阈值下精确度与召回率之间的最佳平衡。
在图中,我们看到最大的F1分数是0.91,出现在置信度阈值大约为0.571时。这表明,在此阈值下,模型达到了较高的精确度和召回率的平衡。一个高F1分数意味着模型在准确识别手势方面表现出色,对于实际应用来说,这是一个非常鼓舞人心的结果。尤其是在手势识别系统中,能够准确地识别和理解用户的手势对于系统的用户体验至关重要。
进一步分析这个曲线,我们可以看到大多数类别的F1分数都集中在较高的区域,这表明模型对大多数手势都有很好的识别能力。然而,曲线中也存在一些波动,这些波动可能指出某些类别的手势识别不如其他类别准确,可能是因为这些手势在视觉上更难以区分,或者训练数据中这些类别的样本较少。
总之,F1分数和置信度曲线为我们提供了一个关键的评价视角,不仅可以帮助我们理解模型整体的性能,还能指导我们调整置信度阈值,以获得最佳的模型表现。对于实际应用而言,选择一个能够平衡精确度和召回率的置信度阈值是非常重要的,它直接关系到模型在现实世界中的可用性和可靠性。
4.3 YOLOv5、YOLOv6、YOLOv7和YOLOv8对比
(1)实验设计:
本实验旨在评估和比较YOLOv5、YOLOv6、YOLOv7和YOLOv8几种模型在常见手势目标检测任务上的性能。为了实现这一目标,博主分别使用使用相同的数据集训练和测试了这四个模型,从而可以进行直接的性能比较。该数据集包含常见手势的图像。本文将比较分析四种模型,旨在揭示每种模型的优缺点,探讨它们在工业环境中实际应用的场景选择。
模型 | 图像大小 (像素) | mAPval 50-95 | CPU ONNX 速度 (毫秒) | A100 TensorRT 速度 (毫秒) | 参数数量 (百万) | FLOPs (十亿) |
---|---|---|---|---|---|---|
YOLOv5nu | 640 | 34.3 | 73.6 | 1.06 | 2.6 | 7.7 |
YOLOv8n | 640 | 37.3 | 80.4 | 0.99 | 3.2 | 8.7 |
YOLOv6N | 640 | 37.5 | - | - | 4.7 | 11.4 |
YOLOv7-tiny | 640 | 37.4 | - | - | 6.01 | 13.1 |
(2)度量指标:
- F1-Score:F1-Score是精确率(Precision)和召回率(Recall)的调和平均值。精确率是指模型正确识别的正例与所有识别为正例的案例之比,而召回率是指模型正确识别的正例与所有实际正例之比。F1-Score对于不平衡的数据集或者需要同时考虑精确率和召回率的任务特别重要。
- mAP(Mean Average Precision):mAP是衡量模型在多个类别上平均检测准确度的指标。它计算了模型在所有类别上的平均精度,是目标检测领域中常用的性能度量。
名称 | YOLOv5nu | YOLOv6n | YOLOv7-tiny | YOLOv8n |
---|---|---|---|---|
mAP | 0.956 | 0.953 | 0.931 | 0.949 |
F1-Score | 0.92 | 0.92 | 0.89 | 0.91 |
(3)实验结果分析:
在进行YOLO系列算法的性能比较时,我们选取了两个关键的评价指标:mAP(mean Average Precision)和F1-Score。mAP反映了模型在整个数据集上对于各类别目标检测的平均精确度,而F1-Score则综合考量了模型的精确度和召回率。通过这两个指标,我们可以全面评估模型在手势识别任务上的性能。
在我们的实验中,YOLOv5nu在mAP上以0.956的得分领先,表明该模型在目标检测任务上表现出了最高的平均精确度。这可能归因于YOLOv5nu在特征提取和目标定位方面的优化,其网络结构可能更适合处理手势识别这一特定任务。高mAP得分表明模型在不同阈值下都保持了较高的检测准确率,这对于实时性要求高的手势识别应用尤为重要。
YOLOv6n在mAP上与YOLOv5nu相差无几,得分为0.953,显示出几乎与YOLOv5nu等同的性能。这可能是因为YOLOv6n在网络架构或者优化算法上做了改进,使得模型能够更好地泛化到不同的手势类型上。同时,YOLOv6n保持了与YOLOv5nu一样高的F1-Score(0.92),这进一步证明了它在精确度和召回率之间达到了良好的平衡。
YOLOv7-tiny的mAP得分为0.931,F1-Score为0.89,两项指标都稍低于前两者。作为一个“轻量化”的模型,YOLOv7-tiny可能在模型大小和运算速度上有优势,但这可能导致了在特征提取和目标定位的性能上的一些妥协。较低的F1-Score表明模型在减少误检(即提高精确度)和避免漏检(即提高召回率)方面可能存在一定的挑战。
YOLOv8n的mAP得分为0.949,F1-Score为0.91,虽然在mAP上略低于YOLOv5nu和YOLOv6n,但F1-Score表明它仍然能够在保持较高召回率的同时,实现相对较高的精确度。YOLOv8n作为最新版本的YOLO,可能集成了一些最新的网络结构和优化策略,使得它在性能上表现出较为均衡的特点。
总体来看,每个模型的性能表现都与其架构设计和优化策略密切相关。高性能的模型往往具有更强大的特征提取能力和更精细的目标定位机制。而在实际应用中,我们需要综合考虑模型的性能、运算效率和易用性。例如,对于需要在边缘设备上运行的手势识别应用,可能会偏好YOLOv7-tiny这样的轻量化模型,尽管其性能略有牺牲。而在服务器端,可以承担更大计算负担的场景中,则可能会优先选择性能更高的YOLOv5nu或YOLOv6n。
4.4 代码实现
在当今的人机交互领域,手势识别技术正日益成为一个重要的研究方向。它允许用户通过自然的手势来控制计算机或其他设备,提供了一种更为直观和方便的交互方式。本博客将详细介绍如何利用深度学习模型YOLOv8和Python编程语言,结合OpenCV库和PySide6工具包,来构建一个实时的手势识别系统。
(1)引入必要的库
首先,我们需要导入一系列的Python库和模块,它们是构建此应用程序的基础。sys模块让我们能够处理与Python解释器相关的功能,如命令行参数。time模块用于计算模型在处理每帧图像时的推理时间。cv2即OpenCV库,是处理图像和视频的强大工具。为了创建图形用户界面(GUI),我们使用PySide6库,它是Qt应用程序框架的Python绑定。
import sys # 导入sys模块,用于访问与Python解释器相关的变量和函数
import time # 导入time模块,用于获取当前时间
import cv2 # 导入OpenCV库,用于图像处理
from QtFusion.widgets import QMainWindow # 从QtFusion库导入FBaseWindow类,用于创建主窗口
from QtFusion.handlers import MediaHandler # 从QtFusion库导入MediaHandler类,用于处理媒体流
from QtFusion.utils import drawRectBox, get_cls_color # 从QtFusion库导入drawRectBox函数,用于在图像上绘制矩形框
from PySide6 import QtWidgets, QtCore # 导入PySide6库的QtWidgets和QtCore模块,用于创建GUI
from QtFusion.path import abs_path
from QtFusion.config import QF_Config
from YOLOv8Model import YOLOv8Detector # 从YOLOv8Model模块导入YOLOv8Detector类,用于物体检测
from datasets.Gesture.label_name import Label_list
QF_Config.set_verbose(False)
(2)设置主窗口
接下来,我们定义了一个名为MainWindow的类,它继承自QtWidgets模块中的QMainWindow。这个类是我们应用程序主窗口的框架,提供了图形界面的基本元素。我们通过该类的构造函数初始化窗口大小,并创建了一个QLabel控件用于展示视频流。此外,还定义了一个键盘事件处理函数,允许用户通过按下Q键来退出应用程序。
class MainWindow(QMainWindow): # 定义MainWindow类,继承自FBaseWindow类
def __init__(self): # 定义构造函数
super().__init__() # 调用父类的构造函数
self.resize(850, 500) # 设置窗口的大小
self.label = QtWidgets.QLabel(self) # 创建一个QLabel对象
self.label.setGeometry(0, 0, 850, 500) # 设置QLabel的位置和大小
def keyPressEvent(self, event): # 定义keyPressEvent函数,用于处理键盘事件
if event.key() == QtCore.Qt.Key.Key_Q: # 如果按下的是Q键
self.close() # 关闭窗口
(3)图像帧处理
为了实现手势识别功能,我们需要处理视频流的每一帧图像。我们定义了frame_process函数,它首先调整图像大小,以适配我们的处理流程。接着,我们利用预先加载的YOLOv8模型对图像进行预处理和推理。预测完成后,我们计算了模型推理所需的时间,并将预测结果绘制到原始图像上。这个过程包括后处理,如提取目标检测信息,并在图像上绘制矩形框和类别标签。
def frame_process(image): # 定义frame_process函数,用于处理每一帧图像
image = cv2.resize(image, (850, 500)) # 调整图像的大小
pre_img = model.preprocess(image) # 对图像进行预处理
t1 = time.time() # 获取当前时间
pred, superimposed_img = model.predict(pre_img) # 使用模型进行预测
t2 = time.time() # 获取当前时间
use_time = t2 - t1 # 计算预测所用的时间
print("推理时间: %.2f" % use_time) # 打印预测所用的时间
det = pred[0] # 获取预测结果
# 如果有检测信息则进入
if det is not None and len(det):
det_info = model.postprocess(pred) # 对预测结果进行后处理
for info in det_info: # 遍历检测信息
name, bbox, conf, cls_id = info['class_name'], info['bbox'], info['score'], info[
'class_id'] # 获取类名、边界框、置信度和类别ID
label = '%s %.0f%%' % (name, conf * 100) # 创建标签,包含类名和置信度
# 画出检测到的目标物
image = drawRectBox(image, bbox, alpha=0.2, addText=label, color=colors[cls_id]) # 在图像上绘制矩形框,并添加标签和颜色
window.dispImage(window.label, image) # 在窗口的label控件上显示图像
(4)常见手势识别
YOLOv8模型的加载和预处理是关键步骤。我们首先创建了一个YOLOv8Detector对象,然后加载了预训练的权重文件。我们还定义了一个颜色列表,为每个检测到的手势类别分配了一个颜色,以便在图像上以不同的颜色标注不同的手势。最后,我们通过MediaHandler类来捕获和处理来自摄像头的实时视频流。设置了视频流的帧率,并将frame_process函数连接到了新帧准备好的信号上。随后,启动了视频流的处理,并显示了主窗口。
cls_name = Label_list # 定义类名列表
model = YOLOv8Detector() # 创建YOLOv8Detector对象
model.load_model(abs_path("weights/best-yolov8n.pt", path_type="current")) # 加载预训练的YOLOv8模型
colors = get_cls_color(model.names) # 获取类别颜色
app = QtWidgets.QApplication(sys.argv) # 创建QApplication对象
window = MainWindow() # 创建MainWindow对象
videoHandler = MediaHandler(fps=30) # 创建MediaHandler对象,设置帧率为30
videoHandler.frameReady.connect(frame_process) # 当有新的帧准备好时,调用frame_process函数
videoHandler.setDevice(device=0) # 设置设备为0,即默认的摄像头
videoHandler.startMedia() # 开始处理媒体流
# 显示窗口
window.show()
# 进入 Qt 应用程序的主循环
sys.exit(app.exec())
通过这些步骤,我们成功构建了一个实时的手势识别系统。该系统不仅能够实时地识别和响应用户的手势,而且提供了一种交互式的用户体验。
5. 常见手势识别系统实现
在实现一款实时常见手势识别系统时,我们追求的是一个将高效能的手势识别技术与用户友好的界面相结合的方案。这个系统设计背后的核心思想是,用户能够通过简单直观的操作,与计算机进行交互,而无需复杂的设置或长时间的学习。为了实现这一目标,我们的系统设计分为三个层次:处理层、界面层和控制层,每个层次各司其职,但又相互协作,共同完成用户指令和机器响应之间的交互任务。
5.1 系统设计思路
MainWindow类的设计采纳了模块化的思想,确保了各个组件——无论是图像处理部分、用户交互界面,还是深度学习模型——都能独立运作,同时又能协同工作,共同完成复杂的常见手势识别任务。这种设计不仅提高了系统的灵活性和可维护性,也使得将来的升级和功能扩展变得更加容易。
架构设计
我们的系统设计遵循了经典的MVC(Model-View-Controller)架构模式,将应用程序划分为三个核心组件:模型(Model)、视图(View)和控制器(Controller),分别对应我们的处理层、界面层和控制层。
- 处理层(Processing Layer):处理层是系统的基础,我们采用了YOLOv8Detector类来实施这一层的功能。它负责加载预训练的深度学习模型,并对实时视频流中的手势进行快速而准确的识别。这个类的设计充分考虑了模型的性能,确保即使在较低端的计算设备上也能实现实时的手势识别。这一层的设计是为了确保系统的核心功能——手势识别的准确性和实时性。
- 界面层(UI Layer):界面层则是与用户直接交互的前端,由Ui_MainWindow类及其生成的用户界面组成。在这一层,我们精心设计了各种界面元素,如按钮、标签、表格等,这些元素不仅美观,而且直观易用。用户可以通过这些界面元素来观看摄像头捕捉的实时图像,看到系统识别的手势,并通过简单的操作来控制系统或调整设置。
- 控制层(Control Layer):控制层作为桥梁,连接处理层和界面层,确保系统能够响应用户的输入并据此执行相应的操作。在MainWindow类中实现的一系列槽函数和方法构成了这一层。它们负责处理用户的各种操作,如启动和停止视频流、调整设置等,并根据用户的操作控制媒体处理器和模型的行为。此外,控制层还管理着系统的信号和槽机制,这是Qt框架中用于模块间交互和数据传递的一种机制。
通过这样层次分明的架构设计,我们的交互式常见手势识别系统不仅能够提供强大的手势识别功能,而且还能给用户带来流畅而愉悦的操作体验。无论是在家庭娱乐、智能家居控制,还是在商业展示等场合,这个系统都能发挥出其应有的作用,让人机交互变得更加自然和高效。
系统流程
我们将介绍构建一个交互式常见手势识别系统的全过程。这一系统设计的核心在于创建一个用户友好的界面,同时在后端实现高效的手势检测与识别功能。以下是常见手势识别系统的工作流程:
- 首先,当用户启动应用程序时,系统会创建MainWindow类的实例。这个实例不仅负责初始化整个应用的界面,也设置了一系列的参数,为用户提供了操作的起点。这是确保用户能够顺利与系统交互的关键一步。
- 接下来,应用程序提供了一个直观的界面,用户可以通过这个界面选择输入源。输入源的选择多样化,可以是摄像头实时捕捉的图像、视频文件或是静态图片,满足不同用户的需求。用户选择输入源后,系统会调用相关的媒体处理器和方法来处理输入数据,这可能包括对摄像头的配置、视频文件的读取或图像文件的加载。
- 一旦媒体输入源准备就绪,系统进入连续帧处理的循环。在预处理阶段,系统会对每一帧图像进行缩放、色彩空间转换和归一化等预处理步骤,以满足YOLO模型的输入要求。然后,在检测与识别阶段,预处理后的图像将被送入YOLOv8模型进行手势的检测和识别。模型会输出手势的位置和类别。在界面更新阶段,随着检测结果的产生,界面将实时更新,展示检测框、标注手势类别,并在界面的表格或条形图中展示检测统计数据。
- 此外,用户还可以通过界面提供的按钮进行交互操作,例如保存检测结果、查询作者和版本信息,以及通过下拉菜单筛选和分析特定的检测结果。用户还可以控制媒体的播放状态,如启动或停止摄像头捕捉、视频播放或图像分析。
整个系统的设计思路旨在将复杂的手势识别技术与简单直观的用户界面相结合,为用户提供一个无缝的交互体验。通过这一设计,系统不仅可以准确快速地识别用户的手势,还能以一种用户友好的方式呈现复杂的数据和分析结果,使用户能够轻松地理解和操作系统。
5.2 登录与账户管理
在我们的交互式常见手势识别系统中,除了强大的手势识别功能之外,还特别重视用户体验的个性化和数据的私密性。为此,我们引入了一个综合的登录和账户管理模块,它基于PySide6构建了友好的用户界面,并利用SQLite数据库来安全地管理用户数据。这个模块是用户进入系统的第一道门槛,它不仅确保了系统使用的安全性,还提供了一系列的个性化选项,让每个用户都能感受到系统的贴心和便利。
用户首先会遇到一个简洁明了的登录界面,这里他们可以注册一个新账户或用已有的账户登录。注册过程非常简单,只需填写基本信息并设置密码即可。一旦登录,用户便可以进入系统的主界面,开始体验手势识别的魔力。我们深知每个用户的喜好和习惯各不相同,因此在账户管理中,我们允许用户进行密码修改、头像设置,甚至是账户注销,让每个人的使用体验都尽可能舒适和个性化。
账户管理的设计不仅仅是为了增加一个功能,它的目的是让用户能够在使用手势识别功能的同时,拥有一个私人定制的空间。在这个空间里,用户的检测结果、设置偏好和操作记录都会被妥善保存。这样,用户不必担心自己的数据会在不经意间被他人查看或是丢失。同时,这也为用户提供了一个数据管理的平台,他们可以在这里查看历史记录,分析使用模式,甚至导出数据用于其他目的。
这一账户管理模块的加入,使得交互式常见手势识别系统不仅仅是一个技术工具,更是一个可以个性化定制的智能助手。它通过提供安全的登录、个性化的设置和便利的数据管理,让每一位用户都能享受到一个安全、舒适且高效的使用体验。这也反映了我们在系统设计中对用户需求的深入考虑和对用户体验的高度重视。通过这样的设计,我们的系统不仅能够在实时目标检测领域满足用户的基本需求,更能提供超出期待的附加价值。
下载链接
若您想获得博文中涉及的实现完整全部资源文件(包括测试图片、视频,py, UI文件,训练数据集、训练代码、界面代码等),这里已打包上传至博主的面包多平台,见可参考博客与视频,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:
完整资源中包含数据集及训练代码,环境配置与界面中文字、图片、logo等的修改方法请见视频,项目完整文件下载请见演示与介绍视频的简介处给出:➷➷➷
演示与介绍视频:https://www.bilibili.com/video/BV1uy421v7tG/
在文件夹下的资源显示如下,下面的链接中也给出了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模型的实时常见手势识别系统。系统以模块化的方式设计,充分采用了合理的架构设计,带来良好的可维护性和可扩展性。其用户界面友好,能够提供实时的常见手势识别和识别结果展示,同时支持用户账户管理,以便于保存和管理检测结果和设置。
该系统支持摄像头、视频、图像和批量文件等多种输入源,能够满足用户在不同场景下的需求。在后面可以添加更多预训练模型,增加检测和识别的种类;优化用户界面,增强个性化设置;并积极聆听用户反馈,以期不断改进系统,以更好地满足用户的需求。
结束语
由于博主能力有限,博文中提及的方法即使经过试验,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。
Terven J, Cordova-Esparza D. A comprehensive review of YOLO: From YOLOv1 to YOLOv8 and beyond[J]. arXiv preprint arXiv:2304.00501, 2023. ↩︎
Redmon J, Divvala S, Girshick R, et al. You only look once: Unified, real-time object detection[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2016: 779-788. ↩︎
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. ↩︎
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. ↩︎