ARTICLE DETAIL

资讯详情

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

吸烟人群检测数据集:从标注到YOLO训练与边缘部署全链路

吸烟人群检测数据集:从标注到YOLO训练与边缘部署全链路 简介本资源为面向目标检测任务的吸烟人群检测数据集适用于计算机视觉方向的学生、算法工程师及科研人员可用于训练和验证抽烟行为识别模型覆盖自然生活场景与影视剧画面中的吸烟人物。数据集共包含2000个文件全部为xml格式的标注文件对应2000余张图片压缩包整体约198.63MB标注内容为边界框左上角与右下角的坐标信息可直接用于目标检测训练无需额外清洗或格式转换。目前已有685人学习下载具备一定的使用参考价值。读者可获得一套开箱即用的吸烟行为检测数据省去自行采集与标注的成本便于快速搭建基线模型、验证算法效果也可用于数据增强、模型对比实验或迁移学习等研究场景适合作为目标检测入门与进阶的实战素材。1. 吸烟人群检测数据集从标注到 YOLO 训练一条能跑通的链路吸烟人群检测数据集本质是一个面向目标检测任务的图像数据集标注对象是「人」和「烟」两类目标输出格式通常兼容 YOLO 系列。它的价值不在于数据量有多大而在于场景聚焦——室内监控、公共场所摄像头、工地安全巡检这些场景里通用 COCO 模型对「手持香烟」这个小目标的召回率经常掉到及格线以下。我最早接触这类需求是在一个园区安防项目里客户要求对吸烟行为做实时告警拿 COCO 预训练模型直接推理烟头几乎全漏。后来自己整理了一份约 3000 张的吸烟场景数据集用 YOLOv8 微调mAP0.5 从 0.41 拉到 0.78才算能交付。这篇文章就把这条链路拆开讲数据集长什么样、怎么标注、怎么转格式、怎么训练、坑在哪。适合手上有吸烟检测需求、准备自己训模型的工程师也适合想拿这个数据集练手目标检测的新手。2. 吸烟人群检测数据集的结构与标注规范2.1 两类目标怎么定义person 与 cigarette吸烟检测的核心难点在于类别定义。很多人第一反应是只标「烟」但实际落地时只标烟会出大问题模型会把白色笔、细长反光物、手指间夹的杂物全判成烟。我的做法是固定两类——person和cigarette其中cigarette只标注正在被手持或叼在嘴边的烟桌上放着的烟盒、烟灰缸里的烟头一律不标。这样模型学到的是「人与烟的交互关系」而不是单纯的细长物体检测。标注框的粒度也要统一。person标全身或可见上半身cigarette标烟的可见部分哪怕只有几个像素也要标因为小目标检测恰恰是这类数据集的训练重点。如果烟被手指遮挡超过一半我一般会放弃这个框避免引入噪声。2.2 目录结构与标注文件格式一份可直接用于 YOLO 训练的吸烟人群检测数据集目录通常长这样smoking_dataset/ ├── images/ │ ├── train/ # 训练集图片约 2400 张 │ ├── val/ # 验证集图片约 400 张 │ └── test/ # 测试集图片约 200 张 ├── labels/ │ ├── train/ # 与图片同名的 .txt 标注 │ ├── val/ │ └── test/ └── data.yaml # 数据集配置文件图片格式统一为.jpg标注为 YOLO 格式的.txt每行五个值class_id x_center y_center width height全部归一化到 0~1。class_id为 0 表示person1 表示cigarette。这里有个血泪经验标注文件名必须和图片名严格一致差一个字符 YOLO 就找不到标签训练时 loss 直接不降排查半天才发现是命名问题。2.3 data.yaml 的写法与路径陷阱data.yaml是 YOLO 训练的入口配置写法如下# 吸烟人群检测数据集配置 path: /home/user/smoking_dataset # 数据集根目录建议写绝对路径 train: images/train # 相对 path 的训练图片目录 val: images/val test: images/test nc: 2 # 类别数 names: 0: person 1: cigarette参数说明path用绝对路径最稳相对路径在不同工作目录下启动训练时经常翻车nc必须和names的条目数一致写错会报索引越界names的顺序要和标注里的class_id对应0 和 1 写反了模型会把人和烟搞混。这个文件看着简单但新手至少有一半的报错出在这里。3. 从原始图片到 YOLO 格式标注工具与转换脚本3.1 标注工具选型LabelImg 与 Roboflow 的取舍标注工具我主要用两个。本地标注用 LabelImg开源、离线、支持 YOLO 格式直接导出缺点是界面老旧、多人协作麻烦。团队协作或需要在线审核时用 Roboflow支持自动标注预填充、多人分工、版本管理导出时直接选 YOLOv8 格式。如果数据涉及隐私不能上云就老老实实用 LabelImg 或 Label Studio 本地部署。标注时的操作要点先标person再标cigarette保证类别顺序一致每张图标注完立刻保存LabelImg 偶尔会丢未保存的框遇到模糊图片直接跳过不要硬标模糊样本对训练只有负作用。3.2 用 Python 脚本做格式转换与校验如果你手上有的是 VOC 格式.xml或 COCO 格式.json的标注需要转成 YOLO 格式。下面这个脚本处理 VOC 转 YOLO并顺带做一次校验import os import xml.etree.ElementTree as ET from PIL import Image # VOC 转 YOLO并校验标注合法性 def voc_to_yolo(xml_dir, img_dir, out_dir, class_map): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() img_name root.find(filename).text img_path os.path.join(img_dir, img_name) if not os.path.exists(img_path): print(f图片缺失跳过: {img_name}) continue w, h Image.open(img_path).size lines [] for obj in root.findall(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) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 越界裁剪防止归一化后超出 0~1 xmin, ymin max(0, xmin), max(0, ymin) xmax, ymax min(w, xmax), min(h, ymax) if xmax xmin or ymax ymin: print(f非法框跳过: {img_name}) continue xc (xmin xmax) / 2 / w yc (ymin ymax) / 2 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) out_path os.path.join(out_dir, xml_file.replace(.xml, .txt)) with open(out_path, w) as f: f.write(\n.join(lines)) # 类别映射person 为 0cigarette 为 1 voc_to_yolo(annotations_xml, images, labels, {person: 0, cigarette: 1})逻辑说明脚本遍历 XML 文件读取图片真实宽高做归一化这是 YOLO 格式的核心要求。越界裁剪那几行很关键标注时手抖画出图片边界的框不裁剪会导致归一化值大于 1训练时直接报错。参数说明class_map决定类别顺序必须和data.yaml的names一致out_dir输出的 txt 文件名和 XML 同名后续要确保和图片名对齐。3.3 数据集划分与防泄漏检查划分训练/验证/测试集时最大的坑是同一段视频的连续帧被分到不同集合导致验证集精度虚高。正确做法是按视频源或拍摄场景划分同一场景的图片只进一个集合。我一般按 8:1:1 划分划分完跑一遍检查脚本确认没有同名图片跨集合出现。如果数据集里有人物重复出现还要检查同一人的图片是否被拆散否则模型会记住人脸而不是学吸烟特征。4. 用 YOLOv8 训练吸烟检测模型参数配置与显存调优4.1 环境搭建与最小训练命令环境用 Python 3.10 PyTorch 2.x ultralytics 包。安装命令pip install ultralytics最小训练命令如下yolo detect train \ datasmoking_dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ device0参数说明model选yolov8n.pt是轻量版适合先跑通链路imgsz640是标准输入尺寸吸烟检测里烟目标小可以尝试imgsz960提升小目标召回但显存占用会翻倍batch16在 8G 显存上比较稳显存不够就降到 8 或 4device0指定第一块 GPUCPU 训练会慢到无法接受。第一次训练建议先用 10 个 epoch 跑通确认 loss 正常下降再拉满。4.2 针对小目标的三个必调参数吸烟检测的核心矛盾是烟太小。除了imgsz还有三个参数值得调参数默认值建议值作用imgsz640960提升小目标分辨率mosaic1.00.5降低马赛克增强避免烟被拼没copy_paste0.00.3复制粘贴小目标增加烟的样本量mosaic增强会把四张图拼成一张烟这种小目标拼完可能只剩几个像素适当降低比例有好处。copy_paste是 YOLOv8 支持的小目标增强手段把烟抠出来贴到其他图上能显著提升召回。我实测在 3000 张数据集上这三个参数调完 mAP0.5 能涨 5 到 8 个点。4.3 训练过程监控与早停策略训练启动后重点看三个指标box_loss是否稳定下降、mAP0.5是否上升、cls_loss是否震荡。如果box_loss降到 0.5 以下但 mAP 不涨大概率是过拟合加数据或加增强。早停用patience2020 个 epoch 没提升就停省时间。训练日志和权重默认存在runs/detect/train/下best.pt是验证集最优权重部署时用这个而不是last.pt。5. 吸烟检测落地的避坑与排查清单5.1 标注类别不均衡导致烟类召回低现象训练完person的 AP 有 0.9cigarette只有 0.4。原因烟的目标框数量远少于人模型偏向多数类。解决用copy_paste增强烟样本或在 loss 里给烟类更高权重也可以在数据层面补充更多吸烟图片。我一般先看标注统计烟框少于总框数 10% 就要警惕。5.2 验证集精度高但实际推理漏检现象验证集 mAP 0.8部署到摄像头画面里烟几乎检不到。原因验证集和训练集同源场景太相似模型没学到泛化特征。解决按场景划分数据集验证集里放不同光照、不同角度的图片部署前用真实摄像头截图做一次测试别只看验证集数字。5.3 图片和标签文件名不匹配现象训练启动后 loss 一直是 nan 或不下降。原因labels目录里的 txt 文件名和images里的图片名对不上YOLO 找不到标签全当背景训练。解决写个脚本比对两个目录的文件名集合差集打印出来逐个修。这个坑我踩过两次每次都是命名带空格或大小写不一致。5.4 显存溢出导致训练中断现象训练到一半报 CUDA out of memory。原因batch或imgsz设太大或者workers开太多导致内存泄漏。解决先把batch减半再降imgszworkers设成 4 或 8 别拉满。如果还不行用yolov8n而不是yolov8m轻量模型显存占用小很多。5.5 推理时置信度阈值设错现象模型能检出烟但框太多误报严重。原因默认conf0.25对吸烟场景偏低很多细长物体被误判。解决部署时把conf提到 0.4 到 0.5同时开iou0.5做 NMS。如果还是误报检查训练数据里有没有把笔、数据线误标成烟这种脏标注必须清掉。6. 把吸烟检测模型压到边缘设备量化与推理加速的一个具体技巧训练完的best.pt在服务器上跑没问题但园区项目往往要部署到 Jetson 或 RK3588 这类边缘盒子这时候模型大小和推理速度就是硬指标。我常用的做法是导出 ONNX 再转 TensorRT或者直接用 ultralytics 的导出命令做半精度量化。先导出 ONNXyolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640 halfTruehalfTrue表示 FP16 半精度模型体积直接减半推理速度提升 30% 左右精度损失通常在 1 个点以内对吸烟检测这种二分类任务完全可接受。导出后在边缘设备上用 ONNX Runtime 或 TensorRT 加载推理代码里注意预处理要和训练时一致letterbox 缩放、BGR 转 RGB、归一化到 0~1任何一步不一致都会导致精度暴跌。如果边缘设备算力实在紧张还可以做 INT8 量化但需要准备校准集。校准集从验证集里抽 200 张有代表性的图片覆盖不同光照和场景量化后用测试集验证精度掉超过 3 个点就说明校准集不够代表性得补样本。我一般会保留 FP16 和 INT8 两个版本线上先跑 FP16算力不够再切 INT8。验证量化模型是否可用别只看 mAP要在真实视频流上跑一遍统计每秒检出帧数和误报次数。我习惯用一段 5 分钟的吸烟场景视频做回归测试人工数出真实吸烟次数和模型告警次数对比召回率低于 85% 就回去查预处理和阈值。这套流程跑熟之后从训练到边缘部署大概两天能完成一轮迭代。最后一个习惯每次训完模型把data.yaml、训练命令、关键参数和 mAP 结果记到一个文本文件里和权重放一起。下次换数据集或调参时翻记录比翻聊天记录靠谱得多。吸烟检测这个方向数据质量比模型结构重要标注干净、场景覆盖全比换更大的模型管用。希望帮到你。本文还有配套的精品资源点击获取
返回列表