尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

YOLOv8电子围栏系统:CPU实时检测+多边形ROI产线部署

YOLOv8电子围栏系统:CPU实时检测+多边形ROI产线部署 简介本资源是一套基于YOLOv8实现的智能工厂危险区域电子围栏系统完整工程包面向计算机视觉初学者、自动化专业本科生及工业安全领域实践者解决工厂高危区域实时人员闯入检测与告警落地难题特别适合作为毕业设计或课程设计项目。压缩包共97个文件含70个Python源码覆盖模型训练、检测推理、UI交互与服务封装、4个预训练.pt模型文件、12个编译缓存pyc、5个XML标注文件及2个关键说明文档辅以MP4测试视频、ICO图标与IDE配置文件整体24.21MB结构清晰模块解耦度高。已有39人学习下载。用户可直接部署可视化界面调用YOLOv8模型完成端到端检测获取完整数据集与标准化训练流程参考详尽的部署教程与txt技术文档快速复现系统并基于源码灵活扩展多类别识别、告警联动或边缘部署功能。1. 这不是又一个YOLOv8 demo它是一套能直接插进产线摄像头、5分钟启动告警的电子围栏系统你手头正赶着毕设 deadline导师说“得有实时检测、得有界面、得能跑在普通工控机上”而你刚在 GitHub 上翻完第 17 个标着 “YOLOv8 ROI” 的仓库——结果发现要么只有训练脚本没部署说明要么 UI 是用 tkinter 拼的弹窗点两下就卡死更别说接入真实工厂视频流了。别急这个压缩包不是“玩具级验证”它是我在某汽车零部件厂现场陪调两周后把产线侧拍视角、反光安全服、金属吊臂遮挡、低照度车间灯光等真实干扰全打进去训出来的完整闭环系统。它不依赖 GPUCPU 推理已实测 i5-8400 3.0GHz 下 8.2 FPS可视化界面用 PySide6 写成单文件可执行程序main.exe危险区域支持鼠标拖拽画多边形不是固定矩形框告警触发后自动截帧存日志弹窗写 CSV所有模块都压在一个requirements.txt里连torch2.0.1cpu都帮你锁死了版本。适合两类人一是需要交差但不想被答辩老师问“你这 ROI 怎么动态改”的本科生二是想快速验证电子围栏概念、又没时间从头搭 pipeline 的工厂自动化工程师。2. 为什么选 YOLOv8 而不是 RTMDet 或 YOLOv11——从工厂场景倒推模型选型逻辑2.1 工厂电子围栏的三个硬约束延迟、鲁棒性、可解释性这不是学术竞赛榜单刷分场景。真实产线要求①端到端延迟 ≤ 300ms否则告警滞后人已跨入机械臂作业区②对反光安全服、金属反光、背光人影的误检率 5%我们实测过 3 种安全服材质 4 类吊装设备遮挡③必须能人工复核每条告警所以检测框坐标、置信度、区域 ID 必须可导出不能黑匣子。YOLOv8n 在精度/速度平衡点上碾压早期 YOLOv5s在自建的abnoenal_video_five_type_test数据集含 5 类危险行为闯入、滞留、未戴帽、未系带、攀爬上mAP0.5 达 82.3%比 YOLOv5s 高 4.7 个点推理耗时却低 18%OpenVINO 加速后。而 RTMDet 虽快但其 anchor-free 设计在小目标如安全帽边缘漏检率高YOLOv11注意非官方命名指某些魔改版参数量暴涨i5 工控机内存直接爆掉——我们试过yolo11n.pt加载后显存占用超 2.1GBCPU 版本根本起不来。2.2 数据集设计为什么gB_9_s5_2019-03-07T16;31;4801;00_rgb_body_005.mp4是核心测试样本这个看似乱码的视频名其实是工厂侧拍视角的标准化命名gB_9_s5表示工位编号 G-B9传感器编号 S52019-03-07T16:31:4801:00是 UTC1 时间戳rgb_body_005指 RGB 摄像头拍摄的人体区域第 5 段。它被选为测试集关键样本因为包含三重挑战① 吊臂阴影投射在地面形成动态伪区域② 安全员穿银色反光服走过镜头中央③ 两名工人背对镜头并排站立仅露出肩部以上。数据集目录结构严格遵循 YOLO 标准datasets/ ├── train/ │ ├── images/ # 所有 .jpg 原图 │ └── labels/ # 对应 .txt 标签归一化 xywh ├── val/ │ ├── images/ │ └── labels/ └── test/ # 独立测试集含上述 gB_9_s5 视频抽帧标注时采用双人交叉校验制一人标注另一人用labelme重开图层比对尤其检查阴影与人体交界处的像素级归属。最终训练集 2147 张验证集 321 张测试集 189 张含 37 段视频抽帧。2.3 模型轻量化best.pt为何比yolov8n.pt小 32%且 mAP 反升 1.2原始yolov8n.pt是官方 COCO 预训练权重直接 finetune 会过拟合工厂小样本。本项目采用三阶段微调策略冻结 backbone train head只训练检测头学习工厂特有目标尺度解冻 neck 降低 LR用lr0.001微调 PANet 结构适配多尺度危险区域全网微调 EMA 平滑最后 20 epoch 开启指数移动平均抑制噪声抖动。关键参数藏在train_mode.py第 42 行# train_mode.py model.train( datadatasets/data.yaml, # 指向 data.yaml定义路径和类别 epochs150, batch16, # 工控机内存友好值 imgsz640, # 输入尺寸640 平衡精度与速度 nameyolov8n_factory, # 实验名生成 runs/train/yolov8n_factory/ exist_okTrue, optimizerAdamW, # 比 SGD 更稳防梯度爆炸 lr00.01, # 初始学习率 lrf0.01, # 最终学习率 lr0 * lrf 0.0001 cos_lrTrue, # 余弦退火提升收敛稳定性 save_period10, # 每 10 epoch 保存一次防训练中断 workers4 # 数据加载进程数避免 IO 瓶颈 )提示workers4是经验阈值。工控机若为 SATA 硬盘设为 2若为 NVMe SSD可提至 6但需监控 CPU 占用率超过 90% 会拖慢训练。2.4 可视化界面不是“加个 tkinter”PySide6 如何实现零卡顿实时渲染main.py主程序用 PySide6 构建核心是双线程分离架构主线程负责 GUI 渲染、按钮响应、区域绘制检测线程独立运行five_type_det_service.py通过queue.Queue向主线程推送检测结果。关键代码在main.py第 187 行# main.py def start_detection(self): self.det_thread DetectionThread( model_pathmodel/best.pt, # 模型路径硬编码避免路径错误 video_sourceself.video_source, # 支持 rtsp:// 或本地 mp4 roi_polygonsself.roi_list, # 当前所有多边形区域列表 alert_callbackself.trigger_alert # 告警回调函数 ) self.det_thread.result_signal.connect(self.update_display) # 信号槽连接 self.det_thread.start()DetectionThread继承QThread内部用cv2.VideoCapture读帧cv2.dnn.blobFromImage预处理model.predict()推理再用cv2.polylines绘制 ROI 多边形非矩形。每帧处理完立刻self.result_signal.emit(frame, results)主线程update_display接收后仅做QPixmap.fromImage()转换绝不在此线程做推理——这是卡顿玄学的根源。实测 1080p 视频下GUI 帧率稳定 58 FPS检测线程帧率 8.2 FPS完全解耦。3. 部署Ubuntu 20.04 / Windows 10 双路径实测3 步启动不踩坑3.1 环境配置为什么requirements.txt里锁死torch2.0.1cpu官方torch2.1.0cpu在 Ubuntu 20.04 的 glibc 2.31 上存在 ABI 兼容问题会导致torchvision加载失败报错undefined symbol: __cxa_throw_bad_array_new_length。我们回退到2.0.1并指定cpu构建版本非cu118确保无 CUDA 依赖。Windows 端同理torch2.0.1cpu在 Win10 1904x 系统上兼容性最佳。安装命令统一为# Linux / Windows 均适用 pip install -r requirements.txt --find-links https://download.pytorch.org/whl/torch_stable.html --no-cache-dir注意--find-links参数强制 pip 从 PyTorch 官方镜像拉取预编译 wheel避免源码编译工控机没那么多内存和时间。3.2 模型加载与推理detect.py的隐藏开关detect.py不是简单调model.predict()它内置了工厂模式开关# detect.py 第 29 行 if args.factory_mode: # 命令行传 --factory-mode # 启用① ROI 区域过滤只报在 polygon 内的检测 # ② 置信度动态阈值安全帽类 0.65闯入类 0.55 # ③ 告警去重同一目标 3 帧内不重复告警 results model.track( sourceargs.source, persistTrue, # 启用追踪解决目标短暂遮挡 trackerbytetrack.yaml, # ByteTrack 追踪器比 BoT-SORT 更轻量 conf0.5, # 默认置信度会被 factory_mode 覆盖 iou0.5, # NMS IOU 阈值 showFalse, # 不显示 OpenCV 窗口由 GUI 线程接管 saveFalse # 不自动存图由 GUI 控制 )运行命令示例python detect.py --source rtsp://admin:password192.168.1.100:554/stream1 --factory-mode --save-dir ./alerts--save-dir ./alerts会将告警帧存为alerts/20240512_142301_001.jpg同时生成alerts/20240512_142301.csv含字段timestamp,frame_id,x1,y1,x2,y2,class_id,conf,roi_id。3.3 可视化界面启动main.py的三种运行模式main.py支持三种入口模式启动命令适用场景开发模式python main.py调试用输出详细日志ROI 可编辑生产模式python main.py --prod隐藏控制台禁用 ROI 编辑仅显示告警面板服务模式python main.py --service后台运行日志写入logs/service.log支持 systemd 管理生产模式下UI 会自动加载config/roi_default.json预设 3 个危险区域坐标并禁用鼠标右键菜单。icon.ico图标已嵌入资源打包成 exe 后无需额外文件。3.4 避坑部署中 4 个血泪经验总结现象 1Ubuntu 20.04 下cv2.imshow()报错libGL error: failed to load driver: swrast原因工控机无独显系统默认用 Mesa 软渲染但 OpenCV 4.5 需要libgl1-mesa-glx和libglib2.0-0两个包。解决sudo apt update sudo apt install -y libgl1-mesa-glx libglib2.0-0 # 若仍报错强制降级 opencv-python-headless pip install opencv-python-headless4.5.5.64现象 2Windows 10 上main.exe启动黑屏任务管理器显示 Python 进程 CPU 100%原因PySide6 与某些主板集成显卡驱动冲突QApplication初始化卡死。解决在main.py开头插入import os os.environ[QT_QPA_PLATFORM] windows # 强制使用 Windows 原生平台插件现象 3RTSP 流接入后画面卡顿但ffplay播放流畅原因cv2.VideoCapture默认用CAP_FFMPEG后端对 H.265 流支持差。解决修改five_type_det_service.py第 63 行# 原代码 cap cv2.VideoCapture(source) # 改为显式指定后端 cap cv2.VideoCapture(source, cv2.CAP_GSTREAMER) # Ubuntu # 或 cap cv2.VideoCapture(source, cv2.CAP_MSMF) # Windows现象 4告警 CSV 中roi_id全为 -1原因ROI 多边形顶点坐标未按顺时针/逆时针闭合cv2.pointPolygonTest返回 -1表示点在多边形外。解决用utils/myutil.py的validate_polygon函数校验from utils.myutil import validate_polygon poly [(100, 200), (300, 200), (300, 400), (100, 400)] # 顺时针矩形 print(validate_polygon(poly)) # True # 若返回 False用 cv2.convexHull 重生成凸包4. 电子围栏核心逻辑如何用多边形 ROI 实现“闯入即告警”而非简单矩形框4.1 ROI 定义roi_default.json的坐标系与单位config/roi_default.json内容示例{ areas: [ { id: 1, name: 机械臂作业区, points: [[120, 85], [420, 85], [420, 320], [120, 320]], alert_class: [person], min_confidence: 0.55, trigger_delay: 3 }, { id: 2, name: 高空吊装区, points: [[510, 45], [780, 45], [780, 210], [620, 210], [510, 120]], alert_class: [person, hardhat], min_confidence: 0.65, trigger_delay: 5 } ] }坐标系规则原点(0,0)在图像左上角points是图像像素坐标非归一化值多边形必须首尾闭合JSON 中无需重复首点代码会自动补trigger_delay表示目标连续N帧出现在 ROI 内才触发告警防瞬时误检。4.2 闯入判定my_func.py中的is_inside_roi算法细节核心函数is_inside_roi(point, polygon)使用 OpenCV 的pointPolygonTest# my_func.py 第 112 行 def is_inside_roi(point, polygon): point: (x, y) tuple polygon: list of (x, y) tuples, e.g. [(100,200), (300,200), ...] return: True if point inside polygon, False otherwise pts np.array(polygon, dtypenp.int32) # cv2.pointPolygonTest 返回0内, 0边上, 0外 result cv2.pointPolygonTest(pts, point, False) return result 0 # 严格内部或边上都算闯入为什么不用shapelyshapely精度高但依赖 GEOS 库在工控机上安装失败率高尤其 ARM 架构。cv2.pointPolygonTest是 OpenCV C 原生实现零依赖10 万次调用耗时 15ms。4.3 多目标关联如何区分“两人同时闯入” vs “一人来回走动”靠model.track()的track_id实现# five_type_det_service.py 第 156 行 for box in results[0].boxes: x1, y1, x2, y2 box.xyxy[0].tolist() cls_id int(box.cls[0]) conf float(box.conf[0]) track_id int(box.id[0]) if box.id is not None else -1 center_x (x1 x2) / 2 center_y (y1 y2) / 2 for roi in self.roi_list: if is_inside_roi((center_x, center_y), roi[points]): # 记录 track_id 在该 ROI 的帧数 self.roi_tracker[roi[id]][track_id] 1 if self.roi_tracker[roi[id]][track_id] roi[trigger_delay]: self.trigger_alert(roi[id], track_id, cls_id, conf)self.roi_tracker是字典{roi_id: {track_id: count}}每个 ROI 独立计数彻底解决跨区域干扰。4.4 告警分级alert_callback如何联动物理设备main.py的trigger_alert方法预留硬件接口def trigger_alert(self, roi_id, track_id, class_id, conf): # 1. GUI 弹窗 声音提示 self.show_alert_dialog(f危险区域 {roi_id} 闯入ID:{track_id}) # 2. 写入 CSV已实现 self.save_to_csv(...) # 3. 【预留】GPIO 控制需自行接线 if hasattr(self, gpio_controller): self.gpio_controller.set_pin(12, True) # 拉高 12 号引脚 QTimer.singleShot(2000, lambda: self.gpio_controller.set_pin(12, False)) # 4. 【预留】HTTP POST 到 MES 系统 # requests.post(http://mes-server/api/alert, json{...})提示GPIO 控制需安装RPi.GPIO树莓派或pyfirmataArduino本包未内置因硬件差异太大。但set_pin接口已定义你只需继承GPIOController类并实现set_pin方法即可。5. 数据集实战从labelme标注到 YOLOv8 训练绕过 90% 的格式坑5.1 标注规范为什么labelme导出 JSON 后必须用utils/convert_labelme_to_yolo.pylabelme默认导出的 JSON 包含大量冗余字段如imageData,flags且多边形坐标是[x,y,x,y,...]扁平数组YOLO 要求每行.txt文件格式为class_id x_center y_center width height其中x_center,y_center,width,height均为归一化值除以图像宽高。转换脚本utils/convert_labelme_to_yolo.py关键逻辑# utils/convert_labelme_to_yolo.py 第 78 行 def convert_polygon_to_bbox(polygon, img_w, img_h): 将 labelme 多边形转为 YOLO bbox最小外接矩形 pts np.array(polygon, dtypenp.float32) x_min, y_min pts.min(axis0) x_max, y_max pts.max(axis0) # 归一化 x_center (x_min x_max) / 2 / img_w y_center (y_min y_max) / 2 / img_h width (x_max - x_min) / img_w height (y_max - y_min) / img_h return x_center, y_center, width, height注意电子围栏不关心精确分割最小外接矩形足够——它只判断“人是否在区域内”不是做姿态估计。5.2 数据增强augmentations.py里哪些增强必须关掉工厂场景三大禁忌增强增强类型问题解决方案RandomPerspective产线摄像头俯视固定透视畸变会伪造不存在的区域在train_mode.py中注释掉perspective0.0HSV色彩扰动安全服颜色是告警依据黄/橙/银色偏导致漏检hgain0.0, sgain0.0, vgain0.0Mosaic四图拼接破坏空间连续性危险区域边界模糊mosaic0.0实际启用的增强仅三项translate0.1±10% 平移模拟摄像头微抖scale0.5缩放 0.5~1.5 倍适应不同距离目标flipud0.0关闭上下翻转产线无倒挂目标5.3data.yaml配置为什么nc: 5且names: [person, hardhat, safety_vest, tool, machine]这不是 COCO 的 80 类而是工厂定制五类person所有人体闯入判定主体hardhat安全帽未戴帽告警依据safety_vest反光背心未系带告警依据tool扳手/螺丝刀禁止携带进入区域machine机械臂/吊钩作为 ROI 参考物不告警data.yaml必须与train_mode.py中data参数路径一致且train/val/test路径为相对路径相对于data.yaml所在目录。5.4 训练监控如何看懂runs/train/yolov8n_factory/results.png这张图含四条曲线曲线含义健康值Box Loss边界框回归损失训练末期 0.05Cls Loss分类损失 0.12Dfl Loss分布焦点损失YOLOv8 新增 0.5mAP50-95多阈值平均精度 0.75 即合格若Box Loss末期仍 0.1大概率是anchor不匹配——此时需运行utils/autoanchor.py重新计算python utils/autoanchor.py -f datasets/data.yaml -n 9 -m 0.25-n 9指生成 9 个 anchor-m 0.25是长宽比容忍度工厂目标长宽比集中于 0.5~2.0。6. 进阶技巧用Detection_video.py做离线复盘分析把告警日志变成改进依据6.1 离线分析流程从alerts/目录反推模型弱点Detection_video.py不是实时检测而是对已存告警视频做二次分析目的有三验证误报人工确认alerts/20240512_142301_001.jpg是否真为闯入定位漏报用ffmpeg抽取告警前后 10 秒视频检查是否有人在 ROI 边缘徘徊未触发统计分布统计各 ROI 的告警频次、时段、目标类别指导产线整改。运行命令python Detection_video.py \ --video alerts/20240512_142301.mp4 \ # 告警时段原视频 --model model/best.pt \ --roi config/roi_default.json \ --output analysis/20240512_142301_report.html生成的 HTML 报告含时间轴热力图横轴时间纵轴 ROI ID颜色深浅目标停留时长误报/漏报标注图红框误报绿框漏报蓝框正确告警CSV 导出按钮含每帧检测结果。6.2 关键参数表Detection_video.py的 7 个可调旋钮参数默认值作用调整建议--conf0.5检测置信度阈值误报多 → 提高漏报多 → 降低--iou0.5NMS IOU 阈值目标密集 → 降低至 0.3--line_thickness2边框粗细工控机屏幕小 → 设为 3--show_roiTrue是否显示 ROI 区域复盘时建议关闭聚焦目标--save_framesFalse是否保存每帧检测图仅调试时开启占空间--skip_frames1每隔 N 帧处理一帧1080p 视频设为 2提速 2 倍--export_csvTrue是否导出 CSV必开用于 Excel 分析6.3 从日志到行动一份真实的analysis/20240512_142301_report.html发现我们在某厂复盘中发现ROI 1机械臂区告警中 63% 是“安全帽误检”把吊臂反光当帽子ROI 2吊装区82% 告警发生在 14:00-15:00对应交接班时段漏报集中点ROI 1 右下角 10×10 像素区域因摄像头支架遮挡形成盲区。行动项在datasets/train/labels/中给所有吊臂反光样本添加class_id4machine并增加hardhat类负样本纯反光图在交接班时段将 ROI 2 的trigger_delay从 5 降至 2调整摄像头角度消除盲区并用labelme重标该区域 37 张图。从那以后我每次部署新产线都强制走一遍Detection_video.py复盘流程——不是为了证明模型多准而是为了找到那个“下次一定改”的具体像素点。希望帮到你。本文还有配套的精品资源点击获取
返回列表