ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

自制YOLO数据集:让监控同时识别吸烟与跌倒行为

自制YOLO数据集:让监控同时识别吸烟与跌倒行为 简介面向目标检测与安防场景的开发者与研究者这份吸烟、跌倒行为YOLO格式数据集可直接用于训练和评估YOLOv5、YOLOv7、YOLOv8等主流检测模型解决监控视频中吸烟与跌倒行为的自动识别问题适用于智慧安防、园区管理、养老监护等应用场景也适合作为目标检测课程实践与算法对比的基准数据。资源包内共2000个文件其中1999个为txt格式标签文件保存每张图像中目标的类别与边界框归一化坐标另包含1个smoke_fall.yaml配置文件用于定义类别名称并指定训练集、验证集路径压缩包大小约98.47MB目录按trainset与testset划分images与labels一一对应结构清晰基本做到解压即可接入训练脚本。目前已有413人学习下载适合目标检测入门学习者快速跑通YOLO训练流程也便于算法工程师进行数据增强、注意力机制调整和模型鲁棒性测试可直接用于吸烟、跌倒检测模型的训练与验证加快项目落地。 去年接了一个智慧养老项目的预研客户需求清单里有两条看着特别简单识别老人跌倒、识别室内吸烟。单项拆开看网上能找到不少现成的开源模型可真到落地环节我傻眼了——公开的跌倒数据集大多标注的是骨架关键点不是目标框吸烟数据集大部分又是做烟雾识别的摄像头对着天花板烟感探头根本不管人手上拿没拿烟。最要命的是几乎没有现成数据集把吸烟和跌倒放在同一套标注体系里而真实监控场景恰恰需要在同一路画面里同时处理这两类行为。最后我决定自己攒一套YOLO格式的行为目标检测数据集。这篇文章把从设计到落地的完整过程记录下来包括类别怎么定、标注怎么标、训练踩了什么坑希望能帮到正在做安防监控、智慧养老、厂区安全生产这类项目的朋友。1. 把吸烟和跌倒放进同一份数据集不是偷懒而是工程需要1.1 同一路摄像头下的两类风险场景看项目需求不能只看单个算法指标要看整套系统的部署形态。在养老机构或者工厂休息区同一个监控点往往要同时承担多种安全判断。比如养老机构的活动室老人在沙发上看电视、起身时晃了一下或者有人违规抽烟镜头覆盖的是同一片区域。再比如加油站旁边的便利店、化工厂的休息区吸烟是消防隐患滑倒跌倒又是安全事故两类风险都真实存在。如果在系统里部署两个模型分别做吸烟检测和跌倒检测你就得管理两套置信度阈值、两套后处理逻辑。画面里一个目标被另一个目标遮挡时两个模型的框还会互相打架处理起来非常别扭。更实际的做法是做一个多类检测模型把smoking和fall作为两个输出类别。模型学到的不是这个物体像某个固定形状而是当前画面中人物的状态是否属于这两种风险行为类别关系让模型自己去学反而比人工叠加规则更稳定。1.2 公开数据集的对接困境我在调研阶段把主流公开数据集翻了一遍。跌倒类数据集以姿态估计为主标注的是关节点坐标要转成检测框得自己写转换脚本而且很多转换结果质量很差吸烟类数据集大量来自烟雾检测场景数据分布和监控画面差异巨大。更头疼的是公开数据集的场景分布极其单一有的所有图都在同一个会议室拍的在一个地方收敛得很好换个走廊、换个光线条件泛化性能立刻掉下来。所以我的判断是与其东拼西凑洗数据不如花时间搭一套标注规则明确、场景覆盖面够用、格式统一的YOLO数据集。数据集是项目的核心资产这份投入省不掉。我最后把数据集规模定在约12000张图片、总共3万多个标注框吸烟类占六成、跌倒类占四成用YOLOv8在训练集上跑出了预期效果。这个过程本身也验证了一个结论做垂直场景的行为检测自建数据集的ROI远高于盲目找公开数据。2. 类别设计与标注规范框的位置决定模型学到什么2.1 类别粒度别把拆细当成精确第一次设计类别时我走过一段弯路。当时我把跌倒拆成三种姿态侧卧、仰卧、趴卧把吸烟拆成持烟和吸烟动作两个阶段。看起来分类很专业实际干了两天就发现这是给自己挖坑。每个细分类别都要凑足样本量而现实场景里这些姿态的分布极不均匀仰卧容易拍到趴卧很难遇到。拆细之后模型大概率只学到多数类那几个姿势少数类几乎不响应。最后我回归到两个主类别smoking和fall外加一个辅助类别person。person类不参与最终业务判断但训练时能帮助模型在预训练特征基础上学会定位人物对两个行为类的召回都有帮助。辅助类在YOLO这类检测器里不会增加太多推理成本因为推理时可以按类名过滤输出但训练阶段它能让模型学到更有分辨力的特征。这个取舍建议所有做行为检测数据集的人参考类别粒度一定要结合样本可得性和业务需求来定不是越细越好。2.2 框人体的外接框别框烟头这是这份数据集最重要的一个设计决定。我见过很多新手做吸烟检测第一反应是标烟头因为烟的视觉特征最明显。但在1080P监控画面里烟头通常只占十几个像素标出来训练模型学到的是极小目标特征噪点极大实际部署时漏检率高到没法接受。正确做法是框整个人因为手持烟是一个整体动作语义模型真正需要学习的是人物手部动作与面部区域的组合特征而不是去找一个发光小点。跌倒检测同理框整个人在跌倒状态下的外接矩形而不是去框某个部位。这个决定背后是一个很朴素的逻辑检测模型适合做目标在哪里这件事而行为是什么应该由框内上下文来决定。把整人框进去模型就能同时看到人的姿态、手部动作、周围环境特征信息量比只框一个烟头大得多。数据集设计本质上是在给模型限定该看哪里框得越合理模型学得越轻松。2.3 标注规则的边界处理办法标注规则如果不提前定清楚几个人标出来的框风格会千差万别。我实际执行的规则如下吸烟人物手持香烟或嘴部有香烟露出取人物整体外接框框体不需要精细卡到手指位置跌倒人物倒地、半卧或斜靠地面框包含全身被家具遮挡的部分按可见范围计算画面中存在模糊目标无法判断是否持烟时直接跳过不标就是最好的标注多人画面中如果能看到两个目标相互遮挡面积超过50%只标注可见度高的一方这些规则每一行都是踩过坑之后写出来的。比如不标模糊目标这条刚开始觉得标注得越多越好后来发现模糊标注进入训练集模型学到的全是噪声负向影响比少标一个框更严重。规则明确之后标注人员的效率也明显提高了因为不需要每次遇到边界情况都犹豫半天。3. 数据生产全流程记录三周做出可复用的数据集3.1 自采和公开视频混编数据来源我分了两路。第一路是组织同事朋友在办公室、会议室、走廊、楼梯间等场景模拟拍摄覆盖不同机位高度、不同光照条件这部分优势是版权干净、场景可控、能按需补齐。第二路是从可商用授权的视频素材平台和部分允许自由使用的公开视频中抽取关键片段主要用来增加场景多样性和人物多样性。两种来源比例大概在6:4左右自采为主、公开为辅。这里要特别提醒一个版权问题商用项目里素材版权纠纷的麻烦程度远超算法性能问题。我的项目用到的所有素材要么自采、要么有可商用授权凭证这一步千万不要省也别抱着只有我自己用不会被发现的侥幸心理。做数据集的长期价值在于可持续迭代版权问题不解决后面每次扩充数据都提心吊胆。3.2 抽帧与初筛策略拿到视频素材后不是无脑每秒抽一帧。我采用的策略是每秒抽1帧作为候选帧再用程序把相邻帧做感知哈希相似度计算相似度高的帧直接去重。行为检测数据集里相邻帧高度相似如果不做去重训练时会因为大量重复样本导致模型过拟合测试集里也会混入泄漏样本评估指标虚高。初筛之后再做人工清洗把运动模糊、严重遮挡、角度怪异的帧剔除。这一步每天能淘汰掉大约百分之二十的候选帧虽然费时间但能保证数据质量下限。模型泛化能力的基础是数据质量而不是数据数量一万张干净图的效果通常好于两万张脏数据加噪声数据。这个观点可能和不少人的直觉相反但我在这个项目里体验得非常明显。3.3 标注工具与双人交叉质检标注工具我用过好几种。单人标注时用X-AnyLabeling它支持保存时直接导出YOLO格式操作界面也跟手团队协作时用CVAT支持多人登录同一项目、任务分配和标注冲突检测。如果团队只有一两个人工具选哪个差别不大关键是导出格式要统一避免后期写一堆转换脚本。实际标注过程中每个人的框选习惯一定会有差异有人喜欢框紧一点、有人喜欢留白多一点。为此我推行了双人交叉质检第一遍标注完成后安排另外一个人对已标注图像再过一遍重点检查框边界是否贴合、类别是否标错、模糊目标是否被误标。质量复核是数据生产里耗时最长的一步但也是决定模型性能上限的关键一步。整体统计下来标注和质检的时间大约占了整个数据生产周期的三分之二。3.4 YOLO格式导出与目录组织最终交付的目录结构如下dataset/ ├── train/ │ ├── images/ │ └── labels/ ├── val/ │ ├── images/ │ └── labels/ ├── test/ │ ├── images/ │ └── labels/ └── data.yamlYOLO格式的标签文件本质就是一行行类别编号加归一化坐标。比如一个画面里同时有吸烟和跌倒行为标签文件可能是0 0.5123 0.6874 0.3245 0.5211 1 0.4987 0.4123 0.2104 0.3018其中0对应fall1对应smoking后面的四个数字分别是中心点x、中心点y、宽度w、高度h全部归一化到0到1之间。data.yaml里配置好类别名称、数据集路径YOLOv8训练时直接指定这个配置文件就能开跑。训练集、验证集、测试集按8:1:1划分确保同一段视频的帧不会同时落入训练集和测试集避免数据泄漏导致评估结果失真。4. 训练实测收敛过程与调优记录4.1 基线配置从YOLOv8s起步跑通第一版训练我选的是YOLOv8s起步输入分辨率640×640batch size 16初始学习率0.01训练200轮加载COCO预训练权重。选YOLOv8s的原因很朴素这个项目最终要部署在边缘设备上比如瑞芯微RK3588这类盒子模型体积和推理速度必须控制住s型号在精度和速度之间最平衡。第一次跑完看结果smoking类的mAP到了0.82fall类只有0.64差距一眼就能看出来。这两类在模型结构上没有任何区别问题几乎肯定出在样本量和样本多样性上。跌倒动作发生的时间窗口通常比一次吸烟动作短得多采集难度也更大样本数量天然就少。这个基线结果不只是给了我一个数字更重要的是告诉我接下来应该往哪个方向补数据。4.2 类别不均衡与数据增强的实战处理针对fall类样本量不足我做了三件事。第一对跌倒类做离线复制增强把跌倒帧复制几份并做随机旋转、平移、缩放补充数量让模型在训练时能更充分看到这个类别的变化第二在线增强里提高Mosaic和MixUp的生效比例让模型看到更多遮挡和重叠场景第三补采阶段专门安排人模拟不同跌倒姿态包括侧倒、后倒、慢速滑倒、扶墙滑坐把姿势多样性拉起来。增强策略要分场景有取舍。Mosaic增强对提升小目标检测有帮助但对行为检测来说过度使用会让行为上下文被切碎反而降低识别效果。所以我Mosaic的启用率只设在0.5左右没有拉满。调完这一轮之后fall类的mAP提升到了0.78以上和smoking类的差距明显缩小。这里的关键是不要把所有希望寄托在增强参数上真实数据的补充永远是第一位的增强只是缓解手段。4.3 推理阶段的两个典型问题训练收敛后真正部署到真实画面里还是遇到两个棘手的坑。第一个是烟头小目标漏检部分场景人物低头时手部被身体挡住模型直接丢框。第二个是跌倒与蹲下捡东西动作的混淆特别是从侧面机位看蹲姿和半跪姿在单帧画面上跟跌倒姿态非常接近。这两个问题都不是单纯加大训练轮数能解决的。我的处理思路是调到后处理阶段连续3帧都检测到跌倒且对应同一目标ID才触发报警吸烟检测也要求连续几帧出现同一个吸烟目标才上报。用时间序列信息来压制单帧误判效果立竿见影。单帧检测模型本身永远会偶发误检这是2D目标检测的物理边界后处理逻辑要主动拥抱这个边界而不是假装它不存在。5. 评估指标之外真实场景里那些没法用mAP衡量的东西5.1 两类行为对误报漏报的容忍度完全不同同样是目标检测吸烟和跌倒两个类目的业务诉求其实是相反的。跌倒检测的漏报代价极高老人摔倒了没被检测到可能直接导致生命危险所以这类目标应该牺牲部分精确率换取更高召回率宁可误报让值班人员多看一眼也不能漏报。吸烟检测更在意误报率频繁误报会让值班人员失去对系统的信任真正发生违规行为时反而没人盯着屏幕确认。在部署阶段我把跌倒类的置信度阈值调到0.25吸烟类阈值调到0.4以上再配合帧间确认逻辑两类的实用性都有明显提升。这个经验纯粹靠看PR曲线和F1值是看不出来的必须替业务方想清楚一个报警进来之后他们会有多重视这个报警的价值到底是提醒注意还是必须立刻处置不同定位对应不同阈值和上报策略。5.2 边界case复盘数据集的持续进化真实场景里会出现很多训练数据里没见过的case我列几个典型的给正准备做类似数据集的朋友一个参考。老人躺着休息时盖着被子整体姿态接近侧卧模型容易误判为跌倒电子烟的烟杆比真烟短很多低分辨率画面里特征不明显漏检率明显更高逆光环境下人物手部区域过曝吸烟检测的有效特征几乎消失多人摔倒时目标互相重叠跟踪ID发生跳变帧间逻辑就失效了。每遇到一个case我的做法是把它对应成增量数据补进去然后微调模型再回归测试。数据集不是做完一次就结束的它是一个需要持续维护的资产。这次做下来最大的体会就是自建数据集的最大优势不在于省钱而在于当业务方反馈这个场景没检测出来的时候你能立刻定位问题是缺哪种数据、该怎么补整个迭代链路完全握在自己手里。5.3 最后一公里从YOLO权重到可部署方案模型训练完不等于项目交付。实际部署时我把YOLOv8的权重用ONNX导出在RK3588开发板上一路走到RKNN量化部署推理帧率能做到25FPS以上满足实时监控需求。也可以用同样的ONNX文件跑OpenVINO格式部署在x86的NVR设备上。如果下游需要做C/Qt客户端直接加载ONNX模型用onnxruntime推理即可不需要在客户端环境里安装深度学习训练框架。做这个项目最大的感触是目标检测系统的工程落地难度并不在模型结构而在于数据标签质量、标注规范、阈值策略、后处理逻辑这四个环节的配合。数据集的标签质量决定模型能力的上限标注规范决定数据集能不能持续扩展阈值策略决定系统在业务里好不好用后处理逻辑决定最终报警靠不靠谱。把这四件事理顺了YOLO格式的数据集才能从一堆txt文件变成真正可交付的行为检测能力。本文还有配套的精品资源点击获取
返回列表