ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

多场景抽烟行为检测数据集构建与YOLOv8训练全流程

多场景抽烟行为检测数据集构建与YOLOv8训练全流程 简介本资源是一个面向计算机视觉与行为识别方向研究者及深度学习开发者的专用数据集聚焦于多场景下抽烟行为的检测与分析适用于智能监控、公共卫生行为建模、AI健康干预等实际应用。数据集共2000张高质量JPG图像配套5318个XML标注文件含边界框坐标与类别标签完整覆盖室内、室外、侧拍、背影、遮挡等多种复杂吸烟场景标注信息精准支持YOLO、Faster R-CNN等主流目标检测模型训练另有少量.ds_store及_images/_annotations目录结构文件便于直接接入PyTorch或TensorFlow数据加载流程。压缩包为RAR格式总大小984.58MB结构清晰、开箱即用。目前已有417人学习下载读者可直接获得带完整空间定位的吸烟行为样本库、标准化标注体系及跨场景泛化训练基础显著降低数据采集与标注成本加速模型迭代与落地验证。 做行为检测的工程师大概率都遇到过这种尴尬模型在测试集上指标漂亮得很一上真实场景就漏检、误检不断。尤其是抽烟行为检测目标小、姿态多变、光照环境复杂很多时候问题的根源不在网络结构而在数据集本身——场景单一、样本量不够、标注口径不统一再强的模型也白搭。我最近整理了一套多场景抽烟行为数据集覆盖室内外、昼夜、远近景、遮挡等常见情况并基于它完整跑通了YOLOv8训练流程。这篇文章就把数据采集、标注规范、训练调参、问题排查的全过程记录下来包括我实际踩过的坑和解决方案给正在做行为识别、目标检测项目的朋友一个可参考的完整样例。1. 数据集核心问题与设计定位1.1 为什么模型总在真实场景“失灵”很多初学者容易陷入一个误区以为模型效果不好就是网络结构不够先进于是今天换个Backbone明天加个注意力机制结果指标没涨多少部署还变麻烦了。我做了几个项目后有一个很深的体会绝大部分工程问题出在训练数据和真实场景之间的分布差异上。具体到抽烟行为检测这个差异尤其明显。监控场景下的抽烟行为有几个天然难点烟支本身非常小一根烟在1080P画面里可能只有十几个像素手部动作复杂有夹烟、递烟、弹烟灰、拿烟靠近嘴边多种状态光照环境变化剧烈白天强光、逆光、黄昏、夜间灯光下烟支和烟雾的视觉特征完全不同。如果你的数据集里全是白天室内固定角度的样本模型自然学不到夜间的泛化能力。所以我在设计这套数据集时第一目标不是“堆数量”而是“铺场景”。数量再多如果场景单一模型学到的本质上只是一个场景的纹理特征换个环境就失效。数据的多样性本质上决定了模型泛化能力的上限。1.2 场景单一导致的两个连锁问题场景单一带来的问题在实际项目中通常是连锁反应的。第一个问题是过拟合模型在训练集上收敛得很好loss很低但验证集一测就露馅mAP掉十几个点。第二个问题是误检这个比漏检更头疼。在厂区禁烟场景里漏检顶多是没发现违规行为误检则会把巡检人员逼疯——比如把白色水管、反光条、烟囱排出的白色蒸汽当成烟支一天推送几百条假报警。这两个问题本质上是同一件事模型没有见过足够多样的负样本和难样本决策边界画得太“陡”。所以我在采集数据时特意加入了很多“疑似烟”但实际不是烟的场景比如卷起来的白纸、白色笔、棒棒糖、手指间夹着的白色物体这些都在标注时单独归为背景类让模型学会区分真正烟支和形状相似物。1.3 数据集规划的三条主线整个数据集的设计我按照三条主线来走。第一条是场景覆盖线按照空间、时间、视角、距离四个维度拆解室内场景包括办公室、会议室、休息室、卫生间室外场景包括园区道路、停车场、工地角落、厂区门口时间维度覆盖白天、黄昏、夜间视角上包括俯视、平视、侧视距离上区分近景3米内、中景3到10米、远景10米以上。第二条是行为状态线抽烟行为不是静止的我把它拆成几个状态点烟手和烟靠近面部、持烟烟夹在手中自然下垂或放在桌上、吸烟烟靠近嘴唇、弹灰、掐灭。每个状态都单独采集和标注这样模型学到的不是单一姿态而是整个行为过程的时空特征。第三条是目标属性线包括单目标单人抽烟、多目标多人同时抽烟、遮挡目标手被身体挡住、人脸侧转、被柱子或植物挡住一部分、小目标远距离高处的监控画面。这三条线交叉组合最终形成了数据集的完整矩阵。2. 多场景数据采集方案设计2.1 场景划分与对应采集策略这里说的“多场景”不是随便找几个地方录几段视频而是有意识地按光照、背景复杂度、目标尺度去划分采集点位。我实际采集中把场景分成了五个大类。第一类是室内办公环境特点是光照稳定、背景相对简单常见元素有白色墙壁、办公桌、电脑屏幕、文件夹。第二类是工业厂区环境背景复杂有管道、设备、反光金属面、警示条纹这些对检测干扰非常大。第三类是园区户外环境包括道路、绿化带、围墙、停车场光照变化剧烈逆光时人脸和手部都是暗的。第四类是夜间低照度环境依赖路灯或室内灯光画面噪点多烟头红点反而是最明显的特征。第五类是移动视角环境用手机或便携设备模拟巡逻人员视角画面有抖动和运动模糊。每个场景类型我至少保证采集了500到1000个有效样本夜间场景单独补充不达标样本1000张以上。采集方式分两种一种是在实际管理区域通过已有监控系统采集历史录像从中抽帧这种方式胜在场景真实、姿态自然缺点是存在隐私合规问题使用前必须经过脱敏审批另一种是在模拟环境中安排人员演示可控性强可以精确控制角度、距离、光照缺点是姿态容易僵化。我建议两种方式结合起来用以第一种为主第二种补充极端情况和罕见姿态。2.2 采集设备与参数选型设备选型直接影响数据集的质量上限。很多公开数据集用手机拍摄的分辨率很高但真实监控场景大多是1080P甚至更低的网络摄像头这就导致训练集和部署场景不匹配。我在采集时专门用了几类设备做区分。近景数据用手机拍摄主要模拟执法记录仪、安全员随身摄像头视角分辨率1080P或4K帧率30FPS。中景和远景数据用网络监控摄像头拍摄分辨率1080P帧率25FPS码率控制在4Mbps左右这更贴近实际部署时的视频流质量。如果条件允许我强烈建议至少配置一台支持光学变焦的球机用来采集远景和长焦视角的数据烟支在长焦画面里会大很多这对提高小目标检测能力非常有价值。有一个容易被忽略的参数是白平衡和曝光模式。大多数网络摄像头默认是自动白平衡、自动曝光但在夜间场景里自动曝光会导致画面过曝烟头的红色光点反而被“洗白”了。我采集夜间数据时手动把曝光时间锁定在1/50秒左右增益上限控制在50%这样烟头的特征能保留下来。2.3 数据量与质量平衡很多人在做数据集时有个心态数量越多越好。但实际上把无效样本塞进数据集只会让训练低效、标注资源浪费。我在整理这套数据集时最终保留了约12000张有效图片其中包含抽烟行为的样本约8000张无抽烟行为的背景样本约4000张。为什么保留这么多背景样本因为目标检测的训练过程负样本决定了误检率。如果一个数据集里全是正样本模型会倾向于“看到什么都觉得像烟”在复杂背景中产生大量假阳性。我把背景样本的比例控制在1比2也就是每两张正样本配一张负样本这个比例实测下来误检率控制得比较理想。关于图像去重这是很多人不重视但很重要的一步。从视频中抽帧得到的相邻帧往往高度相似如果直接把相似帧全部放进数据集会导致训练集和测试集之间存在隐形冗余指标虚高。我用感知哈希算法把相似度超过0.9的帧做了去重这一步把12000张原始图片压缩到了约8000张有效图片后来模型在真实场景的泛化能力确实比不去重时好不少。3. 标注规范与质检流程3.1 标注类别的合理划分标注类别的定义是整个数据集工程里最容易“差之毫厘谬以千里”的环节。很多开源行为数据集会标“smoking”这样一个类别名看起来简洁实际训练起来问题很多。我的做法是把标注类别拆成三个smoke烟支、smoking_action行为区域、cigarette_box烟盒。烟支用矩形框标注针对的就是烟支本身的小目标行为区域标注的是手部或嘴部附近完成吸烟动作的矩形范围这是给行为识别模型用的烟盒主要用来识别“即将抽烟”的状态在禁烟预警场景里非常有用能在真正点烟之前就发出提示。在标注时还要处理一类特殊目标指间夹烟但烟支被手部遮挡到只露出一小截的状态。这种目标烟支的可见像素很少如果单纯按烟支标边界框会非常小且不稳定。我在这个情况下优先标注手部与烟支的联合区域也就是标成smoking_action让模型把“手的姿态烟支局部特征”结合在一起来判断。实测下来这种标注策略显著提升了遮挡场景的召回率。3.2 标注工具选型与配置标注工具我试过LabelImg、Label Studio和X-AnyLabeling三者各有特点。LabelImg是老牌工具轻量干净适合快速做矩形框标注导出的VOC格式和YOLO格式都比较方便。Label Studio功能完整支持多人协作、任务分配、质量控制适合团队作战但对服务器资源的占用也大小项目用起来有点“杀鸡用牛刀”。X-AnyLabeling是我最近比较喜欢的一个工具它内置了多种预训练模型可以做自动标注辅助对视频抽帧序列还能做半自动追踪效率提升明显。对于抽烟行为这种目标比较小、尺度变化大的数据我个人的建议是单人标注用X-AnyLabeling或LabelImg多人协作用Label Studio。重点不在于工具本身而在于标注口径的统一。我在标注前会组织标注员拉通一份详细的标注规范里面包含不同场景的标注示例、边界情况处理规则、常见标注错误的截图对比这份规范对标注质量的提升远大于换一个更好的标注工具。3.3 质检和一致性控制标注完成后质检环节不能省。我采用了“双重检查抽样回归”的流程。第一轮是整体筛查把所有标注结果按图片可视化输出人工快速浏览重点看有没有漏标、错位、明显的边界框尺寸错误。第二轮是交叉复检让另一位标注员随机抽取20%的样本重新标注对比两边框的IoU交并比IoU低于0.7的记录为标注不一致需要回到原标注员那边修正。还有一个容易被忽略的是“边界框一致性”。烟支目标小不同标注员对“烟支范围”的理解可能不同有人标整根烟有人只标烟头还有人把手指也算进去了。这种不一致会导致模型学习到错误的回归目标。我的做法是在标注规范中明确规定烟支边界框包含烟身和烟头的完整可见部分不包含手指如果烟支被手指遮挡以可见部分为准完全不可见时不标烟支只标行为区域。质检阶段我还会做一次类别的频率统计目的不是简单看数量而是定位“短板场景”。比如统计夜间类别的样本量是否足够遮挡难例是否覆盖了各个角度如果某类样本不足就需要回到采集阶段针对性补采而不是硬着头皮直接开训。4. 基于YOLOv8的训练实操4.1 数据集格式转换与划分标注完成的数据我最终统一转成了YOLO格式。YOLO格式的核心是每张图片对应一个同名txt文件每行内容为类别编号 归一化中心点x 归一化中心点y 归一化宽度 归一化高度。以1280宽、720高的图像为例如果一个烟支边界框的左上角坐标是(400, 300)右下角坐标是(450, 330)那么中心点是(425, 315)归一化之后的x就是425/1280约等于0.332y是315/720约等于0.4375宽度是50/1280约等于0.0391高度是30/720约等于0.0417。数据划分上我按8:1:1的比例切分为训练集、验证集和测试集。切分时有一个关键点确保同一视频片段抽出来的帧不要同时出现在训练集和测试集里。否则相邻帧的相似度极高模型在测试集上的表现几乎等于背答案。我的做法是先按视频片段分组再用Python的sklearn库按group分层抽样先分片段再抽帧这样能保证场景级别隔离。目录结构我按照YOLO官方约定的格式来组织smoking_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml4.2 yaml配置与训练启动data.yaml是告诉YOLO模型去哪里读数据的入口文件内容比较简单但细节不能错。path: /data/smoking_dataset train: images/train val: images/val test: images/test nc: 3 names: 0: smoke 1: smoking_action 2: cigarette_box一个容易错的点是path路径。YOLOv8默认会把path、train、val拼接起来形成完整路径。如果你直接把train写成绝对路径或者漏了path字段训练时会报找不到图片的错误。我通常建议path写数据集主目录的绝对路径train和val写相对路径这样换机器迁移时只需要改一行配置。启动训练的命令很简单但参数值得仔细调。我第一版用的是YOLOv8n也就是最轻量的模型1280分辨率下显存占用小但小目标检测能力偏弱。最终生产环境用的是YOLOv8s在精度和速度之间取了一个平衡点。命令如下yolo train \ data/data/smoking_dataset/data.yaml \ modelyolov8s.pt \ epochs200 \ imgsz1280 \ batch16 \ optimizerAdamW \ lr00.001 \ lrf0.01 \ mosaic1.0 \ mixup0.1 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.4 \ patience30这里特意把imgsz设为1280而不是默认的640。原因很简单烟支是小目标640分辨率下烟支可能只有4到6个像素特征信息严重丢失提高到1280后烟支特征能保留更多细节检测精度提升明显。代价是训练速度和推理速度都变慢显存占用也更高如果你的GPU显存小于12G建议先用640跑通流程再逐步做分辨率消融实验。4.3 训练参数调优经验训练过程中的几个细节直接决定模型收敛质量。第一个是数据增强参数不能迷信默认值。YOLOv8的mosaic增强默认开启它在每张图里拼接四张训练图片可以很好提升模型的定位能力。但抽烟行为数据中如果目标本身很小mosaic会进一步把目标缩小让原本就小而模糊的烟支变得更难学。我的做法是mosaic从默认值降到0.8左右同时开启mixup但只给0.1的权重让模型在增强数据中保留更多原始特征信息。第二个是初始学习率的设置。有些人习惯直接套用默认的lr00.01在训练集较大的情况下问题不大但数据量中等且有较多小目标时0.01容易让loss震荡。我下调到0.001收敛更稳定虽然前期loss下降稍微慢一点但最终的mAP更高。配合余弦退火策略lrf0.01训练到后期学习率会平滑降到初始值的百分之一可以较好地收敛到局部最优。第三个是epoch的设置和early stopping的配合。我设了200个epoch配合patience30也就是如果30个epoch内验证集mAP没有提升训练提前终止。这套数据第一次跑的时候大约在第120个epoch达到最优说明训练本身是充分收敛的不需要硬撑到200个epoch。训练完成后建议重点看的指标组合是mAP0.5反映模型在宽松IoU下的检出能力mAP0.5:0.95反映框回归的精准程度。针对抽烟行为这种小目标检测任务mAP0.5更重要一些因为实际业务关注的是“有没有检测到”而不是“框贴合得有多精确”。4.4 评估与迭代训练完不是直接部署要先在测试集上做一轮评估。YOLOv8训练完成后会自动在val集上跑指标但test集的评估需要手动执行命令是yolo predict modelruns/train/exp/weights/best.pt \ source/data/smoking_dataset/images/test \ save_txtTrue \ conf0.25 \ save_confTrue跑完预测后我会重点看两个结果一是每个类别的precision和recall二是具体的预测可视化样例。如果recall低而precision正常说明漏检多需要补充对应场景的正样本或者降低置信度阈值如果precision低而recall正常说明误检多需要补充负样本或者提高置信度阈值。等模型在测试集上mAP0.5达到0.85以上我才认为它达到了部署到真实场景的基本线。5. 真实场景中的常见问题排查5.1 小目标漏检问题小目标漏检是抽烟检测中最常见的问题。烟支在真实监控画面中往往只有几十个像素模型在特征提取过程中经过多次降采样后小目标的特征很容易被背景特征覆盖。解决思路不只是换大模型还有几个更实用的方向。第一个是提高输入分辨率这个前面已经提到过1280比640在小目标上的mAP能提升5到8个百分点。第二个是使用多尺度训练开启YOLOv8的尺度增强后模型每轮迭代会随机缩放输入尺寸这样相当于让模型看到不同尺寸下的烟支形态对小目标的适应性更好。第三个是尝试在模型中增加P2检测头YOLOv8默认从P3层开始检测对应的特征图步长是8而要更好地捕捉小目标需要从P2层也就是步长为4的特征图开始检测。不过这需要修改模型结构工程复杂度会提高建议作为进阶优化方案。5.2 夜间与低照度场景失效夜间场景是抽烟检测的另一个痛点。烟支在夜间的主要特征是烟头红点但烟身几乎不可见这导致模型依赖的特征和白天完全不同。如果你只采集了白天数据夜间部署时性能会骤降。我的处理方式是把夜间数据单独做一组并且在数据增强阶段加入了亮度调整和噪声扰动。具体来说我把训练集里的一部分正常图片在预处理阶段做亮度衰减模拟夜间环境然后配合噪声增强让模型学会在低信噪比条件下提取关键特征。这种方法的提升有限但至少能让模型在夜间场景不至于完全失效。真正要做得好的话还是要定期补充真实夜间场景的数据。另一个好用的技巧是在训练时加入红外图像的模拟。很多监控摄像头有红外模式红外画面里烟头的红点会更突出且不容易受背景干扰。如果你能采集到红外数据建议单独重训一个模型效果会远好于把红外和可见光混在一个模型里训练。5.3 类别不平衡的问题如果训练数据里90%都是近景数据只有10%是远景数据那么远景场景的检测能力一定会被“淹没”。我在数据采集时对每个场景类别做了配额控制比如白天室内近景占比不超过25%夜间场景占比不低于15%远景和中景各占20%左右。这样能保证模型不会过度偏向某一类场景。但在实际训练中即便采集时控制了比例仍然会出现某些难例类别学习不充分的情况。我的做法是应用Focal Loss的思想如果模型在某个难分样本上置信度很低训练时会加大这部分样本的损失权重。YOLOv8默认使用的是带类别平衡的BCE Loss如果你想用Focal Loss需要手动改损失函数配置或者借助Ultralytics的一些扩展实现。对绝大多数工程场景我建议先用默认损失函数把主要精力放在优化数据样本的分布上。5.4 遮挡与密集场景误检多人同时抽烟的场景手部相互交叠烟支彼此靠近模型很容易把两个人手里的烟误认为一个人的行为。这类问题在目标检测层面很难完全解决因为检测模型本身就是逐目标独立判断的缺少目标之间的空间关系建模。我在工程上给出的妥协方案是分两步走第一步用检测模型输出所有检测框第二步基于检测框的手部关键点或距离关系做后处理规则比如两个smoke框之间的距离较近且有各自的smoking_action框关联时判定为多人独立吸烟而不是一个目标。这个方案虽然朴素但实际用下来比直接更换模型结构更有效也更容易部署。另外遮挡场景容易出现漏检的典型情况是手插兜、手放桌面下、用手遮挡嘴部。这些情况下的烟支几乎不可见本质上已经超出了视觉目标检测的能力边界。我一般会在标注时把这类样本单独归入难例集在训练时故意保留让模型的置信度输出偏低。这样在真实业务中这些样本不会给出错误的高置信度预测而是留给后续的人工审核环节。6. 模型的部署与后续扩展6.1 边缘端部署落地训练好的模型最终要部署到监控摄像头或边缘计算盒子上去。目前主流方案是导出为TensorRT的engine格式在NVIDIA Jetson系列设备上运行或者导出为ONNX格式再通过ONNX Runtime在RK3588等国产边缘设备上运行。以Jetson Orin Nano为例导出流程是先用YOLOv8导出ONNX然后用TensorRT的trtexec工具把ONNX转换为FP16精度的engine文件。注意导出时要指定动态batch并设置与训练时一致的输入分辨率。我可以负责任地说很多人的模型在边缘设备上跑不快原因就是在导出时没做FP16量化或者输入分辨率设置不匹配。部署时还有一个容易被忽略的参数是nms阈值。YOLO模型输出的原始预测框是大量重叠的候选框NMS用来在这些框里挑选最终结果。如果nms阈值设置太高比如0.9会产生大量重叠框导致同一个烟支被输出多个检测结果设置太低比如0.3又容易把密集场景里的真实目标过滤掉。我实测下来抽烟检测场景设置nms_iou为0.5比较平衡。实时的推理还有另一个方向就是把多个视频流分帧调度让边缘设备在低利用率下也能平稳处理多路输入。6.2 数据集的持续迭代机制数据集不是一次性工作而是一个持续迭代的闭环。我在项目落地后建立了一套“发现难例-补充标注-增量训练”的迭代机制。具体来说部署后的系统每天会保存两类图片一类是置信度在0.3到0.7之间的模糊预测结果另一类是人工确认过的漏检和误检截图。这些图片每周汇总一次经过清洗和去重后补充到训练集里做增量训练。增量训练有两种常见做法一种是直接在新的完整数据集上重新训练优点是稳定可靠缺点是每次都要花时间另一种是以当前权重为预训练权重只在小样本上继续迭代速度快但有一定可能遗忘旧数据。工程上我推荐第一种即每隔两周用“原始数据新增难例”全量重训一轮这样既保证数据的时效性又不会出现灾难性遗忘。关于数据集的版本管理我也建议认真做一下。最好能记录每个版本包含的图片数量、场景分布、标注类别数量以及对应的模型评估指标。我在实际项目中发现版本记录做得好定位模型回退原因时效率会高很多。你甚至可以根据某个版本的mAP变化追溯到是新增了哪些难例导致的指标抖动。6.3 从检测走向行为理解的扩展方向前面讲的都是“看单帧图像”的检测模型但真正的行为识别更强调时空连续性。很多抽烟行为在单帧里很难判断比如烟在手里举着下一秒究竟是靠近嘴边还是放下单靠检测很难提前预警。所以我在这个数据集的基础上正在尝试做两个扩展方向。第一个是引入时序模型。把连续多帧的检测框序列作为输入配合行为分类模型判断当前处于“持烟”“点烟”“吸烟”中的哪个状态。这个想法不算新但依赖高质量的视频级标注数据。第二个是接入姿态估计模型先检测人体关键点特别是手部关键点和头部关键点然后根据手与嘴的距离、手的停留时间来判断是否发生了吸烟动作。这两个方向各有优劣前者依赖检测精度后者更擅长处理动作连续性在实际工程中我倾向于结合二者。最后说一点我个人探索操作系统上的经验教训。做小目标检测项目尤其是抽烟、打电话这类行为识别任务模型结构的选择重要但远没有数据多样性和标注质量重要。我在多次复盘中都发现一次有效的难例补充往往比换一个更大的模型带来的收益更明显。如果你也在做类似的项目我建议先从数据层面找问题再去纠结结构层面的优化这条路走起来会顺畅很多。本文还有配套的精品资源点击获取
返回列表