基于YOLOv8的安全帽检测系统
本文介绍了一个基于YOLOv8的安全帽检测系统,该系统利用深度学习技术实现作业场景中安全帽佩戴的实时监测。系统采用Python开发,结合Tkinter界面和OpenCV图像处理,支持图片、视频及摄像头输入的检测。文章详细阐述了项目背景、技术架构、环境配置、数据集准备、模型训练等关键环节,并提供了核心代码实现方案。该系统可有效提升工业安全监管效率,降低人工成本,为高危作业环境提供智能化安全监控解决方
基于YOLOv8的安全帽检测系统:从零到一的工业安全监控解决方案
源码获取:https://mbd.pub/o/bread/YZWXmZdwZA==
摘要
本文详细介绍了一个基于YOLOv8深度学习框架的安全帽检测系统,该系统能够实时检测图片、视频和摄像头画面中的安全帽佩戴情况。系统采用Python语言开发,结合Tkinter图形界面和OpenCV图像处理库,实现了用户友好的交互体验。文章将从项目背景、技术选型、系统架构、核心代码解析、性能优化等多个维度进行全面剖析,为读者提供完整的技术实现方案。
1. 项目背景与意义
1.1 工业安全的重要性
在建筑工地、工厂车间、电力设施等高风险作业环境中,安全帽是保护工人头部安全的重要防护装备。据统计,超过60%的工业事故与头部受伤有关,而正确佩戴安全帽可以有效减少85%的头部伤害风险。然而,传统的人工监管方式存在效率低下、监管盲区等问题,亟需智能化的监控解决方案。
1.2 计算机视觉在安全监控中的应用
随着深度学习技术的发展,计算机视觉在工业安全监控领域展现出巨大潜力。基于目标检测算法的安全帽检测系统能够实现:
- 24小时不间断监控
- 实时预警和报警
- 数据统计和分析
- 降低人工监管成本
2. 技术选型与系统架构
2.1 核心技术框架
本项目采用YOLOv8作为核心检测算法,主要技术栈包括:
- 深度学习框架: Ultralytics YOLOv8
- 编程语言: Python 3.8+
- 图形界面: Tkinter
- 图像处理: OpenCV
- 模型格式: PyTorch (.pt)
2.2 系统架构设计
系统采用分层架构设计:
应用层 (Tkinter GUI)
↓
服务层 (检测逻辑、统计功能)
↓
核心层 (YOLOv8模型、OpenCV处理)
↓
数据层 (图片、视频、摄像头流)
3. 环境配置与依赖安装
3.1 环境要求
- Python 3.8+
- CUDA 11.7+ (GPU版本)
- 至少8GB RAM
- 推荐GPU: NVIDIA GTX 1060 6GB+
3.2 依赖安装
# 创建虚拟环境
python -m venv venv
venv\Scripts\activate
# 安装核心依赖
pip install ultralytics opencv-python pillow
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
4. 数据集准备与模型训练
4.1 数据集结构
项目使用YOLO格式的数据集,目录结构如下:
css-data/
├── train/
│ ├── images/
│ └── labels/
├── valid/
│ ├── images/
│ └── labels/
└── test/
├── images/
└── labels/
4.2 数据集配置文件
safehat.yaml 配置文件定义了数据集路径和类别信息:
train: E:\ultralytics-main\css-data\train\images\
val: E:\ultralytics-main\css-data\valid\images\
nc: 2
names: ['No_SafetyHat', 'SafetyHat']
4.3 模型训练
使用以下命令训练YOLOv8模型:
yolo detect train data=safehat.yaml model=yolov8n.pt epochs=100 imgsz=640
5. 核心代码解析
5.1 主程序结构
Main.py 是整个系统的入口文件,主要包含以下功能模块:
5.1.1 导入依赖
import cv2
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from ultralytics import YOLO
import os
import time
from datetime import datetime
5.1.2 全局变量定义
# 全局变量
model = YOLO('best.pt') # 加载预训练模型
is_running = False # 检测状态标志
detection_results = [] # 检测结果存储
current_model_path = 'best.pt' # 当前模型路径
start_time = None # 计时开始时间
5.2 图片检测功能
图片检测是系统的核心功能之一,实现代码如下:
def detect_image():
global is_running, detection_results, start_time
image_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.jpeg;*.png")])
if image_path:
start_time = time.time()
img = cv2.imread(image_path)
if img is not None:
# 显示检测状态
status_label.config(text="检测中...")
root.update()
# 使用YOLO模型进行预测
results = model.predict(source=img)
detection_results = []
# 处理检测结果
for r in results:
boxes = r.boxes
for box in boxes:
cls = int(box.cls)
confidence = float(box.conf[0])
class_name = model.names[cls]
x1, y1, x2, y2 = box.xyxy[0]
# 绘制检测框和标签
color = get_color_for_class(cls)
cv2.rectangle(img, (int(x1), int(y1)), (int(x2), int(y2)), color, 2)
cv2.putText(img, f"{class_name}: {confidence:.2f}", (int(x1), int(y1) - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
# 记录检测结果
detection_results.append({
'class': class_name,
'confidence': confidence,
'position': (int(x1), int(y1), int(x2), int(y2))
})
# 更新统计信息
update_statistics()
# 显示检测结果窗口
image_window = tk.Toplevel(root)
image_window.title(f"图片检测结果 - {os.path.basename(image_path)}")
image_window.geometry("800x600")
# 使用PIL处理图像显示
from PIL import Image, ImageTk
img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 调整图像大小以适应窗口
img_pil.thumbnail((700, 500))
img_tk = ImageTk.PhotoImage(img_pil)
label = tk.Label(image_window, image=img_tk)
label.image = img_tk
label.pack(pady=10)
# 添加保存按钮
save_button = tk.Button(image_window, text="保存结果",
command=lambda: save_detection_result(img, image_path),
bg="#4CAF50", fg="white")
save_button.pack(pady=5)
# 显示检测时间
detection_time = time.time() - start_time
time_label = tk.Label(image_window, text=f"检测耗时: {detection_time:.2f}秒")
time_label.pack()
status_label.config(text="检测完成")
else:
messagebox.showerror("错误", f"无法读取图片:{image_path}")
5.3 视频检测功能
视频检测功能实现了逐帧处理和分析:
def detect_video():
global is_running, detection_results, start_time
video_path = filedialog.askopenfilename(filetypes=[("Video files", "*.mp4;*.avi;*.mkv;*.mov")])
if video_path:
start_time = time.time()
cap = cv2.VideoCapture(video_path)
is_running = True
detection_results = []
frame_count = 0
status_label.config(text="视频检测中...")
while cap.isOpened() and is_running:
ret, frame = cap.read()
if not ret:
break
frame_count += 1
# 对每一帧进行检测
results = model.predict(source=frame)
frame_detections = []
for r in results:
boxes = r.boxes
for box in boxes:
cls = int(box.cls)
confidence = float(box.conf[0])
class_name = model.names[cls]
x1, y1, x2, y2 = box.xyxy[0]
color = get_color_for_class(cls)
# 绘制检测框
cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), color, 2)
cv2.putText(frame, f"{class_name}: {confidence:.2f}", (int(x1), int(y1) - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
frame_detections.append({
'class': class_name,
'confidence': confidence,
'position': (int(x1), int(y1), int(x2), int(y2))
})
detection_results.append(frame_detections)
# 缩放视频帧显示
scale_percent = 70
width = int(frame.shape[1] * scale_percent / 100)
height = int(frame.shape[0] * scale_percent / 100)
dim = (width, height)
resized_frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
cv2.imshow('Video Detection', resized_frame)
key = cv2.waitKey(1)
if key == 27: # ESC键退出
break
cap.release()
cv2.destroyAllWindows()
# 更新统计信息
update_statistics()
status_label.config(text=f"视频检测完成,共处理{frame_count}帧")
5.4 摄像头实时检测
摄像头检测功能支持实时监控:
def start_camera_detection():
global is_running, detection_results, start_time
cap = cv2.VideoCapture(0) # 打开默认摄像头
is_running = True
detection_results = []
frame_count = 0
start_time = time.time()
status_label.config(text="摄像头实时检测中...")
while cap.isOpened() and is_running:
ret, frame = cap.read()
if not ret:
break
frame_count += 1
results = model.predict(source=frame)
frame_detections = []
for r in results:
boxes = r.boxes
for box in boxes:
cls = int(box.cls)
confidence = float(box.conf[0])
class_name = model.names[cls]
x1, y1, x2, y2 = box.xyxy[0]
color = get_color_for_class(cls)
cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), color, 2)
cv2.putText(frame, f"{class_name}: {confidence:.2f}", (int(x1), int(y1) - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
frame_detections.append({
'class': class_name,
'confidence': confidence,
'position': (int(x1), int(y1), int(x2), int(y2))
})
detection_results.append(frame_detections)
# 显示FPS
current_time = time.time()
fps = frame_count / (current_time - start_time)
cv2.putText(frame, f"FPS: {fps:.1f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow('Camera Detection', frame)
key = cv2.waitKey(1)
if key == 27: # ESC键退出
break
cap.release()
cv2.destroyAllWindows()
update_statistics()
status_label.config(text=f"摄像头检测完成,共处理{frame_count}帧")
5.5 统计信息更新函数
这是系统的重要功能,负责统计和分析检测结果:
def update_statistics():
"""更新统计信息显示"""
if detection_results:
total_detections = 0
class_counts = {}
# 处理不同类型的检测结果
for result in detection_results:
if isinstance(result, list): # 视频或摄像头检测的帧列表
for detection in result:
if isinstance(detection, dict): # 确保是检测结果字典
class_name = detection['class']
class_counts[class_name] = class_counts.get(class_name, 0) + 1
total_detections += 1
elif isinstance(result, dict): # 图片检测的单个检测结果
class_name = result['class']
class_counts[class_name] = class_counts.get(class_name, 0) + 1
total_detections += 1
stats_text = f"总检测数: {total_detections}\n"
for class_name, count in class_counts.items():
stats_text += f"{class_name}: {count}\n"
stats_label.config(text=stats_text)
5.6 辅助功能函数
5.6.1 颜色映射函数
def get_color_for_class(cls):
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (0, 255, 255), (255, 0, 255)]
return colors[cls % len(colors)]
5.6.2 结果保存函数
def save_detection_result(image, original_path):
"""保存检测结果"""
save_path = filedialog.asksaveasfilename(
defaultextension=".jpg",
filetypes=[("JPEG files", "*.jpg"), ("PNG files", "*.png")],
initialfile=f"detected_{os.path.basename(original_path)}"
)
if save_path:
cv2.imwrite(save_path, image)
messagebox.showinfo("成功", f"检测结果已保存到: {save_path}")
5.6.3 模型加载函数
def load_model():
"""加载自定义模型"""
global model, current_model_path
model_path = filedialog.askopenfilename(
filetypes=[("PyTorch模型", "*.pt"), ("所有文件", "*.*")],
title="选择YOLO模型文件"
)
if model_path:
try:
model = YOLO(model_path)
current_model_path = model_path
status_label.config(text=f"已加载模型: {os.path.basename(model_path)}")
messagebox.showinfo("成功", f"模型加载成功: {os.path.basename(model_path)}")
except Exception as e:
messagebox.showerror("错误", f"模型加载失败: {str(e)}")
6. 图形界面设计
6.1 主界面布局
系统采用Tkinter构建用户友好的图形界面:
# 创建主窗口
root = tk.Tk()
root.title('安全帽检测系统')
root.geometry("600x500")
# 创建主框架
main_frame = ttk.Frame(root, padding="20")
main_frame.pack(fill=tk.BOTH, expand=True)
# 标题
title_label = tk.Label(main_frame, text="安全帽检测系统", font=("Helvetica", 16, "bold"))
title_label.pack(pady=10)
# 模型信息
model_info = tk.Label(main_frame, text=f"当前模型: {os.path.basename(current_model_path)}",
font=("Helvetica", 10))
model_info.pack(pady=5)
6.2 功能按钮设计
# 按钮框架
button_frame = ttk.Frame(main_frame)
button_frame.pack(pady=20)
# 检测功能按钮
image_button = tk.Button(button_frame, text="图片检测", command=detect_image,
bg="#4CAF50", fg="white", font=("Helvetica", 12), width=15, height=2)
image_button.grid(row=0, column=0, padx=10, pady=10)
video_button = tk.Button(button_frame, text="视频检测", command=detect_video,
bg="#2196F3", fg="white", font=("Helvetica", 12), width=15, height=2)
video_button.grid(row=0, column=1, padx=10, pady=10)
camera_button = tk.Button(button_frame, text="摄像头检测", command=start_camera_detection,
bg="#FF9800", fg="white", font=("Helvetica", 12), width=15, height=2)
camera_button.grid(row=0, column=2, padx=10, pady=10)
6.3 统计信息显示
# 统计信息框架
stats_frame = ttk.LabelFrame(main_frame, text="统计信息", padding="10")
stats_frame.pack(fill=tk.X, pady=10)
stats_label = tk.Label(stats_frame, text="暂无检测数据", justify=tk.LEFT)
stats_label.pack()
# 状态栏
status_frame = ttk.Frame(main_frame)
status_frame.pack(fill=tk.X, pady=5)
status_label = tk.Label(status_frame, text="就绪", relief=tk.SUNKEN, anchor=tk.W)
status_label.pack(fill=tk.X)
7. 性能优化与调试
7.1 性能优化策略
- 模型优化: 使用YOLOv8n轻量级模型
- 图像缩放: 检测前适当缩放图像
- 批量处理: 视频检测时优化帧处理
- 内存管理: 及时释放不再使用的资源
7.2 调试技巧
- 日志记录: 添加详细的运行日志
- 性能监控: 实时显示FPS和检测时间
- 错误处理: 完善的异常捕获机制
- 用户反馈: 清晰的状态提示信息
8. 系统测试与验证
8.1 功能测试
测试用例包括:
- 图片检测准确性
- 视频流畅性
- 摄像头实时性
- 统计功能正确性
8.2 性能测试
测试环境:
- CPU: Intel i7-10700K
- GPU: NVIDIA RTX 3060 12GB
- RAM: 32GB DDR4
测试结果:
- 图片检测: ~55ms/张
- 视频检测: ~25FPS (640x480)
- 内存占用: <500MB
9. 应用场景与扩展
9.1 典型应用场景
- 建筑工地安全监控
- 工厂生产安全监管
- 电力设施安全巡查
- 教育培训演示
9.2 功能扩展方向
- 多类别检测: 增加其他安全装备检测
- 云端部署: 支持远程监控
- 移动端应用: 开发手机APP
- 数据分析: 生成统计报表
10. 总结与展望
10.1 技术总结
本项目成功实现了基于YOLOv8的安全帽检测系统,具有以下特点:
- 高精度检测: 准确识别安全帽佩戴情况
- 多模式支持: 图片、视频、摄像头全面覆盖
- 用户友好: 简洁直观的图形界面
- 易于扩展: 模块化设计便于功能扩展
10.2 未来展望
未来可以进一步优化:
- 集成更先进的YOLO版本
- 支持更多安全装备检测
- 开发Web端应用
- 实现智能预警系统



火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)