抽烟检测数据集实战指南:标注规范、清洗与训练避坑

发布时间:2026/10/16 6:45:26
抽烟检测数据集实战指南:标注规范、清洗与训练避坑 简介面向深度学习与机器学习图像检测任务这是一套带完整标注的抽烟检测数据包。数据按 Annotations、Imagenet、JPEGImages 三个目录组织原始图片集中在 JPEGImages经 labelImg 标注后生成的 XML 文件统一放入 Annotations可直接衔接 Faster R-CNN、YOLO 等常见目标检测训练流程。包体约 298.09MB按文件类型统计共 7897 个文件核心为 4650 个 JPG 图片与 3235 个 XML 标注文件另附 README、train/val/test 划分 txt 和 voc2yolo4.py 转换脚本便于将 VOC 格式标注快速转为 YOLOv4 所需格式省去手工整理标签的环节。资源已有 7528 人浏览学习适合需要真实抽烟样本、希望跳过人工标注阶段的研究者、竞赛选手和工程开发人员。拿到后可直接复用标注结果与数据划分脚本也可参考脚本逻辑适配其他检测框架明显降低数据准备与格式转换的时间成本。1. 抽烟检测数据集你以为买的是图片其实买的是标注规范和验收标准一套标注好的抽烟检测数据集表面上是“图片XML/JSON/TXT标注文件”的压缩包实际上是一整套为监督学习准备的训练物料。这里的核心不是那几千张 JPEG而是每张图里框住烟支、烟雾和嘴部区域的那几行坐标——模型能不能在工地、加油站、办公楼走廊里稳定识别出违规抽烟行为几乎完全取决于这些框标得准不准、边界统一不统一、难例覆盖得全不全。很多团队拿到数据集后第一件事就是转格式、开训练结果训练到一半发现 loss 降不下去或者验证集 mAP 有 0.9 但一到真实摄像头画面就疯狂漏检。这类问题通常不是模型结构选错了而是数据集里的标注噪声、类别失衡和上下文缺失在作祟。本文按“数据集构成 → 清洗筛选 → 标注质检 → 训练避坑 → 半自动增量”这条链展开把每一步怎么做、参数怎么设、坑在哪里讲透。2. 数据集内部结构目录布局、标注格式与类别的选型逻辑2.1 标注格式选型YOLO txt、COCO json、VOC xml 谁更合适一套抽烟检测数据集最常见的交付形态是 Images 和 Labels 两个顶层目录或按 train / val / test 划分的完整目录树。拿到手第一件事不是打开图片看效果而是确认标注格式。三种主流格式各有适用场景YOLO txt 格式是归一化的类别中心点宽高训练时代码处理最省事COCO json 格式自带图像信息、标注信息和类别映射表适合做 mmdetection 或 Detectron2 这类框架的输入VOC xml 格式是绝对像素坐标适合阅读、人工校验和在小工具之间流转。dataset_smoking/ ├── images/ │ ├── train/ # 训练集图片 │ ├── val/ # 验证集图片 │ └── test/ # 测试集图片 ├── labels/ │ ├── train/ # 与图片同名的 .txt 标注 │ ├── val/ │ └── test/ ├── classes.txt # 类别列表一行一个类别名 └── data.yaml # 训练配置指向上述路径这是一种最直接的 YOLO 系列目录布局。图片和标注文件保持同名是关键。如果交付的是 COCO json通常是一个 annotations 文件夹加一个 instances_train.json、instances_val.jsonVOC 则是每个图片配一个同名 xml 文件。我拿到数据集会先跑一个三分钟的一致性校验遍历所有图片文件检查对应标注文件是否都存在、是否为空文件、类别 ID 是否超出 classes.txt 的范围。这一步能筛掉不少交付时漏拷贝文件的问题。# 快速校验检查 labels 中是否有孤儿文件、空文件、越界类别ID find labels -name *.txt | while read f; do [ ! -s $f ] echo empty: $f done python - EOF from pathlib import Path for p in Path(labels).rglob(*.txt): for line in p.read_text().splitlines(): cls int(line.split()[0]) if cls 0 or cls 1: print(fbad class {cls} in {p}) EOF这段脚本做了两件事第一段 shell 检查空标注文件第二段 Python 遍历所有 txt 的类别 ID 是否越界。以上示例假设只有“吸烟”和“背景”两类实际使用时根据 classes.txt 行数调整上限即可。更严谨的做法是同时校验坐标是否在 0~1 之间、宽高是否为正值——YOLO 格式里任何负坐标或零宽高都会在训练时报错或静默产生无效 anchor。2.2 类别与属性单类烟支还是多类“烟烟雾嘴部”抽烟检测数据集在类别设计上大致分三种路线只标一个“smoking”框、标出“cigarette smoke”两类、以及标出“烟支 烟雾 嘴部/手部区域”的多类属性。第一种实现最简单但模型学到的特征是“手和嘴附近的模糊物体”容易把手机、冰棍、签字笔误判成烟第二种能缓解一部分误判但烟雾是半透明、形态多变的标注一致性很难保证第三种更接近真实业务需要的语义但标注成本高。我做这类项目时默认建议至少区分两个类别cigarette和smoke。用两个框表达“这个人嘴里有烟”和“有烟雾飘出”两个独立信号业务层再做综合判断。如果数据集本身只给了一个类也别急着退掉先用它完成 baseline后续增量迭代时再按统一规范补标。属性标注方面标识是否“正在点燃/只是叼烟”、是否“烟雾遮挡脸部”、是否“电子烟”对训练后的规则过滤有很大帮助。2.3 训练集与验证集划分边界随机划分还是按场景划分很多数据集交付时已经随机划分好了 train/val/test但随机划分有一个隐蔽问题如果同一个场景连续拍了大量相似帧随机划分会把这些相似帧同时分进训练和验证导致验证分数偏高。更严格的做法是按采集场景或视频片段分组比如同一地点不同时间拍的帧全部进训练集或验证集不能跨集合。我拿到训练集后会把图片按像素哈希聚类做一次相似帧去重再去重后的数据里按 8:1:1 重新划分。如果数据源里有明显的连续帧序列文件名带时间戳或帧号直接用文件名前缀分组。这样做的代价是验证集会损失一点分数但换来的是线上表现更可信——验证集分数如果比随机划分低 3~5 个点这属于正常现象。3. 数据清洗与分布检查光照、距离、姿态和硬负样本3.1 数据分布矩阵先把 90% 的问题暴露在训练之前抽烟检测的难点集中在光线暗、距离远、角度刁、遮挡重四个维度。一张白天正面大脸叼烟的图片属于易例一堆傍晚工地背光、半张脸被安全帽遮挡、烟只露出一小截的图片才是真实场景。拿到数据集后先做一个维度抽样检查而不是直接训练每个维度抽 20~30 张图看标注质量。四个维度组合下来就是一张 4x4 的抽样网格这一步只需半天能把后续返工时间省下一大半。维度易例特征难例特征建议最少张数光照白天自然光、面部受光均匀逆光、夜晚路灯、室内荧光灯300距离胸部以上占画面主体全身远距离、监控俯视小目标300姿态正面或轻微侧脸低头、转头、手遮挡嘴部200遮挡无遮挡口罩、帽子、烟雾弥散150表格里的张数只是底线参考不是标准。真实项目里如果部署场景是加油站夜晚和逆光样本至少要占到 40% 以上如果是办公楼室内重点反而是日光灯下的低对比度和远处走廊的小目标。按部署场景反向决定数据分布才是选型的关键逻辑。3.2 相似帧去重与清晰度过滤一张图被复制三次会毁掉验证集视频抽帧得到的数据集常常存在大量重复帧尤其是人物静止、只有烟雾变化的那几秒。重复帧如果不清理轻则让训练集分布失真重则导致验证集和训练集之间出现数据泄露——同一帧的轻微压缩变体同时出现在两边模型“记住”了验证图mAP 虚高。# 基于感知哈希的相似帧去重连续帧之间哈希距离小于阈值则丢弃 import cv2, imagehash from PIL import Image from pathlib import Path def is_duplicate(hash1, hash2, cutoff5): return hash1 - hash2 cutoff prev_hash None for img_path in sorted(Path(raw_frames).glob(*.jpg)): img cv2.imread(str(img_path)) if img is None: continue cur_hash imagehash.phash(Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))) if prev_hash is not None and is_duplicate(prev_hash, cur_hash): print(fdrop duplicate: {img_path.name}) # img_path.unlink() # 确认后解除注释 prev_hash cur_hash这里的感知哈希把图片压缩成 64 位指纹汉明距离小于等于 5 视为近似重复。cutoff 调到 8 会更激进适合连续视频帧调到 3 则只删几乎一模一样的图。注意这种方式只对“同机位、同目标”的连续帧有效不同场景但相似构图的图片不会被误删。更完整的方案是先做场景切分再在场景内做哈希去重。3.3 硬负样本没有“烟”的图片才是好数据集的一部分抽烟检测的误报很多时候来自数据集里缺乏“看似像烟但实际不是烟”的负样本。纯背景图好找难的是那些包含手势、嘴部动作、饮料吸管、白色耳机线、笔的图片——模型如果没见过这类样本就会把一切长条形白色物体往“烟”上靠。我一般建议负样本占比做到 20%~30%且其中一半以上要包含人物。验证时要专门看误报率。如果数据集里没有单列负样本目录可以用不含任何标注的普通图片补充搭配一个空 labels 文件即可。注意 YOLO 训练时空标注文件是允许的但有些版本的自动 anchor 计算会忽略它们需要确认数据加载器是否正常读取了空文件目录。4. 从图片到标注标注规范、标注工具与质检流程4.1 标注规范里的三个边界定义画框范围、遮挡处理、电子烟归属标注规范里争议最大的三个问题框要框住什么、目标被遮挡时怎么框、电子烟算不算。第一个问题我习惯定义为“烟支可见部分的最小外接矩形”不包含嘴部和手烟雾是另一个独立框但前提是烟雾必须和烟支有空间连续性画面里远处飘来的无关烟雾不标。这样定义是因为检测器后续要依赖烟支位置做业务判断框得太大等于引入背景噪声。第二个问题目标被手遮挡或嘴唇遮挡时统一按“可见部分外接矩形”标注不推断被遮挡的完整烟支。推断框会让不同标注员的框差出 30% 以上。第三个问题电子烟在视觉上和传统烟支有明显差异无燃烧端、形态笔直且色彩多样如果有业务需求就单独设一个ecigarette类如果没有就统一不标标注规范里要写死避免标注员按个人理解随意处理。4.2 标注工具链从 LabelImg 到半自动预标注手工标注优先选支持类别预设、自动保存、快捷键切图的工具。常见做法是先用 LabelImg 做小批量试标因为它的 XML 格式直观、改起来容易适合团队第一次对齐规范。等规范稳定后再换用支持 YOLO 格式直接导出、能多人协同的工具因为这类工具多人同时标注同一个任务集时可以实时看到彼此的标注情况复核效率更高。# 开源的通用标注工具启动命令按自己环境选择即可 labelimg # 若安装的是桌面版 # 或 cvat-cli --help # 基于浏览器的多人标注工具的命令行入口上述命令本身没有参数需要调关键是标注工程的文件组织数据源按“原始图片 一份同名 json 或 txt”维护导出的标注文件必须能溯源到原始图。多人标注时给每个标注员分配独立子目录避免多人同时写同一个文件导致覆盖。4.3 质检环节IoU 一致性抽检与边界框面积统计质检不能只看“有没有漏标”更要看“不同人标同一个目标的框一致不一致”。最省钱的办法是同一批 100 张图让两个标注员各标一遍计算相同目标的 IoU 分布。如果中位数低于 0.7说明规范没对齐加标前需要重新沟通而不是直接修改标注。# 简单版质检计算两个标注文件之间的框级 IoU 统计 def iou_of_boxes(box_a, box_b): x1 max(box_a[0], box_b[0]); y1 max(box_a[1], box_b[1]) x2 min(box_a[2], box_b[2]); y2 min(box_a[3], box_b[3]) inter max(0, x2 - x1) * max(0, y2 - y1) area_a (box_a[2] - box_a[0]) * (box_a[3] - box_a[1]) area_b (box_b[2] - box_b[0]) * (box_b[3] - box_b[1]) return inter / (area_a area_b - inter) iou_list [] # 遍历同名标注文件按坐标进行两两匹配计算最大 IoU # 低于 0.5 的优先人工查看可能是漏标或边界差异这段代码只演示了单对框的 IoU 计算实际质检脚本里要做的是按类别分组、按面积排序后再匹配优先检查面积最大的前 20% 目标。面积小的目标 IoU 天然偏低不要用同一个阈值一刀切。正确做法是面积大于 32x32 像素的目标要求 IoU 不低于 0.7小于 32x32 的放宽到 0.5。5. 训练阶段才暴露的数据集坑五个高频翻车现场与排查路径5.1 模型把手机当烟上下文区域漏标导致的特征误学习现象 → 原因 → 解决现象训练出的模型在验证集上表现正常部署到真实场景里频繁把“手举到耳边”或“低头看手机”识别成抽烟。打开推理可视化发现模型抓的特征是“手部靠近脸部 嘴部张开”根本不关心手里有没有烟。原因数据标注时只框了烟支没有框背景。更准确地说是训练图里所有“手在嘴附近”的样本都同时带有烟支标注模型学到了“手在脸附近”这个强相关特征而烟支本身的小目标特征反而不重要了。解决往训练集里大量补充“手在脸附近但不抽烟”的负样本最好达到正样本量的 20% 以上。同时在标注规范里增加一条画完烟支框后检查同一张图里是否有另一个“疑似手部靠近嘴部”的区域如有则把整张图记为 hard negative 备用。如果补充数据成本太高也可以做一个保守策略推理时同时要求“烟支框存在”且“烟支框与嘴部区域重叠”用规则过滤掉单靠手势触发的误报。5.2 验证集 mAP 0.9 但夜间摄像头全灭场景分布偏差现象 → 原因 → 解决现象训练集和验证集来自同一个数据包白天室内占比超过 70%夜间和逆光样本不到 5%。mAP 看起来很高但拿到真实夜间场景测试漏检率超过一半。原因随机划分只保证了“数量均衡”没有保证“场景均衡”。夜间样本太少且都集中在训练集或验证集一边模型基本没有见过暗光特征。解决按“场景优先、数量其次”的原则重划数据集。先给每张图打场景标签按“场所工地/楼道/室内 时间段白天/夜晚”组合分成子集每个子集内部再按 8:1:1 划分。训练时如果暗光样本仍然不够用图像增强的方式模拟随机降低亮度、加高斯噪声、模拟荧光灯频闪。注意增强参数不能过猛亮度降到原图 40% 以下会让标注框本身也失真。5.3 远处小目标全漏检烟支 20x10 像素的宿命现象 → 原因 → 解决现象远距离监控画面里烟支在图像中只有 20x10 像素甚至更小模型几乎全部漏检而近景大目标识别得很好。原因数据集中远距离小目标占比太低导致训练的 anchor 匹配策略里小尺寸 anchor 分配不到足够正样本。解决三个手段组合使用——其一将输入分辨率从 640 提升到 960 或 1280小目标像素面积对应变大其二训练时开启 mosaic 增强并把小目标所在的子图单独随机裁剪放大后拼回原图其三如果小目标仍然漏检做离线切片推理把原图按 2x2 或 3x3 切片每片放大后再推理最后聚合结果。这个解法会显著增加推理耗时一般只在固定摄像头场景下用。5.4 标注边界不一致导致 NMS 后框漂移现象 → 原因 → 解决现象两个标注员画同一个目标一个习惯紧贴烟支画另一个习惯把烟头处的烟雾一并框进去。训练后模型输出的框在两个习惯之间摇摆NMS 后框忽大忽小业务侧计算“烟支是否位于嘴部区域”的规则时灵时不灵。原因标注规范没有量化“外接矩形”的边界范围。解决用 5.3 里提到的双人抽检 IoU 方法把 IoU 中位数低于 0.75 的目标列出找出每个类别的系统性偏差。比如发现“烟支上边界多以烟雾为准”是主要偏差就在规范里明确“烟支框不包含烟雾区域”。也可以增加一个后处理步骤对模型输出的框做尺寸聚类超过当前图片尺度中位数 3 倍的框视为异常回退到上一帧或相邻锚框的位置。5.5 验证集分数越训越低标注噪声被模型反噬现象 → 原因 → 解决现象训练初期验证集 mAP 正常上升训练到中途开始下降或者震荡剧烈。loss 曲线显示收敛但 mAP 不涨。原因训练集里存在大量错误标注——标签类别错误、框偏移一半以上、目标漏标。模型前期拟合的是“大多数正确样本”后期开始记忆噪声样本导致泛化下降。解决不要在训练上死磕回到数据集做一轮“错题本检查”。把训练完的模型在训练集上做推理找出置信度很低但标注存在的目标或者置信度很高但标注缺失的目标导出成表逐张看。一个 2000 张的数据集做出 200 张错题本是正常的把这些错题本图片修正标注后重训mAP 通常能回升 3~5 个点。这就是数据清洗的真正价值所在。6. 进阶技巧用训练出来的模型反向迭代数据集让标注量越滚越少训练完第一个可用模型后最常见的做法是直接交付但我更推荐一个迭代习惯利用当前模型对新采集的原始视频做预标注人工只修正不重画把修正结果并回训练集。这个流程能解决冷启动阶段“标注工作量太大”的难题一般第二轮迭代后纯手工标注量可以降到原来的三成左右。# 半自动标注流水线推理 置信度过滤 人工修正 python detect.py --source raw_videos/ --weights runs/train/exp/weights/best.pt \ --conf 0.35 --save-txt --save-conf--conf 0.35是预标注的关键参数。设高了会漏掉大量难例变成纯人工标注设低了会产生一堆假正样本修正工作量更大。经验值是从 0.3 起步先跑 200 帧看预标注质量再调整。--save-txt会输出 YOLO 格式的预测结果--save-conf保留置信度方便后续按置信度区间分配人工修正优先级0.6 以上的直接入库0.3~0.6 的优先修正0.3 以下的单独整理成 hard negative 候选。预标注结果并入训练集前必须做一次标签质量门禁置信度高于 0.6 的框直接采用但同一张图里如果模型输出了互相重叠超过 50% 的两个同类框说明该图存在歧义需要人工确认置信度低于 0.3 的框一律丢弃。另一条经验是每次增量合并后重新统计类别的宽高分布如果新样本的框尺寸分布和现有训练集差异过大说明推理模型在当前分辨率下有系统性偏差要回到 5.3 那类问题去排查。这个半自动流程持续做三个月后数据集会逐渐收敛到“难例密度很高、冗余相似帧很少”的状态。我自己最深的感受是数据集项目永远没有“彻底完成”的那天它跟模型一起演进。一套好的抽烟检测数据集不是一次交付而是一条数据闭环的起点——今天你花在质检和清洗上的每一分钟都会在明天的漏检率数字上还回来。希望这篇笔记能帮到你愿你的训练曲线一路平稳。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询