当前位置: 首页 > news >正文

基于深度学习YOLOv8的安全手套佩戴识别检测系统(YOLOv8+YOLO数据集+UI界面+Python项目源码+模型)

一、项目介绍

本项目基于YOLOv8算法开发了一套安全手套佩戴识别检测系统,主要用于识别作业人员是否规范佩戴手套。系统采用两类别目标检测模型(Gloves/NO-Gloves),通过实时分析视频流或图像数据,可自动识别佩戴手套的人员和未佩戴手套的违规行为,广泛应用于建筑工地、工厂车间、电力作业等需要手部防护的安全监管场景,有效提升安全生产管理的智能化水平。

数据集共包含8,097张高质量标注图像,其中训练集7,086张、验证集676张、测试集335张。数据覆盖多种实际工业场景,确保了模型的泛化能力。所有数据均经过专业标注团队进行边界框标注和质量校验,为模型提供了高质量的学习基础。

目录

一、项目介绍

二、项目功能展示

系统功能

图片检测

视频检测

摄像头实时检测

三、数据集介绍

数据集配置文件

四、项目环境配置

创建虚拟环境

pycharm中配置anaconda

安装所需要库

五、模型训练

训练代码

训练结果

六、核心代码​编辑

七、项目源码(视频简介内)


基于深度学习YOLOv8的安全手套佩戴识别检测系统(YOLOv8+YOLO数据集+UI界面+Python项目源码+模型)_哔哩哔哩_bilibili

基于深度学习YOLOv8的安全手套佩戴识别检测系统(YOLOv8+YOLO数据集+UI界面+Python项目源码+模型)

二、项目功能展示

系统功能

图片检测:可对图片进行检测,返回检测框及类别信息。

视频检测:支持视频文件输入,检测视频中每一帧的情况。

摄像头实时检测:连接USB 摄像头,实现实时监测。

参数实时调节(置信度和IoU阈值)

  • 图片检测

该功能允许用户通过单张图片进行目标检测。输入一张图片后,YOLO模型会实时分析图像,识别出其中的目标,并在图像中框出检测到的目标,输出带有目标框的图像。

  • 视频检测

视频检测功能允许用户将视频文件作为输入。YOLO模型将逐帧分析视频,并在每一帧中标记出检测到的目标。最终结果可以是带有目标框的视频文件或实时展示,适用于视频监控和分析等场景。

  • 摄像头实时检测

该功能支持通过连接摄像头进行实时目标检测。YOLO模型能够在摄像头拍摄的实时视频流中进行目标检测,实时识别并显示检测结果。此功能非常适用于安防监控、无人驾驶、智能交通等应用,提供即时反馈。

核心特点:

  • 高精度:基于YOLO模型,提供精确的目标检测能力,适用于不同类型的图像和视频。
  • 实时性:特别优化的算法使得实时目标检测成为可能,无论是在视频还是摄像头实时检测中,响应速度都非常快。
  • 批量处理:支持高效的批量图像和视频处理,适合大规模数据分析。

三、数据集介绍

数据集共包含8,097张高质量标注图像,其中训练集7,086张、验证集676张、测试集335张。数据覆盖多种实际工业场景,确保了模型的泛化能力。所有数据均经过专业标注团队进行边界框标注和质量校验,为模型提供了高质量的学习基础。

数据集配置文件

数据集采用YOLO格式的配置文件,主要包含以下内容:

train: F:\安全手套佩戴识别检测数据集\train\images val: F:\安全手套佩戴识别检测数据集\valid\images test: F:\安全手套佩戴识别检测数据集\test\images nc: 2 names: ['Gloves', 'NO-Gloves']

四、项目环境配置

创建虚拟环境

首先新建一个Anaconda环境,每个项目用不同的环境,这样项目中所用的依赖包互不干扰。

终端输入

conda create -n yolov8 python==3.9

激活虚拟环境

conda activate yolov8

安装cpu版本pytorch

pip install torch torchvision torchaudio

pycharm中配置anaconda

安装所需要库

pip install -r requirements.txt

五、模型训练

训练代码

