基于 YOLOv8 的智能安全帽检测系统
本文介绍了一个基于YOLOv8深度学习算法的智能安全帽检测系统。系统采用PyQt5开发桌面客户端,实现图片、视频和实时摄像头三种检测模式,可精准识别作业人员是否佩戴安全帽。系统包含用户登录、AI检测、数据管理和预警通知四大模块,具有置信度调节、实时统计、语音预警等功能。通过MySQL数据库存储检测日志,支持数据导出和分析。测试结果表明,该系统能有效提升高危作业场景的安全监管效率,为工业安全生产提供

hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
🦁作者简介:一名喜欢分享和记录学习的在校大学生
💥个人主页:code袁的博客
💥 个人QQ:2647996100
🐯 个人wechat:code8896
code袁系列专栏导航
1.《毕业设计与课程设计》本专栏分享一些毕业设计的源码以及项目成果。🥰🥰🥰
2.《微信小程序开发》本专栏从基础到入门的一系开发流程,并且分享了自己在开发中遇到的一系列问题。🤹🤹🤹
3.《vue开发系列全程线路》本专栏分享自己的vue的学习历程。非常期待和您一起在这个小小的互联网世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

一、项目背景与意义
在建筑工地、电力运维、矿山开采等高危作业场景中,安全帽是保障工人生命安全的第一道防线。然而,传统的人工巡检方式存在效率低、覆盖不全、易受主观因素影响等问题,导致未佩戴安全帽的违规行为屡禁不止,埋下了严重的安全隐患。
随着深度学习技术的快速发展,基于计算机视觉的智能安全检测系统应运而生。本项目采用当前最先进的 YOLOv8 目标检测算法,结合 PyQt5 构建了一套完整的智能安全帽检测系统,实现了对作业人员安全帽佩戴情况的实时、自动、精准识别与预警,为工业安全生产提供了强有力的技术支撑。
二、技术栈选型
本项目采用前后端分离的架构设计,核心技术栈如下:
三、系统架构设计
本系统整体分为用户登录模块、AI 检测模块、数据管理模块和预警通知模块四大核心部分,架构清晰,易于维护和扩展:
1.用户登录模块
提供用户名、密码及验证码校验功能,保障系统访问安全。
支持新用户注册,实现权限管理。
界面采用深色科技风设计,提升用户体验。
2.AI 检测模块
支持三种检测模式:图片检测、视频文件检测、实时摄像头流检测。
集成 YOLOv8 模型,可灵活切换不同权重文件(如best.pt)。
提供置信度阈值调节滑块,用户可根据场景需求调整检测精度。
实时显示检测耗时、发现目标数量、目标类别及置信度。
3.数据管理模块
实时更新检测日志,记录每条检测结果的 ID、源文件、识别类别、置信度和边界框坐标。
支持一键导出检测报告,生成结构化文档用于安全管理和复盘。
提供日志清空功能,方便系统维护。
4.预警通知模块
当检测到未佩戴安全帽(NoHelmet)时,自动触发语音预警,提醒现场人员和管理人员。
在界面右侧实时统计 Helmet 和 NoHelmet 的数量,直观展示检测结果。
四、核心功能实现
1. YOLOv8 模型训练与推理
本项目的核心是 YOLOv8 模型的应用。我们首先收集了包含 “佩戴安全帽” 和 “未佩戴安全帽” 两类目标的数据集,对 YOLOv8n/s/m 等不同尺寸的模型进行了训练和对比,最终选择了在精度和速度上表现最优的模型权重。
from ultralytics import YOLO
model=YOLO("./yolov8n.pt",task="detect")
model.train(data='yolo-bm.yaml',workers=0,epochs=50,batch=16)
2. PyQt5 桌面客户端开发
为了让非技术人员也能方便地使用这套系统,我们基于 PyQt5 开发了直观易用的桌面客户端。主要实现了以下功能:
1.登录界面:
使用 QLineEdit、QPushButton 等组件构建,实现了表单验证和验证码刷新功能。
2.主界面布局:
采用 QSplitter 和 QGridLayout 进行布局,左侧为功能导航栏,中间为检测结果展示区,右侧为系统状态和统计信息区。
实时检测:通过 QTimer 定时器,定时从摄像头或视频文件中读取帧,送入 YOLOv8 模型进行推理,并将结果实时渲染到 QLabel 上。
交互反馈:检测到违规行为时,通过 QSoundEffect 播放语音预警,同时更新日志表格和统计数据。
3. 关键技术细节
实时性优化:通过多线程技术,将模型推理和界面更新分离,避免界面卡顿,确保检测流畅。
置信度调节:通过 QSlider 组件,让用户可以实时调整置信度阈值,过滤掉低置信度的误检。
数据持久化:使用 SQLAlchemy ORM 框架,将检测日志和用户信息高效地存储到数据库中,支持快速查询和导出。
五、效果展示
1. 登录界面
系统启动后,用户首先进入登录界面,输入账号密码和验证码后即可进入主系统。

