ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

翻越栏杆行为识别数据集与YOLO目标检测落地全流程

2026/10/1 13:43:15 拓冰建站 浏览量
翻越栏杆行为识别数据集与YOLO目标检测落地全流程 简介这份翻越栏杆行为识别数据集面向计算机视觉与深度学习方向的开发者、学生及安防场景算法研究者用于目标检测模型的训练与验证可支撑地铁、站台、围栏等场景下的异常行为识别任务。资源包共1539个文件包含512张jpg图像、512个txt标签、512个xml标签以及2个cache缓存文件和1个yaml类别配置文件压缩包约30.83MB同时提供YOLO与VOC两种标注格式图片与标签已按训练集、验证集、测试集划分完毕可直接投入YOLOv5至YOLOv10等YOLO系列算法也兼容Faster R-CNN、SSD等检测框架。目前已有907人学习下载适合作为课程设计、毕业设计或算法对比实验的现成数据基础。借助完整的图像、双格式标签与数据划分读者可省去标注与整理环节快速搭建训练流程、验证模型在跨越栏杆行为上的检测效果并在此基础上开展数据增强、类别平衡与精度调优等进阶实验。1. 翻越栏杆行为识别数据集从标注到目标检测落地的完整路径地铁站台、高速匝道、园区围墙这些场景里翻越栏杆的行为一旦发生轻则设备损坏重则人身伤亡。传统做法靠人工盯监控一个安保人员盯十几路画面漏检几乎是必然。翻越栏杆行为识别数据集配合目标检测模型是目前性价比最高的自动化方案——它不依赖昂贵的红外热成像或激光雷达普通 RGB 摄像头加一台边缘计算盒子就能跑起来。这个方向适合两类人一是做智慧安防、智慧交通的算法工程师需要快速验证翻越行为检测的可行性二是已经有一定 YOLO 使用经验、想切入行为识别细分场景的开发者。数据集的核心价值在于把「翻越」这个动作拆解成可标注的视觉目标——人体、栏杆、人体与栏杆的空间关系然后用目标检测框架去学习这些目标的特征分布。接下来我会从数据集构建、标注规范、模型训练、参数调优到避坑把整条链路讲透。2. 翻越栏杆行为识别数据集构建逻辑与标注规范2.1 为什么翻越行为要用目标检测而不是纯分类行为识别常见的技术路线有三条视频分类如 SlowFast、时序动作检测如 ActionFormer、以及基于目标检测的帧级行为判定。前两者精度上限高但对数据量和算力的要求也高一个中等规模的行为分类数据集动辄需要上千段视频片段标注成本极高。而翻越栏杆这个场景有一个天然优势行为发生时会伴随明确的视觉目标——人体处于栏杆上方或跨越栏杆的瞬间姿态栏杆本身也是固定参照物。我一般会把问题转化为在单帧图像中检测「人体」和「栏杆」两类目标再通过人体框与栏杆框的空间关系IoU、中心点相对位置、人体框底部与栏杆顶部的距离来判定是否发生翻越。这样做的好处是标注成本低——只需要画框不需要逐帧打时序标签推理速度快——YOLO 系列在边缘设备上轻松跑到 30 FPS 以上可解释性强——判定逻辑是白盒的方便调试和阈值调整。当然纯目标检测也有边界。如果摄像头角度导致栏杆被遮挡严重或者夜间光照极差检测框会抖动空间关系判定就会不稳定。这时候需要引入多帧投票机制或者补充红外可见光目标检测数据集做融合。但对于大多数白天场景的园区和站台单帧目标检测方案已经够用。2.2 数据采集场景覆盖比数量更重要翻越栏杆行为识别数据集的采集最忌讳的是只在一个摄像头、一个角度、一种光照下拍几千张。我见过一个团队用固定机位拍了 8000 张模型在测试集上 mAP 0.92换一个摄像头直接掉到 0.5。血泪经验是场景多样性比绝对数量重要得多。采集时至少覆盖以下维度维度建议覆盖说明摄像头角度正对、侧向 45 度、俯视 30 度俯视角度下人体框与栏杆框重叠严重难度最大光照条件白天顺光、白天逆光、黄昏、夜间补光逆光和夜间是翻车重灾区栏杆类型横杆、竖杆、玻璃护栏、铁艺栏杆不同纹理对检测器干扰不同人体姿态正在翻越、骑跨、已翻过、正常行走负样本要包含靠近栏杆但未翻越的情况遮挡程度无遮挡、部分遮挡、严重遮挡遮挡样本占比建议 15% 到 20%每个维度组合下采集 200 到 500 张即可总量控制在 3000 到 5000 张。如果预算允许用不同分辨率的摄像头各采一遍后续做多尺度训练。注意不要用视频抽帧的方式制造大量近似重复帧那样只会让模型过拟合到特定背景。2.3 标注规范人体框和栏杆框怎么画标注工具用 LabelImg、CVAT 或 X-AnyLabeling 都行格式统一成 YOLO 的 txt 格式。关键是标注规则要统一否则不同标注员画出来的框差异很大模型学到的就是噪声。人体框规则框住可见的人体部分包括头部、躯干、四肢。如果人被栏杆遮挡只框可见部分不要脑补被遮挡的区域。正在翻越时人体往往呈倾斜或倒挂姿态框要贴合实际像素范围不要强行拉成直立矩形。栏杆框规则框住栏杆的连续段不要框整排栏杆。比如一个人正在翻越某一段横杆就框住他身体附近 2 到 3 米范围内的栏杆段。这样做的原因是整排栏杆框太大与人体框的 IoU 计算会失真。如果栏杆是竖杆阵列框住包含 3 到 5 根竖杆的区域即可。类别命名建议用person和fence不要用person_climbing这种带行为语义的类别名。行为判定交给后处理逻辑检测器只负责定位。# 将 LabelImg 的 XML 标注转换为 YOLO txt 格式 import xml.etree.ElementTree as ET import os def convert_annotation(xml_path, output_dir, class_map): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): cls_name obj.find(name).text if cls_name not in class_map: continue cls_id class_map[cls_name] bbox obj.find(bndbox) x1 float(bbox.find(xmin).text) y1 float(bbox.find(ymin).text) x2 float(bbox.find(xmax).text) y2 float(bbox.find(ymax).text) # YOLO 格式class_id cx cy w h归一化到 0-1 cx (x1 x2) / 2.0 / w cy (y1 y2) / 2.0 / h bw (x2 - x1) / w bh (y2 - y1) / h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) out_path os.path.join(output_dir, os.path.basename(xml_path).replace(.xml, .txt)) with open(out_path, w) as f: f.write(\n.join(lines)) # class_map {person: 0, fence: 1}这段脚本的核心逻辑是坐标归一化。YOLO 不直接使用像素坐标而是用相对于图像宽高的比例值。cx和cy是框中心点坐标除以图像宽高bw和bh是框宽高除以图像宽高。参数class_map控制类别映射确保person对应 0、fence对应 1。转换后要抽查几个 txt 文件确认没有出现坐标大于 1 或小于 0 的异常值。2.4 数据集划分与增强策略划分比例按 8:1:1 走训练集、验证集、测试集。注意要按场景划分不能随机打散——同一个摄像头下的相似帧如果同时出现在训练集和测试集测试精度会虚高。正确做法是留出 1 到 2 个完全没参与训练的摄像头场景作为测试集。数据增强用 Albumentations 库重点做以下几类随机裁剪和缩放模拟不同距离下的目标大小变化亮度、对比度、色调抖动模拟不同光照随机遮挡模拟栏杆遮挡人体的场景水平翻转但注意翻转后栏杆的左右关系会变如果场景有方向性语义要慎用不要用旋转增强因为摄像头安装角度是固定的旋转会引入不存在的视角。Mosaic 增强可以用但翻越行为样本本身就不多Mosaic 四合一后单张图里目标太小建议只在训练后期关闭 Mosaic。3. 用 YOLOv8 训练翻越栏杆检测模型配置与调参3.1 环境搭建与数据配置文件YOLOv8 是目前落地最稳的选择Ultralytics 的工程化做得好导出 ONNX 和 TensorRT 都方便。如果你在用 YOLOv11 或更新的版本流程基本一致改一下模型加载的权重名即可。三维目标检测和多模态目标检测在这个场景里属于过度设计单目 RGB 加二维检测足够。# 创建环境并安装依赖 conda create -n fence_det python3.10 -y conda activate fence_det pip install ultralytics albumentations opencv-python onnx onnxruntime数据配置文件fence_data.yaml这样写path: /data/fence_dataset train: images/train val: images/val test: images/test names: 0: person 1: fencepath是数据集根目录train、val、test是相对路径。names里的类别顺序必须和标注时的class_map一致否则模型学出来的类别会错位。这个文件放在项目根目录训练时通过参数传入。3.2 训练命令与关键参数含义yolo detect train \ modelyolov8s.pt \ datafence_data.yaml \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience30 \ device0 \ projectfence_runs \ nameexp01逐项说明modelyolov8s.pt选 small 版本在精度和速度之间平衡边缘设备上 TensorRT 推理能到 50 FPS 以上。epochs150是上限配合patience30做早停——30 轮验证集 mAP 不提升就停。imgsz640是输入分辨率如果摄像头原始分辨率是 1080P建议改成 960 或 1280小目标召回会明显提升。batch16在 8GB 显存下比较稳显存不够就降到 8 并开启ampTrue混合精度。lr00.01是初始学习率lrf0.01是最终学习率系数余弦退火到初始值的 1%。训练过程中重点看三个指标metrics/mAP50、metrics/mAP50-95和val/box_loss。mAP50 到 0.85 以上、mAP50-95 到 0.6 以上基本可用。如果 box_loss 震荡不降检查标注框是否有大量越界或宽高为 0 的异常样本。3.3 翻越行为判定逻辑从检测框到报警信号模型输出的是人体框和栏杆框要判定是否翻越需要写后处理逻辑。核心思路是计算人体框与栏杆框的空间关系。import numpy as np def is_climbing(person_box, fence_box, img_h, overlap_thresh0.05): person_box: [x1, y1, x2, y2] 人体框像素坐标 fence_box: [x1, y1, x2, y2] 栏杆框像素坐标 img_h: 图像高度 px1, py1, px2, py2 person_box fx1, fy1, fx2, fy2 fence_box # 计算交并比 ix1 max(px1, fx1) iy1 max(py1, fy1) ix2 min(px2, fx2) iy2 min(py2, fy2) inter max(0, ix2 - ix1) * max(0, iy2 - iy1) person_area (px2 - px1) * (py2 - py1) fence_area (fx2 - fx1) * (fy2 - fy1) union person_area fence_area - inter iou inter / union if union 0 else 0 # 人体框底部是否低于栏杆框顶部说明人体在栏杆上方或跨越 person_bottom py2 fence_top fy1 vertical_overlap person_bottom fence_top # 人体框中心是否在栏杆框水平范围内 person_cx (px1 px2) / 2 horizontal_in fx1 person_cx fx2 if iou overlap_thresh and vertical_overlap and horizontal_in: return True return False这段逻辑的判定条件是人体框与栏杆框有足够重叠、人体框底部低于栏杆框顶部、人体中心在栏杆水平范围内。三个条件同时满足才触发报警。overlap_thresh0.05是经验值设太高会漏检骑跨姿态设太低会把靠近栏杆的正常行走误报。实际部署时建议用连续 5 帧中至少 3 帧触发才报警降低误报率。3.4 模型导出与边缘部署训练完成后导出 ONNX 或 TensorRT 引擎# 导出 ONNX yolo export modelfence_runs/exp01/weights/best.pt formatonnx opset12 simplifyTrue # 导出 TensorRT需要 NVIDIA GPU 环境 yolo export modelfence_runs/exp01/weights/best.pt formatengine halfTrue device0opset12兼容性最好simplifyTrue会做计算图简化。TensorRT 导出时halfTrue开启 FP16 推理速度提升约 1.5 到 2 倍精度损失通常在 1% 以内。部署到 Jetson 或工控机时用 DeepStream 或 Triton Inference Server 做推理服务配合 GStreamer 拉流单路 1080P 视频在 Jetson Xavier NX 上能跑到 25 FPS 以上。4. 翻越栏杆检测的避坑与排查清单4.1 坑一栏杆框标注过大导致 IoU 失真现象模型训练 loss 正常下降但后处理判定翻越时频繁误报正常行走的人也被判定为翻越。原因标注时把整排栏杆框成一个大框人体框与这个大框的 IoU 很容易超过阈值但实际人体离栏杆还有一段距离。解决重新标注栏杆框只框住人体附近 2 到 3 米范围。如果已经标注完不想重做可以在后处理里加一个约束——人体框中心点到栏杆框中心点的水平距离小于人体框宽度的 1.5 倍才判定。4.2 坑二逆光场景下人体框丢失现象白天顺光场景 mAP 0.9逆光场景 mAP 掉到 0.4人体几乎检测不到。原因逆光时人体变成剪影纹理信息丢失模型依赖的 RGB 特征失效。解决训练时加入大量逆光增强样本用 Albumentations 的RandomGamma和RandomBrightnessContrast模拟。如果逆光场景是刚需考虑补充红外可见光目标检测数据集做双光融合或者换用对光照更鲁棒的 backbone。4.3 坑三小目标栏杆竖杆被漏检现象横杆检测正常但细竖杆的栏杆框经常漏检导致翻越判定失效。原因竖杆在图像中宽度可能只有几个像素YOLO 下采样 32 倍后特征几乎消失。解决把imgsz从 640 提到 960 或 1280小目标召回会明显改善。或者在数据增强里加RandomScale让模型见过更小尺度的目标。如果还不行换 YOLOv8 的 P2 变体增加一个高分辨率检测头。4.4 坑四模型微调崩了——学习率设太大现象加载预训练权重后微调前几个 epoch loss 直接飙到 nan。原因lr0设成了 0.1 或更大预训练权重的特征分布被瞬间破坏。解决微调时lr0降到 0.001 到 0.005warmup_epochs设 3 到 5让学习率从极小值慢慢升上来。如果已经崩了重新加载预训练权重把学习率减半再试。4.5 坑五测试集精度虚高——数据泄漏现象测试集 mAP 0.95上线后实际场景 mAP 不到 0.6。原因训练集和测试集来自同一个视频的相邻帧模型记住了背景而不是学到了目标特征。解决按摄像头或时间段划分数据集确保测试集场景在训练集中完全没出现过。如果只有一段视频按时间前 70% 做训练、后 30% 做测试不要随机抽帧。5. 翻越栏杆检测的进阶技巧多帧投票与阈值自适应单帧判定最大的问题是抖动。摄像头轻微晃动、光照突变、行人快速走过都可能让某一帧的检测框异常导致误报。我在实际项目里用多帧投票把误报率从每天 20 多次降到了 2 次以内。具体做法是维护一个长度为 10 的滑动窗口记录每帧的翻越判定结果。当窗口内为 True 的帧数达到 6 帧以上才触发报警。这个阈值可以根据场景调整地铁站台人流密集调到 7 帧园区围墙人少5 帧就够。窗口长度也不宜太长10 帧在 25 FPS 下对应 0.4 秒再长会延迟报警。另一个技巧是阈值自适应。overlap_thresh固定值在不同摄像头下表现差异很大。我一般会在部署初期用一批正常行走的负样本跑一遍统计人体框与栏杆框 IoU 的分布取 95 分位值作为初始阈值。然后每周用误报样本做一次微调让阈值随场景变化缓慢漂移。from collections import deque class ClimbDetector: def __init__(self, window_size10, trigger_ratio0.6): self.window deque(maxlenwindow_size) self.trigger_ratio trigger_ratio def update(self, frame_result): self.window.append(frame_result) if len(self.window) self.window.maxlen: return False true_count sum(self.window) return true_count / len(self.window) self.trigger_ratio # 使用示例 detector ClimbDetector(window_size10, trigger_ratio0.6) # 每帧调用 detector.update(is_climbing_result)window_size10控制平滑程度trigger_ratio0.6控制灵敏度。这两个参数需要根据实际场景的误报和漏报容忍度来调。如果漏报代价高把trigger_ratio降到 0.4如果误报代价高提到 0.8。最后说一个我踩过的坑不要用检测框的绝对像素坐标做判定因为不同分辨率的摄像头像素尺度不同。所有空间关系计算都要归一化到图像宽高或者用相对比例。这个习惯能让你换摄像头时少改很多代码。希望帮到你。本文还有配套的精品资源点击获取