from ultralytics import YOLO model_path = 'yolov8s.pt' data_path = 'datasets/data.yaml' if __name__ == '__main__': model = YOLO(model_path) results = model.train(data=data_path, epochs=500, batch=64, device='0', workers=0, project='runs/detect', name='exp', )
根据实际情况更换模型 yolov8n.yaml (nano):轻量化模型,适合嵌入式设备,速度快但精度略低。 yolov8s.yaml (small):小模型,适合实时任务。 yolov8m.yaml (medium):中等大小模型,兼顾速度和精度。 yolov8b.yaml (base):基本版模型,适合大部分应用场景。 yolov8l.yaml (large):大型模型,适合对精度要求高的任务。
  • --batch 64:每批次64张图像。
  • --epochs 500:训练500轮。
  • --datasets/data.yaml:数据集配置文件。
  • --weights yolov8s.pt:初始化模型权重,yolov8s.pt是预训练的轻量级YOLO模型。

训练结果

六、核心代码

from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import Qt, QTimer from PyQt5.QtGui import QImage, QPixmap, QIcon from PyQt5.QtWidgets import (QFileDialog, QMessageBox, QTableWidgetItem, QStyledItemDelegate, QHeaderView) import cv2 import numpy as np from ultralytics import YOLO import os import datetime import sys class CenteredDelegate(QStyledItemDelegate): def initStyleOption(self, option, index): super().initStyleOption(option, index) option.displayAlignment = Qt.AlignCenter class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(1400, 900) MainWindow.setWindowTitle("YOLOv8 目标检测系统") # 设置窗口图标 if hasattr(sys, '_MEIPASS'): icon_path = os.path.join(sys._MEIPASS, 'icon.ico') else: icon_path = 'icon.ico' if os.path.exists(icon_path): MainWindow.setWindowIcon(QIcon(icon_path)) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") # 主布局 self.main_layout = QtWidgets.QHBoxLayout(self.centralwidget) self.main_layout.setContentsMargins(10, 10, 10, 10) self.main_layout.setSpacing(15) # 左侧布局 (图像显示) self.left_layout = QtWidgets.QVBoxLayout() self.left_layout.setSpacing(15) # 原始图像组 self.original_group = QtWidgets.QGroupBox("原始图像") self.original_group.setMinimumHeight(400) self.original_img_label = QtWidgets.QLabel() self.original_img_label.setAlignment(QtCore.Qt.AlignCenter) self.original_img_label.setText("等待加载图像...") self.original_img_label.setStyleSheet("background-color: #F0F0F0; border: 1px solid #CCCCCC;") original_layout = QtWidgets.QVBoxLayout() original_layout.addWidget(self.original_img_label) self.original_group.setLayout(original_layout) self.left_layout.addWidget(self.original_group) # 检测结果图像组 self.result_group = QtWidgets.QGroupBox("检测结果") self.result_group.setMinimumHeight(400) self.result_img_label = QtWidgets.QLabel() self.result_img_label.setAlignment(QtCore.Qt.AlignCenter) self.result_img_label.setText("检测结果将显示在这里") self.result_img_label.setStyleSheet("background-color: #F0F0F0; border: 1px solid #CCCCCC;") result_layout = QtWidgets.QVBoxLayout() result_layout.addWidget(self.result_img_label) self.result_group.setLayout(result_layout) self.left_layout.addWidget(self.result_group) self.main_layout.addLayout(self.left_layout, stretch=3) # 右侧布局 (控制面板) self.right_layout = QtWidgets.QVBoxLayout() self.right_layout.setSpacing(15) # 模型选择组 self.model_group = QtWidgets.QGroupBox("模型设置") self.model_group.setStyleSheet("QGroupBox { font-weight: bold; }") self.model_layout = QtWidgets.QVBoxLayout() # 模型选择 self.model_combo = QtWidgets.QComboBox() self.model_combo.addItems(["best.pt"]) self.model_combo.setCurrentIndex(0) # 加载模型按钮 self.load_model_btn = QtWidgets.QPushButton(" 加载模型") self.load_model_btn.setIcon(QIcon.fromTheme("document-open")) self.load_model_btn.setStyleSheet( "QPushButton { padding: 8px; background-color: #4CAF50; color: white; border-radius: 4px; }" "QPushButton:hover { background-color: #45a049; }" ) self.model_layout.addWidget(self.model_combo) self.model_layout.addWidget(self.load_model_btn) self.model_group.setLayout(self.model_layout) self.right_layout.addWidget(self.model_group) # 参数设置组 self.param_group = QtWidgets.QGroupBox("检测参数") self.param_group.setStyleSheet("QGroupBox { font-weight: bold; }") self.param_layout = QtWidgets.QFormLayout() self.param_layout.setLabelAlignment(Qt.AlignLeft) self.param_layout.setFormAlignment(Qt.AlignLeft) self.param_layout.setVerticalSpacing(15) # 置信度滑块 self.conf_slider = QtWidgets.QSlider(Qt.Horizontal) self.conf_slider.setRange(1, 99) self.conf_slider.setValue(25) self.conf_value = QtWidgets.QLabel("0.25") self.conf_value.setAlignment(Qt.AlignCenter) self.conf_value.setStyleSheet("font-weight: bold; color: #2196F3;") # IoU滑块 self.iou_slider = QtWidgets.QSlider(Qt.Horizontal) self.iou_slider.setRange(1, 99) self.iou_slider.setValue(45) self.iou_value = QtWidgets.QLabel("0.45") self.iou_value.setAlignment(Qt.AlignCenter) self.iou_value.setStyleSheet("font-weight: bold; color: #2196F3;") self.param_layout.addRow("置信度阈值:", self.conf_slider) self.param_layout.addRow("当前值:", self.conf_value) self.param_layout.addRow(QtWidgets.QLabel("")) # 空行 self.param_layout.addRow("IoU阈值:", self.iou_slider) self.param_layout.addRow("当前值:", self.iou_value) self.param_group.setLayout(self.param_layout) self.right_layout.addWidget(self.param_group) # 功能按钮组 self.func_group = QtWidgets.QGroupBox("检测功能") self.func_group.setStyleSheet("QGroupBox { font-weight: bold; }") self.func_layout = QtWidgets.QVBoxLayout() self.func_layout.setSpacing(10) # 图片检测按钮 self.image_btn = QtWidgets.QPushButton(" 图片检测") self.image_btn.setIcon(QIcon.fromTheme("image-x-generic")) # 视频检测按钮 self.video_btn = QtWidgets.QPushButton(" 视频检测") self.video_btn.setIcon(QIcon.fromTheme("video-x-generic")) # 摄像头检测按钮 self.camera_btn = QtWidgets.QPushButton(" 摄像头检测") self.camera_btn.setIcon(QIcon.fromTheme("camera-web")) # 停止检测按钮 self.stop_btn = QtWidgets.QPushButton(" 停止检测") self.stop_btn.setIcon(QIcon.fromTheme("process-stop")) self.stop_btn.setEnabled(False) # 保存结果按钮 self.save_btn = QtWidgets.QPushButton(" 保存结果") self.save_btn.setIcon(QIcon.fromTheme("document-save")) self.save_btn.setEnabled(False) # 设置按钮样式 button_style = """ QPushButton { padding: 10px; background-color: #2196F3; color: white; border: none; border-radius: 4px; text-align: left; } QPushButton:hover { background-color: #0b7dda; } QPushButton:disabled { background-color: #cccccc; } """ for btn in [self.image_btn, self.video_btn, self.camera_btn, self.stop_btn, self.save_btn]: btn.setStyleSheet(button_style) self.func_layout.addWidget(btn) self.func_group.setLayout(self.func_layout) self.right_layout.addWidget(self.func_group) # 检测结果表格组 self.table_group = QtWidgets.QGroupBox("检测结果详情") self.table_group.setStyleSheet("QGroupBox { font-weight: bold; }") self.table_layout = QtWidgets.QVBoxLayout() self.result_table = QtWidgets.QTableWidget() self.result_table.setColumnCount(4) self.result_table.setHorizontalHeaderLabels(["类别", "置信度", "左上坐标", "右下坐标"]) self.result_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.result_table.verticalHeader().setVisible(False) self.result_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.result_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) # 设置表格样式 self.result_table.setStyleSheet(""" QTableWidget { border: 1px solid #e0e0e0; alternate-background-color: #f5f5f5; } QHeaderView::section { background-color: #2196F3; color: white; padding: 5px; border: none; } QTableWidget::item { padding: 5px; } """) # 设置居中代理 delegate = CenteredDelegate(self.result_table) self.result_table.setItemDelegate(delegate) self.table_layout.addWidget(self.result_table) self.table_group.setLayout(self.table_layout) self.right_layout.addWidget(self.table_group, stretch=1) self.main_layout.addLayout(self.right_layout, stretch=1) MainWindow.setCentralWidget(self.centralwidget) # 状态栏 self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setStyleSheet("QStatusBar { border-top: 1px solid #c0c0c0; }") MainWindow.setStatusBar(self.statusbar) # 初始化变量 self.model = None self.cap = None self.timer = QTimer() self.is_camera_running = False self.current_image = None self.current_result = None self.video_writer = None self.output_path = "output" # 创建输出目录 if not os.path.exists(self.output_path): os.makedirs(self.output_path) # 连接信号槽 self.load_model_btn.clicked.connect(self.load_model) self.image_btn.clicked.connect(self.detect_image) self.video_btn.clicked.connect(self.detect_video) self.camera_btn.clicked.connect(self.detect_camera) self.stop_btn.clicked.connect(self.stop_detection) self.save_btn.clicked.connect(self.save_result) self.conf_slider.valueChanged.connect(self.update_conf_value) self.iou_slider.valueChanged.connect(self.update_iou_value) self.timer.timeout.connect(self.update_camera_frame) # 设置全局样式 self.set_style() def set_style(self): style = """ QMainWindow { background-color: #f5f5f5; } QGroupBox { border: 1px solid #e0e0e0; border-radius: 5px; margin-top: 10px; padding-top: 15px; } QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 3px; } QLabel { color: #333333; } QComboBox { padding: 5px; border: 1px solid #cccccc; border-radius: 3px; } QSlider::groove:horizontal { height: 6px; background: #e0e0e0; border-radius: 3px; } QSlider::handle:horizontal { width: 16px; height: 16px; margin: -5px 0; background: #2196F3; border-radius: 8px; } QSlider::sub-page:horizontal { background: #2196F3; border-radius: 3px; } """ self.centralwidget.setStyleSheet(style) def load_model(self): model_name = self.model_combo.currentText().split(" ")[0] try: self.model = YOLO(model_name) self.statusbar.showMessage(f"模型 {model_name} 加载成功", 3000) self.image_btn.setEnabled(True) self.video_btn.setEnabled(True) self.camera_btn.setEnabled(True) except Exception as e: QMessageBox.critical(None, "错误", f"模型加载失败: {str(e)}") def update_conf_value(self): conf = self.conf_slider.value() / 100 self.conf_value.setText(f"{conf:.2f}") def update_iou_value(self): iou = self.iou_slider.value() / 100 self.iou_value.setText(f"{iou:.2f}") def detect_image(self): if self.model is None: QMessageBox.warning(None, "警告", "请先加载模型") return file_path, _ = QFileDialog.getOpenFileName( None, "选择图片", "", "图片文件 (*.jpg *.jpeg *.png *.bmp);;所有文件 (*)" ) if file_path: try: # 读取图片 img = cv2.imread(file_path) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 显示原始图片 self.display_image(img, self.original_img_label) self.current_image = img.copy() # 检测图片 conf = self.conf_slider.value() / 100 iou = self.iou_slider.value() / 100 self.statusbar.showMessage("正在检测图片...") QtWidgets.QApplication.processEvents() # 更新UI results = self.model.predict(img, conf=conf, iou=iou) result_img = results[0].plot() # 显示检测结果 self.display_image(result_img, self.result_img_label) self.current_result = result_img.copy() # 更新结果表格 self.update_result_table(results[0]) self.save_btn.setEnabled(True) self.statusbar.showMessage(f"图片检测完成: {os.path.basename(file_path)}", 3000) except Exception as e: QMessageBox.critical(None, "错误", f"图片检测失败: {str(e)}") self.statusbar.showMessage("图片检测失败", 3000) def detect_video(self): if self.model is None: QMessageBox.warning(None, "警告", "请先加载模型") return file_path, _ = QFileDialog.getOpenFileName( None, "选择视频", "", "视频文件 (*.mp4 *.avi *.mov *.mkv);;所有文件 (*)" ) if file_path: try: self.cap = cv2.VideoCapture(file_path) if not self.cap.isOpened(): raise Exception("无法打开视频文件") # 获取视频信息 fps = self.cap.get(cv2.CAP_PROP_FPS) width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 创建视频写入器 timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") output_file = os.path.join(self.output_path, f"output_{timestamp}.mp4") fourcc = cv2.VideoWriter_fourcc(*'mp4v') self.video_writer = cv2.VideoWriter(output_file, fourcc, fps, (width, height)) # 启用停止按钮,禁用其他按钮 self.stop_btn.setEnabled(True) self.save_btn.setEnabled(True) self.image_btn.setEnabled(False) self.video_btn.setEnabled(False) self.camera_btn.setEnabled(False) # 开始处理视频 self.timer.start(30) # 30ms间隔 self.statusbar.showMessage(f"正在处理视频: {os.path.basename(file_path)}...") except Exception as e: QMessageBox.critical(None, "错误", f"视频检测失败: {str(e)}") self.statusbar.showMessage("视频检测失败", 3000)

