简介这份资源面向计算机、人工智能、自动化等专业的在校学生与教师提供一套可直接运行的智慧工厂危险区域闯入识别方案适合作为毕业设计、课程设计或大作业的完整参考。项目以YOLOv8目标检测为核心配套可视化界面能够对工厂危险区域的人员闯入行为进行实时识别与预警兼顾算法训练与交互展示。压缩包共8个文件约15.91MB包含3个Python脚本、3个模型权重文件与2个说明文本分别对应模型训练、视频检测、可视化页面设计以及预训练权重与使用说明结构清晰、便于快速部署。资源内还提供核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果与标签分布图等完整实验产物方便直接用于答辩展示与结果分析。目前已有28人学习下载代码均经测试运行成功拿来即可上手也可在此基础上修改扩展实现更多检测功能。1. 从一次产线误报说起危险区域闯入识别到底难在哪去年帮一家做汽车零部件冲压的客户做安全改造他们最头疼的不是摄像头不够而是误报太多。冲压机旁边划了黄色警戒线工人偶尔伸手取件传统方案用红外对射或者区域像素变化检测结果一只飞鸟、一束叉车灯光、甚至蒸汽都能触发停机一天停十几次产线班长直接把报警器电源拔了。这就是危险区域闯入识别最真实的痛点不是检测不到人而是分不清「人」和「像人的东西」更分不清「路过」和「闯入」。基于 YOLOv8 的智慧工厂危险区域闯入识别系统核心思路是把目标检测和区域逻辑判断拆开YOLOv8 负责在每一帧里稳定找出 person 这个类区域判断负责回答「这个人的脚底点有没有落在危险多边形内」。这样做的好处是模型只学「人长什么样」区域规则可以随时改换车间、换工位不用重新训练。这套方案适合做毕设或课程设计的同学也适合工厂里想快速验证视觉安全方案的工程师因为源码、数据集、可视化界面和部署教程都打包好了简单部署即可运行不用从零搭环境。我见过太多人一上来就调 YOLOv8 的 head 或者换 backbone结果连标注格式都没对齐训练 loss 都不降。先把「检测 区域判断」这条链路跑通再谈改进才是正经落地路径。下面按我实际部署的顺序从环境、数据、训练、区域逻辑到可视化界面一步步拆开讲。2. 环境配置与 YOLOv8 安装CPU 版本也能先跑通2.1 为什么建议先用 CPU 版本验证链路很多同学拿到源码第一反应是找 GPU但如果你手头只有一台办公笔记本或者实验室服务器暂时排不上用 CPU 版本先把推理和区域判断跑通完全可行。YOLOv8n 在 CPU 上单帧推理大约 80 到 150 毫秒对于危险区域闯入这种不需要 60 帧实时性的场景5 到 10 FPS 足够触发报警。等链路验证没问题再换 GPU 训练自己的数据集效率会高很多。Ubuntu 20.04 和 CentOS 7 都能装但 CentOS 7 默认 Python 版本太低建议用 conda 建独立环境。Windows 上跑可视化界面也没问题只是 OpenCV 的 GUI 依赖需要额外注意。我一般会先建一个干净的虚拟环境避免和系统里的包打架。# 创建 Python 3.9 虚拟环境YOLOv8 对 3.8-3.10 支持最好 conda create -n yolov8_factory python3.9 -y conda activate yolov8_factory # 安装 PyTorch CPU 版本注意去官网复制对应命令这里以 pip 为例 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu # 安装 ultralytics 和可视化界面依赖 pip install ultralytics opencv-python pillow pyyaml tqdm这段命令的逻辑是先隔离环境再装 PyTorch 作为 YOLOv8 的推理后端最后装 ultralytics 这个官方库。参数上唯一要注意的是 PyTorch 版本如果你后面要换 GPU把--index-url换成 CUDA 对应的地址即可。装完后用yolo checks验证能看到环境信息就说明基础链路通了。2.2 验证 YOLOv8 安装是否成功的最小命令不要急着跑训练先用官方预训练权重做一次推理确认模型能加载、能出框。这一步能排除 80% 的环境问题。# 下载 yolov8n.pt 并在一张测试图上推理 yolo predict modelyolov8n.pt sourcehttps://ultralytics.com/images/bus.jpg saveTrue如果这条命令能跑通并在runs/detect/predict下生成带框的图片说明 YOLOv8 安装没问题。常见翻车点是网络下载权重失败可以手动下载yolov8n.pt放到当前目录把model改成./yolov8n.pt。另一个坑是 OpenCV 版本冲突如果报cv2.imshow相关错误重装opencv-python-headless换成opencv-python即可。提示CPU 版本推理时把imgsz设成 640 就够了设太大只会拖慢速度对危险区域判断精度提升有限。3. 数据集处理从 Labelme 标注到 YOLOv8 格式的完整转换3.1 危险区域闯入数据集应该标什么这个系统的数据集不需要标「闯入」这个行为只需要标person一个类。因为闯入是区域逻辑判断的结果不是视觉特征。我见过有人把「人」和「闯入的人」分成两类标结果模型根本学不会因为同一个人的姿态在不同帧里差异太大。正确做法是所有出现人的帧都标person框要贴紧人体包括被设备部分遮挡的情况。数据集来源可以是工厂实地拍摄也可以用公开行人数据集补充。关键是场景要覆盖你的目标车间光照变化、人员穿工服、戴安全帽、叉车经过遮挡等。一般 2000 到 5000 张图就能出一个可用的模型太少容易过拟合太多标注成本高。Labelme 标注后会生成 JSON 文件每个 JSON 对应一张图里面记录了多边形或矩形框的坐标。3.2 Labelme JSON 转 YOLO txt 的脚本与四个边界坑YOLOv8 需要的是每张图一个.txt每行class_id x_center y_center width height全部归一化到 0 到 1。下面这个脚本我用了很多次直接改路径就能跑。import json import os from pathlib import Path # 输入 Labelme JSON 文件夹输出 YOLO 标签文件夹 json_dir Path(labelme_jsons) out_dir Path(yolo_labels) out_dir.mkdir(exist_okTrue) # 类别映射这里只有 person 一类 class_map {person: 0} for json_file in json_dir.glob(*.json): with open(json_file, r, encodingutf-8) as f: data json.load(f) img_w data[imageWidth] img_h data[imageHeight] lines [] for shape in data[shapes]: label shape[label] if label not in class_map: continue points shape[points] # 取多边形或矩形的外接矩形 xs [p[0] for p in points] ys [p[1] for p in points] x_min, x_max min(xs), max(xs) y_min, y_max min(ys), max(ys) # 边界裁剪防止标注超出图像范围 x_min max(0, min(x_min, img_w - 1)) x_max max(0, min(x_max, img_w - 1)) y_min max(0, min(y_min, img_h - 1)) y_max max(0, min(y_max, img_h - 1)) # 归一化中心点和宽高 x_center (x_min x_max) / 2.0 / img_w y_center (y_min y_max) / 2.0 / img_h w (x_max - x_min) / img_w h (y_max - y_min) / img_h # 过滤掉宽高为 0 的无效框 if w 0 or h 0: continue lines.append(f{class_map[label]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) # 即使没有目标也要生成空文件否则训练时会报找不到标签 with open(out_dir / (json_file.stem .txt), w) as f: f.write(\n.join(lines))逻辑说明脚本遍历每个 JSON读取图像宽高把每个person形状转成外接矩形再归一化。四个边界坑分别是第一标注点可能超出图像边界不裁剪会导致归一化值大于 1训练时报错第二宽或高为 0 的框要过滤否则 YOLOv8 会报invalid labels第三没有目标的图也要生成空 txt否则数据集校验会失败第四类别名必须和data.yaml里的names顺序一致这里person对应 0。3.3 data.yaml 的写法与训练集验证集划分转换完标签后按 8:1:1 划分训练、验证、测试集目录结构建议如下dataset/ images/ train/ val/ test/ labels/ train/ val/ test/然后写data.yamlpath: ./dataset train: images/train val: images/val test: images/test nc: 1 names: [person]nc是类别数这里只有 person 所以是 1。names的顺序必须和转换脚本里的class_map一致。如果后面要加安全帽、反光衣等类别改这里和脚本里的映射即可但危险区域闯入本身只需要 person。4. 训练自己的数据集参数怎么设、曲线怎么看4.1 YOLOv8 训练命令与关键参数解释环境、数据都准备好后训练命令其实很短但参数设不对会浪费很多时间。yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns_factory \ nameexp1逐项说明modelyolov8n.pt表示从预训练权重开始微调比自己从头训快很多epochs100对 2000 到 5000 张图足够如果 loss 还在降可以加到 150imgsz640是输入分辨率工厂场景里人占画面比例不大640 够用想提升小目标可以试 960 但显存要够batch16在 8G 显存上比较稳CPU 训练就设 4 或 8lr00.01是初始学习率微调时不要设太大否则预训练权重会被冲掉patience20表示 20 轮验证指标不提升就早停省时间。训练开始后终端会打印每轮的 box_loss、cls_loss 和 mAP。重点看mAP50-95和mAP50前者更严格。如果cls_loss一直不降检查标签类别是否对如果box_loss震荡把lr0降到 0.005 再试。4.2 用损失函数曲线判断过拟合与欠拟合训练完成后runs_factory/exp1下会有results.csv和results.png。我一般会画一张损失曲线图直观判断模型状态。import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs_factory/exp1/results.csv) df.columns df.columns.str.strip() plt.figure(figsize(10, 5)) plt.plot(df[epoch], df[train/box_loss], labeltrain box loss) plt.plot(df[epoch], df[val/box_loss], labelval box loss) plt.plot(df[epoch], df[train/cls_loss], labeltrain cls loss) plt.plot(df[epoch], df[val/cls_loss], labelval cls loss) plt.xlabel(epoch) plt.ylabel(loss) plt.legend() plt.savefig(loss_curve.png, dpi150)逻辑说明训练 loss 和验证 loss 同时下降且接近说明拟合正常训练 loss 继续降但验证 loss 抬头就是过拟合需要加数据或加增强两条都居高不下是欠拟合检查学习率或模型容量。危险区域闯入场景里过拟合的典型表现是验证集 mAP 高但实际车间误报多因为训练集场景太单一。注意不要只看 mAP 高就上线一定要用一段没参与训练的车间视频做推理测试看误报和漏报。4.3 模型导出与推理速度优化训练完的best.pt可以直接用于推理但如果要部署到边缘设备可以导出 ONNX 或 TensorRT。CPU 部署建议导出 ONNX用 OpenCV DNN 或 ONNX Runtime 加载比 PyTorch 直接推理快 20% 到 30%。yolo export modelruns_factory/exp1/weights/best.pt formatonnx imgsz640导出后得到best.onnx推理时把modelbest.pt换成modelbest.onnx即可。如果部署到 RK3588 或 Hi3516CV610 这类板端需要走对应的模型转换工具链流程更复杂建议先用 PC 验证效果再上板。5. 危险区域判断逻辑与可视化界面实现5.1 多边形区域定义与脚底点判断检测到人之后怎么判断「闯入」我一般用脚底点也就是检测框底边的中点。相比用框中心点脚底点更符合地面区域的实际位置人站在区域外但身体前倾时中心点可能已经在区域内脚底点不会误判。区域用多边形表示支持任意形状比如冲压机周围的 L 形警戒区。判断点是否在多边形内用射线法OpenCV 自带pointPolygonTest。import cv2 import numpy as np # 定义危险区域多边形坐标按实际画面比例设置 danger_zone np.array([[200, 300], [500, 300], [500, 600], [200, 600]], dtypenp.int32) def is_intrusion(box, zone): # box 格式 [x1, y1, x2, y2] x1, y1, x2, y2 box # 脚底点底边中点 foot_x (x1 x2) / 2.0 foot_y y2 # pointPolygonTest 返回正数表示在内部 result cv2.pointPolygonTest(zone, (foot_x, foot_y), False) return result 0逻辑说明danger_zone是四个顶点实际使用时可以用鼠标在界面上点选生成。pointPolygonTest的第三个参数False表示只返回距离符号不返回具体距离速度更快。如果返回大于等于 0说明脚底点在区域内触发闯入报警。参数上要注意区域坐标必须和推理时的图像尺寸一致。如果推理时做了 resize区域坐标也要按比例缩放。我一般会在界面上让用户直接在原始分辨率上画区域推理前再把区域缩放到模型输入尺寸避免坐标错位。5.2 可视化界面用 PyQt5 还是 Web 端源码里通常带一个可视化界面常见的是 PyQt5 或 Gradio。PyQt5 适合本地桌面运行能直接调摄像头延迟低Gradio 适合浏览器访问方便演示但延迟稍高。如果是毕设答辩PyQt5 更稳因为不依赖网络。界面核心功能就三块视频显示、区域绘制、报警日志。视频显示用 OpenCV 读帧YOLOv8 推理后画框和区域闯入时框变红并记录时间。区域绘制用鼠标事件收集顶点右键闭合。报警日志写到一个列表里支持导出 CSV。# 简化版 PyQt5 视频循环逻辑 cap cv2.VideoCapture(0) while True: ret, frame cap.read() if not ret: break results model(frame, imgsz640, verboseFalse) for r in results: for box in r.boxes: x1, y1, x2, y2 map(int, box.xyxy[0]) if is_intrusion([x1, y1, x2, y2], danger_zone): cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2) # 记录报警 else: cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.polylines(frame, [danger_zone], True, (0, 255, 255), 2) cv2.imshow(Factory Safety, frame) if cv2.waitKey(1) 0xFF ord(q): break这段代码把检测、区域判断、绘制串起来。verboseFalse关掉 YOLO 的日志输出避免刷屏。实际界面里会把cv2.imshow换成 Qt 的 QLabel 显示报警日志写到表格控件。5.3 报警去抖与多目标处理实际产线上人走过区域边缘时可能连续几帧触发又消失如果每帧都报警日志会爆炸。我一般加一个计数器连续 3 帧检测到闯入才触发一次报警报警后 5 秒内不重复报同一目标。多目标时给每个框分配一个简单 ID用 IOU 匹配前后帧避免同一个人被反复计数。# 简单去抖逻辑 intrusion_counter 0 alarm_cooldown 0 if is_intrusion(box, danger_zone): intrusion_counter 1 else: intrusion_counter 0 if intrusion_counter 3 and alarm_cooldown 0: trigger_alarm() alarm_cooldown 50 # 约 5 秒按 10FPS 算 if alarm_cooldown 0: alarm_cooldown - 1参数3和50根据实际帧率调整。帧率低就减小计数阈值帧率高就增大冷却帧数。这个逻辑不复杂但不加的话演示时会被频繁报警搞得很尴尬。6. 避坑与排查部署危险区域识别系统时最容易翻车的 5 个点6.1 现象训练 loss 正常但推理时一个框都没有原因通常是推理时的图像预处理和训练时不一致。YOLOv8 训练时默认做了 letterbox 填充推理时如果直接 resize 会改变宽高比导致目标变形。解决方法是推理时也用model.predict的默认预处理不要自己手动 resize 后再送入模型。如果必须手动处理确保保持宽高比并填充灰边。6.2 现象区域判断总是误报人明明在区域外先检查区域坐标和推理图像尺寸是否匹配。常见情况是界面按 1920x1080 画的区域但推理时把帧缩到了 640x640坐标没同步缩放。解决方法是统一在原始分辨率上做区域判断或者把区域坐标按缩放比例同步变换。另一个原因是用了框中心点而不是脚底点改成脚底点后误报会明显减少。6.3 现象CPU 推理太慢视频卡成幻灯片YOLOv8n 在 CPU 上单帧 100 毫秒左右如果同时开可视化界面和视频解码很容易掉到 2 到 3 FPS。解决方法是把推理分辨率降到 416 或 320或者跳帧推理每 3 帧检测一次中间帧沿用上一次结果。如果还慢导出 ONNX 用 ONNX Runtime 推理开启多线程。6.4 现象换一个车间后模型完全失效这是过拟合到训练场景的典型表现。训练集里如果只有白天、固定角度、穿同色工服的人换到夜间或逆光场景模型召回率会暴跌。解决方法是在数据集里加入目标场景的样本至少 500 张覆盖不同光照和角度。如果来不及重新标先用现有模型加一个低阈值推理把误报和漏报的帧截下来人工筛选再增量训练。6.5 现象可视化界面打包成 exe 后打不开PyQt5 打包时经常漏掉 OpenCV 的依赖库。用 PyInstaller 打包时加--hidden-importcv2和--collect-all ultralytics否则运行时找不到模型或 DLL。另一个坑是模型权重文件没有一起打包exe 在别的机器上找不到best.pt。解决方法是用--add-data把权重和配置文件一起打进去运行时用sys._MEIPASS定位路径。7. 进阶技巧用区域掩码和轨迹过滤把误报再降一半如果你已经把基础链路跑通想让系统在车间里真正可用我建议加两个东西区域掩码和轨迹过滤。区域掩码是把危险区域从画面里裁出来单独做检测减少区域外人员的干扰轨迹过滤是记录每个人连续多帧的位置只有从区域外进入区域内才算闯入已经在区域内的人不重复报警。先讲区域掩码。YOLOv8 支持classes参数只检测特定类别但不支持只检测特定区域。我的做法是在推理前把区域外的像素涂黑或者用 ROI 裁剪。涂黑更简单但会改变画面统计特性可能影响模型。ROI 裁剪更干净但区域坐标要重新映射。我一般用 ROI 裁剪因为危险区域通常只占画面一小部分裁出来还能提高小目标分辨率。# ROI 裁剪推理区域外不检测 x, y, w, h cv2.boundingRect(danger_zone) roi frame[y:yh, x:xw] results model(roi, imgsz640, verboseFalse) # 检测框坐标映射回原图 for r in results: for box in r.boxes: x1, y1, x2, y2 map(int, box.xyxy[0]) x1 x; x2 x; y1 y; y2 y # 后续判断和绘制这段代码把危险区域的外接矩形裁出来推理检测框再映射回原图。好处是区域外的人不会被检测减少计算量和误报。参数上注意boundingRect返回的是整数坐标裁剪时要确保不越界。再讲轨迹过滤。简单做法是给每个检测框分配一个 ID用 IOU 匹配前后帧。如果某个 ID 的脚底点从区域外变成区域内才触发报警如果一开始就在区域内只记录不报警。这样能过滤掉在区域内工作的人只抓真正闯入的。# 简化轨迹过滤记录上一帧脚底点是否在区域内 track_history {} # id - last_inside def check_intrusion_with_track(track_id, foot_point, zone): inside cv2.pointPolygonTest(zone, foot_point, False) 0 last_inside track_history.get(track_id, False) track_history[track_id] inside # 只有从外到内才报警 return inside and not last_inside这个逻辑需要配合目标跟踪YOLOv8 本身不带跟踪可以用 ByteTrack 或简单的 IOU 匹配。如果不想引入跟踪库用检测框的 IOU 做前后帧关联也能凑合但人走动快时容易断。我一般会加一个最大丢失帧数超过 10 帧没匹配上就删除轨迹。最后说一个验证方法不要只看 mAP用一段 10 分钟的车间视频跑一遍统计误报次数和漏报次数。误报包括区域外人员被误判、非人员目标被误判漏报包括真实闯入没报警。我自己的经验是mAP50 到 0.9 以上实际误报仍然可能每小时好几次必须靠区域逻辑和轨迹过滤压下去。这套系统值不值得做取决于你能不能接受「检测模型只负责找人业务逻辑负责判断」这个分工。我踩过最大的坑就是试图让模型直接学「闯入」行为结果标注成本翻倍效果还差。把问题拆开每一层都简单可控才是工程落地的习惯。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
代码管理软件国产化替代实战:从Git迁移到权限重建的完整指南 我先把话说在前面:如果你的团队现在还在用GitLab、GitHub Enterprise这类国外代码托管系统,而且公司有信创改造或者国产化验收的要求,那这篇文章就是给你写的。我不绕弯子,直接讲代码管理软件国产化替代这件事到底怎么做ÿ… · 2026/9/24 18:16:27
OpenCV眼底病灶检测:从图像预处理到临床可用的完整实践 简介:本资源是一套基于Python与OpenCV实现的视网膜图像眼底病灶检测完整项目,面向计算机、人工智能、生物医学工程等专业的本科生及研究生,适用于毕业设计、课程设计与医学图像分析入门实践。项目覆盖微动脉瘤、出血点、硬性/软性渗出物及血管… · 2026/9/24 18:16:27
AI文本可视化工具实测:从杂乱文本到结构化思维导图与流程图 先交代一下背景,我最近在折腾各种 AI 效率工具,其实不是刻意去追新,而是手头确实碰到一个痛点:平时写技术方案、整理会议纪要、梳理需求逻辑,经常要对着好几千字的文本发愁,纯文字读起来太费劲,… · 2026/9/24 18:16:27
从2比10到25比23:中国女排用23天完成一场漂亮的翻身仗 2比10落后,还能赢吗?
9月22日晚,2026年爱知名古屋亚运会女排决赛,中国女排在第三局开局落后8分的情况下,将比分追至19平,最终以25比23完成逆转。随着日本队最后一次接发球出界,中国女排以3比0击… · 2026/9/24 18:43:57
TransUnet眼底血管分割实战:拆解Transformer与U-Net缝合细节 简介:本资源是一套基于TransUnet架构实现眼底血管DRIVE数据集分割的完整实战方案,面向医学图像分割初学者与深度学习实践者,解决视网膜血管结构精准分割这一典型生物医学图像分析任务。压缩包共76个文件,含40张标注图像࿰… · 2026/9/24 18:43:57
Java Spring Boot搭建智慧养老平台:从设备接入到告警落地 简介:一套基于SpringBoot的智慧养老平台Java源码,面向计算机、电子信息工程等专业的学习者,可作为毕业设计、课程设计或期末大作业使用。项目采用B/S架构与MVC分层设计,后端整合SpringBoot、Mybatis与MySQL,前端结合Vu… · 2026/9/24 18:43:57
Flutter For OpenHarmony开发:用Liquid模板引擎优雅处理动态文本 做 Flutter For OpenHarmony 开发,我把文本拼接这块硬骨头啃下来了做 Flutter For OpenHarmony 开发有一阵子了,要我说,最容易被低估的坑不在 UI,不在状态管理,反而在"文本处理"这种不起眼的地方。尤其那种&… · 2026/9/24 18:43:57
Flutter for OpenHarmony实战:扫雷游戏数字显示与适配解析 最近在折腾Flutter for OpenHarmony的游戏合集类App,踩了不少坑,也积累了一些可复现的经验。这个项目本身不复杂,就是做一个包含多个小游戏的App,先落地的是扫雷模块,重点难点在棋盘数字的生成与显示。但越是不复杂的项… · 2026/9/24 18:43:57
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44