2. 图片检测效果
系统可以对单张图片进行检测,精准识别出图中人员是否佩戴安全帽,并标注出置信度。
3. 视频 / 实时检测效果
在实时摄像头或视频流检测中,系统能够以毫秒级的速度处理每一帧,实时显示检测结果和预警信息。
六、模型结果


七、核心代码
import sys
import os
import pymysql
from datetime import datetime
# 将当前目录加入系统路径,确保能导入同目录的login.py
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QLabel, QLineEdit, QPushButton,
QFrame, QSpacerItem, QSizePolicy, QMessageBox,
QGraphicsDropShadowEffect)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QCursor, QColor
# 尝试导入登录窗口(添加异常处理,防止导入失败)
try:
from login import LoginWindow
except ImportError as e:
print(f"导入登录模块失败: {e}")
LoginWindow = None
# ================= MySQL 数据库配置 =================
def get_mysql_connection():
"""创建并返回 MySQL 连接(按需修改配置)"""
try:
conn = pymysql.connect(
host='localhost', # 数据库地址(本地填localhost,远程填IP)
port=3306, # MySQL端口(默认3306)
user='root', # 数据库用户名
password='123456', # 替换为你的MySQL密码
database='helmet', # 数据库名
)
return conn
except pymysql.MySQLError as e:
QMessageBox.critical(None, "数据库错误", f"连接MySQL失败:{str(e)}")
return None
class RegisterWindow(QMainWindow):
def __init__(self):
super().__init__()
self.login_window = None
self.initUI()
def initUI(self):
self.setWindowTitle('🚜 智能安全帽检测系统 - 账号注册')
self.resize(900, 580)
# 1. 设置主窗口背景
main_widget = QWidget()
main_widget.setObjectName("MainWindow")
self.setCentralWidget(main_widget)
main_layout = QVBoxLayout(main_widget)
main_layout.setContentsMargins(40, 40, 40, 40) # 留出边距,用于显示阴影
# 2. 创建居中的主卡片
self.card_frame = QFrame()
self.card_frame.setObjectName("MainCard")
card_layout = QHBoxLayout(self.card_frame)
card_layout.setContentsMargins(0, 0, 0, 0)
card_layout.setSpacing(0)
# 为卡片添加高级阴影
shadow = QGraphicsDropShadowEffect(self)
shadow.setBlurRadius(20)
shadow.setXOffset(0)
shadow.setYOffset(10)
shadow.setColor(QColor(0, 0, 0, 80))
self.card_frame.setGraphicsEffect(shadow)
# 3. 加载全局现代化 QSS 样式表
self.setup_style()
# ================= 1. 左侧信息面板 =================
left_panel = QFrame()
left_panel.setObjectName("LeftPanel")
left_layout = QVBoxLayout(left_panel)
left_layout.setContentsMargins(40, 40, 40, 40)
left_layout.setAlignment(Qt.AlignCenter)
logo_label = QLabel("📝")
logo_label.setFont(QFont("Segoe UI Emoji", 70))
logo_label.setAlignment(Qt.AlignCenter)
logo_label.setStyleSheet("margin-bottom: 20px;")
left_title = QLabel("欢迎注册")
left_title.setFont(QFont("Microsoft YaHei", 24, QFont.Bold))
left_title.setStyleSheet("color: #F8FAFC; letter-spacing: 2px;")
left_title.setAlignment(Qt.AlignCenter)
sub_title = QLabel("智能终端系统")
sub_title.setFont(QFont("Microsoft YaHei", 12))
sub_title.setStyleSheet("color: #38BDF8; margin-top: 10px; font-weight: bold;")
sub_title.setAlignment(Qt.AlignCenter)
desc_label = QLabel("加入我们,体验前沿的AI视觉检测服务\n安全、高效、精准防护")
desc_label.setFont(QFont("Microsoft YaHei", 10))
desc_label.setStyleSheet("color: #94A3B8; margin-top: 15px; line-height: 1.5;")
desc_label.setAlignment(Qt.AlignCenter)
left_layout.addStretch()
left_layout.addWidget(logo_label)
left_layout.addWidget(left_title)
left_layout.addWidget(sub_title)
left_layout.addWidget(desc_label)
left_layout.addStretch()
# ================= 2. 右侧注册面板 =================
right_panel = QFrame()
right_panel.setObjectName("RightPanel")
right_layout = QVBoxLayout(right_panel)
right_layout.setContentsMargins(50, 40, 50, 40)
right_layout.addStretch(1)
right_title = QLabel("创建新账号")
right_title.setFont(QFont("Microsoft YaHei", 18, QFont.Bold))
right_title.setStyleSheet("color: #F8FAFC; margin-bottom: 5px;")
right_title.setAlignment(Qt.AlignCenter)
right_layout.addWidget(right_title)
right_sub = QLabel("填写以下信息完成注册")
right_sub.setStyleSheet("color: #64748B; margin-bottom: 25px; font-size: 13px;")
right_sub.setAlignment(Qt.AlignCenter)
right_layout.addWidget(right_sub)
# --- 用户名输入区 ---
right_layout.addWidget(self.create_label("设置用户名"))
user_frame = QFrame()
user_frame.setProperty("class", "InputFrame")
user_layout = QHBoxLayout(user_frame)
user_layout.setContentsMargins(15, 8, 15, 8)
user_icon = QLabel("👤")
user_icon.setStyleSheet("color: #94A3B8; font-size: 14px;")
self.reg_user_input = QLineEdit()
self.reg_user_input.setPlaceholderText("请输入4-16位字母或数字")
user_layout.addWidget(user_icon)
user_layout.addWidget(self.reg_user_input)
right_layout.addWidget(user_frame)
right_layout.addSpacing(15)
# --- 密码输入区 ---
right_layout.addWidget(self.create_label("设置密码"))
pwd_frame = QFrame()
pwd_frame.setProperty("class", "InputFrame")
pwd_layout = QHBoxLayout(pwd_frame)
pwd_layout.setContentsMargins(15, 8, 15, 8)
pwd_icon = QLabel("🔒")
pwd_icon.setStyleSheet("color: #94A3B8; font-size: 14px;")
self.reg_pwd_input = QLineEdit()
self.reg_pwd_input.setPlaceholderText("请输入密码(至少6位)")
self.reg_pwd_input.setEchoMode(QLineEdit.Password)
pwd_layout.addWidget(pwd_icon)
pwd_layout.addWidget(self.reg_pwd_input)
right_layout.addWidget(pwd_frame)
right_layout.addSpacing(15)
# --- 确认密码输入区 ---
right_layout.addWidget(self.create_label("确认密码"))
pwd2_frame = QFrame()
pwd2_frame.setProperty("class", "InputFrame")
pwd2_layout = QHBoxLayout(pwd2_frame)
pwd2_layout.setContentsMargins(15, 8, 15, 8)
pwd2_icon = QLabel("🔒")
pwd2_icon.setStyleSheet("color: #94A3B8; font-size: 14px;")
self.reg_pwd2_input = QLineEdit()
self.reg_pwd2_input.setPlaceholderText("请再次输入密码以确认")
self.reg_pwd2_input.setEchoMode(QLineEdit.Password)
pwd2_layout.addWidget(pwd2_icon)
pwd2_layout.addWidget(self.reg_pwd2_input)
right_layout.addWidget(pwd2_frame)
right_layout.addSpacing(30)
# --- 按钮区 ---
self.btn_submit_register = QPushButton("立 即 注 册")
self.btn_submit_register.setObjectName("btn_register_main")
self.btn_submit_register.setCursor(QCursor(Qt.PointingHandCursor))
self.btn_submit_register.clicked.connect(self.submit_register)
right_layout.addWidget(self.btn_submit_register)
right_layout.addSpacing(10)
self.btn_back_to_login = QPushButton("已有账号?返回登录")
self.btn_back_to_login.setObjectName("btn_ghost")
self.btn_back_to_login.setCursor(QCursor(Qt.PointingHandCursor))
self.btn_back_to_login.clicked.connect(self.back_to_login)
right_layout.addWidget(self.btn_back_to_login)
right_layout.addStretch(1)
# ================= 3. 加入主卡片布局 =================
card_layout.addWidget(left_panel, 45) # 调整比例,视觉更协调
card_layout.addWidget(right_panel, 55)
main_layout.addWidget(self.card_frame)
def setup_style(self):
"""定义现代化 UI 样式表"""
style = """
/* 全局与背景 */
QWidget#MainWindow {
background-color: #0F172A; /* 深邃蓝灰背景 */
}
* {
font-family: "Segoe UI", "Microsoft YaHei", sans-serif;
}
/* 主卡片布局 */
QFrame#MainCard {
background-color: transparent;
}
QFrame#LeftPanel {
background-color: #1E293B;
border-top-left-radius: 12px;
border-bottom-left-radius: 12px;
border: 1px solid #334155;
border-right: none;
}
QFrame#RightPanel {
background-color: #0F172A;
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
border: 1px solid #334155;
border-left: 1px solid #1E293B;
}
/* 输入框包装层 */
.InputFrame {
background-color: #1E293B;
border: 1px solid #334155;
border-radius: 8px;
}
.InputFrame:hover {
border: 1px solid #475569;
background-color: #233043;
}
/* 原生输入框 */
QLineEdit {
background-color: transparent;
border: none;
color: #F8FAFC;
font-size: 14px;
padding-left: 5px;
}
QLineEdit::placeholder {
color: #64748B;
}
/* 注册主按钮 */
QPushButton#btn_register_main {
background-color: #2563EB;
color: white;
border: none;
border-radius: 8px;
padding: 14px;
font-size: 15px;
font-weight: bold;
letter-spacing: 2px;
}
QPushButton#btn_register_main:hover {
background-color: #3B82F6;
}
QPushButton#btn_register_main:pressed {
background-color: #1D4ED8;
}
/* 返回登录幽灵按钮 */
QPushButton#btn_ghost {
background-color: transparent;
color: #94A3B8;
border: 1px solid #334155;
border-radius: 8px;
padding: 12px;
font-size: 14px;
}
QPushButton#btn_ghost:hover {
border: 1px solid #475569;
color: #F8FAFC;
background-color: rgba(51, 65, 85, 0.5);
}
"""
self.setStyleSheet(style)
def create_label(self, text):
"""辅助函数:创建输入框上方的小标题标签"""
lbl = QLabel(text)
lbl.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))
lbl.setStyleSheet("color: #94A3B8; margin-bottom: 2px; margin-left: 2px;")
return lbl
def submit_register(self):
"""处理注册提交逻辑 - 写入MySQL数据库"""
# 1. 获取并验证输入
username = self.reg_user_input.text().strip()
password = self.reg_pwd_input.text().strip()
password2 = self.reg_pwd2_input.text().strip()
# 基础验证
if not username:
QMessageBox.warning(self, "注册提示", "请输入用户名!")
return
if len(username) < 4 or len(username) > 16:
QMessageBox.warning(self, "注册提示", "用户名长度需在4-16位之间!")
return
if not password:
QMessageBox.warning(self, "注册提示", "请输入密码!")
return
if len(password) < 6:
QMessageBox.warning(self, "注册提示", "密码长度至少6位!")
return
if password != password2:
QMessageBox.warning(self, "注册提示", "两次输入的密码不一致!")
return
# 2. 连接MySQL并写入数据
conn = get_mysql_connection()
if not conn:
return
try:
# 创建游标
cursor = conn.cursor()
# 检查用户名是否已存在
check_sql = "SELECT username FROM user WHERE username = %s"
cursor.execute(check_sql, (username,))
if cursor.fetchone(): # 查到数据说明用户名已存在
QMessageBox.warning(self, "注册提示", "用户名已存在!")
return
# 插入新用户(注意:实际项目中密码要加密,这里先明文演示)
insert_sql = "INSERT INTO user (username, password) VALUES (%s, %s)"
cursor.execute(insert_sql, (username, password))
# 提交事务
conn.commit()
QMessageBox.information(self, "注册成功", "账号注册成功!即将返回登录界面")
# 返回登录
self.back_to_login()
except pymysql.MySQLError as e:
conn.rollback() # 出错回滚
QMessageBox.critical(self, "数据库错误", f"注册失败:{str(e)}")
finally:
# 关闭游标和连接
cursor.close()
conn.close()
def back_to_login(self):
"""返回登录界面"""
try:
if LoginWindow is None:
QMessageBox.critical(self, "错误", "无法找到登录窗口模块!")
return
self.login_window = LoginWindow()
self.login_window.show()
self.close()
except Exception as e:
QMessageBox.critical(self, "错误", f"打开登录窗口失败:{str(e)}")
def closeEvent(self, event):
"""窗口关闭时的清理操作"""
if self.login_window and not self.login_window.isVisible():
self.login_window.show()
event.accept()
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle("Fusion")
# 启用全局字体抗锯齿优化
font = app.font()
font.setStyleStrategy(QFont.PreferAntialias)
app.setFont(font)
window = RegisterWindow()
window.show()
sys.exit(app.exec_())
八、源码获取
大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻
更多推荐

所有评论(0)