七、项目源码(视频简介内)

演示与介绍视频:

基于深度学习YOLOv8的安全手套佩戴识别检测系统(YOLOv8+YOLO数据集+UI界面+Python项目源码+模型)_哔哩哔哩_bilibili

基于深度学习YOLOv8的安全手套佩戴识别检测系统(YOLOv8+YOLO数据集+UI界面+Python项目源码+模型)

http://www.zskr.cn/news/1491101.html

相关文章:

  • 从YUV到H.265:搞懂这些‘行话’,你才算入了音视频开发的门
  • Sqribble文档自动化:模板驱动的结构化排版系统解析
  • 西安黄金回收市场六大品牌服务测评 - 润富黄金回收
  • 告别GUI依赖:用APDL命令流高效管理你的ANSYS分析项目(含.log文件妙用)
  • 时序签名变换:用路径积分提升拐点预测鲁棒性
  • 10分钟精通跨平台翻译神器Pot:解决多语言工作痛点的终极指南
  • 医疗AI为何伤人?从数据偏见到临床断崖的真相
  • 拆解TriCore的CMPSWAP.W指令:从TC264官方库看多核锁的硬件实现
  • 从地图App到算法竞赛:手把手教你用C++实现Dijkstra最短路径(附邻接表避坑指南)
  • 2026年操作台厂家选购参考指南:工业操作台、实验室操作台、不锈钢操作台、控制系统操作设备优质厂商汇总 - 海棠依旧大
  • XR处理器性能对比:高通XR2 Gen 2与旗舰SoC解析
  • Python中文语音合成实战:本地化TTS引擎选型与部署指南
  • PCA降维后数据‘镜像’了?用sklearn和自实现代码对比鸢尾花数据可视化,揭秘差异原因与注意事项
  • 粉盒植绒加工技术全解析:美妆蛋植绒加工/衣架植绒加工/遮阳板植绒加工/铝管植绒加工/面板植绒加工/香水瓶植绒加工/选择指南 - 优质品牌商家
  • 别再手动算权重了!用SPSSAU的AHP层次分析法,5分钟搞定旅游决策
  • 咸阳黄金回收市场盘点 2026年6月六大正规渠道实测 - 润富黄金回收
  • 物理增强神经网络DDCCNet革新量子化学计算
  • TPU双通道XOR架构实现SVPWM全占空比与高精度死区控制
  • 告别命令行焦虑:用Rancher 2.5.11的图形界面,5分钟搞定K8s集群与应用部署
  • 浙江珠宝展柜定制技术解析:温州商场专柜/温州实木烤漆展柜/温州展柜设计安装/温州珠宝展柜/温州美妆展柜/温州金银首饰展柜/选择指南 - 优质品牌商家
  • 无线通信中的‘多普勒效应’:从物理原理到SDR中的频偏估计实战
  • 从论文到代码:深入理解CosineLRScheduler(SGDR)如何帮你逃离局部最优陷阱
  • 避坑指南:RK3568 Android 11系统下RTL8821CU WiFi与蓝牙的共存配置与常见问题解决
  • 非科班学AI不晚:四阶跃迁路径与5大避坑指南
  • 15-2 理解Class类并获取Class的实例
  • PythonJS高级技巧:解锁Go、Lua等多语言转译的隐藏功能 [特殊字符]
  • 别再手动建模了!手把手教你将SolidWorks模型导入MATLAB做有限元仿真(附完整代码)
  • 2026年6月北京老房改造装修公司推荐:五大排名专业评测旧房翻新注意事项价格 - 品牌推荐
  • 别再只改文件权限了!阿里云OSS存储桶的ACL策略详解与最佳安全实践
  • 全域数学·第一部· 数术本源之第五卷 算子数学与泛函原本