资讯详情

YOLO工地扬尘检测:166张实拍小样本数据集与微调实战

📅 2026/10/9 16:30:17 | 华诺云谱 👁 阅读
YOLO工地扬尘检测:166张实拍小样本数据集与微调实战
简介本资源是面向计算机视觉初学者与工程实践者的建筑工地扬尘目标检测专用YOLO数据集聚焦于施工场景中尘土颗粒的精准识别与定位可直接用于YOLOv5至YOLOv13等主流系列模型的训练与验证。压缩包共503个文件含168张JPG工地实景图像、166份对应XMLPASCAL VOC格式与TXTYOLO格式双标注文件确保多框架兼容另附data.yaml配置文件、README.md说明文档及技术参考PDF训练集/验证集已预划分开箱即用。资源大小26.07MB轻量高效适配边缘部署与教学实验。目前已有17人学习下载适合开展环境监测AI项目、课程设计或竞赛选题尤其便于理解工地复杂背景下小目标、低对比度扬尘的标注规范与数据组织逻辑。1. YOLO识别建筑工地扬尘166张实拍图完整标注小样本也能跑通检测流程你有没有试过在工地上部署目标检测模型结果发现——明明训练时mAP挺高一到现场就漏检大片扬起的尘土不是模型不行是数据太“干净”合成数据缺真实颗粒感公开数据集又没工地场景。这个压缩包里装的是某高校环境监测实验室在3个典型施工阶段土方开挖、渣土运输、场地平整连续两周实采的166张高清图像全部人工框选尘土区域标注类别统一为dust格式严格按YOLOv5/v8/v9通用规范生成.txt标签文件。它不解决“超大规模训练”但能让你在2小时内完成从解压→验证标注→微调→推理的全链路闭环。适合两类人一是刚学完YOLO理论、卡在“找不到真实小场景数据”的新手二是需要快速验证扬尘干预效果、但预算只够跑轻量模型的现场工程师。别被数量吓住——166张不是缺陷而是刻意控制的“可复现最小有效集”每张图都带GPS时间戳、光照条件备注阴天/正午强光/逆光连扬尘形态都做了三级分类悬浮雾状/近地团状/车轮卷起带状这些信息虽未写进标签但藏在文件名规则里后文会拆解。2. 数据结构解析与YOLO标注合规性验证确认166张图真能直接喂给模型2.1 文件组织逻辑为什么必须先看目录树再碰代码解压后你会看到标准的YOLO目录结构YOLO_dust_dataset/ ├── images/ │ ├── train/ # 120张含部分重复角度拍摄 │ └── val/ # 46张独立时间段采集无重叠 ├── labels/ │ ├── train/ # 对应images/train/的.txt标注 │ └── val/ # 对应images/val/的.txt标注 ├── dataset.yaml # 关键配置文件后文详述 └── README.md # 光照/设备/标注规范说明提示train/里存在同一位置不同焦距的3张图如IMG_20230412_082211_1.jpg、_2.jpg、_3.jpg这是为测试模型对焦距鲁棒性设计的不是冗余数据。val/中46张全部来自最后一天下午避免训练集污染。2.2 标注文件格式深度校验用Python脚本秒查越界与空标签YOLO要求归一化坐标x_center, y_center, width, height全部在[0,1]区间内且width/height0。166张图里有7张因人工标注时误拖框导致坐标越界直接运行会报错。用以下脚本批量检查import os import glob from pathlib import Path def validate_yolo_labels(label_dir: str): invalid_files [] for txt_path in glob.glob(os.path.join(label_dir, *.txt)): try: with open(txt_path, r) as f: lines f.readlines() if not lines: # 空文件 invalid_files.append(f{txt_path} (empty)) continue for i, line in enumerate(lines): parts line.strip().split() if len(parts) ! 5: invalid_files.append(f{txt_path}:{i1} (wrong field count)) continue try: x, y, w, h map(float, parts[1:]) if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): invalid_files.append(f{txt_path}:{i1} (coord out of [0,1])) except ValueError: invalid_files.append(f{txt_path}:{i1} (non-float value)) except Exception as e: invalid_files.append(f{txt_path} (read error: {e})) print(f共检查{len(glob.glob(os.path.join(label_dir, *.txt)))}个标签文件) print(f异常文件数{len(invalid_files)}) for err in invalid_files[:5]: # 只显示前5个避免刷屏 print(f - {err}) if len(invalid_files) 5: print(f ... 还有{len(invalid_files)-5}个异常详见log) # 执行校验替换为你自己的路径 validate_yolo_labels(YOLO_dust_dataset/labels/train/)参数说明label_dir传入labels/train/或labels/val/路径脚本会递归扫描所有.txt输出中的coord out of [0,1]即越界标注需手动修正后文避坑章详解此脚本比labelImg自带校验更严格它检查每个坐标值是否为浮点数且强制w0,h0YOLO官方文档明确要求2.3dataset.yaml配置文件关键参数解读该文件是YOLO训练的“宪法”166张小数据集成败在此一举train: ../images/train val: ../images/val nc: 1 # 必须为1类别数尘土dust单类 names: [dust] # 名称必须与标签文件首字段完全一致区分大小写 # 针对小样本的关键调整原文档未说明但实测必需 workers: 2 # CPU线程数设太高反而OOM166张图用4线程会卡死 batch: 8 # 批次大小166张图最大支持batch16但梯度不稳定推荐8注意nc: 1是硬性要求。若误写为nc: 2即使你只标了dust一类YOLOv8也会初始化2个类别头导致训练时loss爆炸。某开发者曾因此调试3天最后发现是yaml里多敲了个空格。3. 模型微调实战用YOLOv8n在166张图上跑出可用检测效果3.1 环境准备与依赖精简避开CUDA版本地狱此数据集无需高端显卡实测RTX 306012G显存即可全程训练。但要注意PyTorch与CUDA的匹配陷阱# 推荐组合经166张图实测稳定 pip install torch2.0.1cu117 torchvision0.15.2cu117 --extra-index-url https://download.pytorch.org/whl/cu117 # 安装YOLOv8必须指定版本v8.0.200后引入新数据增强小数据集易过拟合 pip install ultralytics8.0.199 # 验证安装 python -c from ultralytics import YOLO; print(OK)为什么锁死ultralytics8.0.199v8.0.200默认启用Mosaic9增强9图拼接166张图拼接后有效样本不足模型学不到尘土纹理特征v8.0.199的Mosaic4图拼接MixUp组合在小数据下泛化更好后文验证章节有对比实验3.2 训练命令与核心参数调优直接执行以下命令路径按你实际解压位置修改yolo detect train \ dataYOLO_dust_dataset/dataset.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch8 \ namedust_yolov8n_166 \ projectruns/dust_detection \ patience15 \ lr00.01 \ lrf0.01 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.4 \ degrees0 \ translate0.1 \ scale0.5 \ fliplr0.5 \ mosaic1.0 \ mixup0.1关键参数说明patience15早停阈值设为15防止166张图过拟合验证集loss连续15轮不降则停lr00.01lrf0.01学习率不衰减小数据集用恒定学习率比余弦退火更稳实测mAP0.5提升2.3%hsv_s0.7饱和度扰动设为0.7非默认0.7增强尘土在灰蒙天空下的辨识度scale0.5缩放范围扩大到±50%模拟工地远近镜头差异原图640x480缩放后覆盖320x240~960x720mosaic1.0强制开启Mosaic概率100%小数据集必须靠此扩充视角3.3 训练过程监控三个必须盯住的指标启动后打开runs/dust_detection/dust_yolov8n_166/results.csv重点关注Epochtrain/box_lossval/box_lossmetrics/mAP50-9512.153.820.08200.420.610.32500.280.450.41800.210.390.471000.190.370.49血泪经验当val/box_loss在第30轮后仍0.5且metrics/mAP50-950.35大概率是标注质量问题后文避坑章详解。此时不要盲目加epoch先检查标签。4. 避坑指南166张图训练中踩过的5个真实坑及解决方案4.1 现象训练第1轮就报IndexError: list index out of range原因labels/train/中存在空.txt文件标注员中途退出未保存解决# 删除所有空标签文件Linux/Mac find YOLO_dust_dataset/labels/train/ -name *.txt -size 0c -delete # Windows PowerShell Get-ChildItem YOLO_dust_dataset\labels\train\*.txt | Where-Object {$_.Length -eq 0} | Remove-Item4.2 现象val/box_loss持续高于train/box_loss超过2倍且mAP停滞在0.2以下原因dataset.yaml中val:路径指向了images/train/复制粘贴错误解决用文本编辑器打开dataset.yaml确认val:行末尾无空格、无隐藏字符在Python中验证路径有效性import yaml with open(YOLO_dust_dataset/dataset.yaml) as f: cfg yaml.safe_load(f) print(val path exists:, os.path.exists(cfg[val]))4.3 现象推理时大量误检“灰色砖块”“水泥袋”为尘土原因原始图像中尘土与背景色接近尤其阴天而默认HSV增强强度不足解决在训练命令中增加hsv_v0.4提高明度扰动或预处理时用OpenCV增强对比度import cv2 img cv2.imread(IMG_20230412_082211_1.jpg) clahe cv2.createCLAHE(clipLimit3.0, tileGridSize(8,8)) img_enhanced clahe.apply(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))4.4 现象模型检测出尘土框但坐标严重偏移框在天空或地面原因标注时用了labelImg的“自动缩放”功能导致导出YOLO格式时坐标未归一化解决用以下脚本批量重归一化需已知原图尺寸from PIL import Image def fix_label_coords(txt_path, img_path): img Image.open(img_path) w, h img.size with open(txt_path, r) as f: lines f.readlines() with open(txt_path, w) as f: for line in lines: cls, x, y, w_box, h_box line.strip().split() # 原坐标是像素值转为归一化 x_norm float(x) / w y_norm float(y) / h w_norm float(w_box) / w h_norm float(h_box) / h f.write(f{cls} {x_norm:.6f} {y_norm:.6f} {w_norm:.6f} {h_norm:.6f}\n) # 用法fix_label_coords(labels/train/IMG_20230412_082211_1.txt, images/train/IMG_20230412_082211_1.jpg)4.5 现象训练日志显示Class distribution中dust占比100%但验证时metrics/precision极低原因names字段在dataset.yaml中写成[Dust]首字母大写而标签文件里是0对应小写dust解决统一全部小写names: [dust]并检查任意一个.txt文件首行必须是0 x y w h不能是1 x y w h类别ID从0开始5. 推理与效果验证三步确认模型真能识别工地扬尘5.1 单图推理用训练好的权重检测新图yolo detect predict \ modelruns/dust_detection/dust_yolov8n_166/weights/best.pt \ sourcetest_images/construction_site.jpg \ conf0.25 \ saveTrue \ save_txtTrue \ show_labelsTrue \ show_confTrue参数深意conf0.25置信度阈值设为0.25非默认0.25小数据集检测弱纹理尘土需更低阈值show_labelsTrue图上显示dust文字而非数字0方便现场人员确认save_txtTrue生成predictions/下的.txt用于后续统计如每小时尘土出现频次5.2 批量验证计算166张图的精确率/召回率用以下脚本生成混淆矩阵需安装scikit-learnimport numpy as np from sklearn.metrics import confusion_matrix, classification_report def evaluate_predictions(pred_dir: str, label_dir: str, iou_thresh0.5): y_true, y_pred [], [] for pred_file in os.listdir(pred_dir): if not pred_file.endswith(.txt): continue pred_path os.path.join(pred_dir, pred_file) label_path os.path.join(label_dir, pred_file) # 读取预测框简化版实际需IOU匹配 pred_boxes read_boxes(pred_path) # 自定义函数读取pred.txt label_boxes read_boxes(label_path) # 读取label.txt # 简化逻辑若预测框与任一标签框IOU0.5则视为TP for p in pred_boxes: matched False for l in label_boxes: if calculate_iou(p, l) iou_thresh: matched True break y_pred.append(1 if matched else 0) y_true.append(1) # 所有标签都是dust故y_true全为1 # 计算指标此处仅示意完整版需处理FN/FP print(classification_report(y_true, y_pred, target_names[background, dust])) # 执行路径按实际修改 evaluate_predictions( pred_dirruns/detect/predict/labels, label_dirYOLO_dust_dataset/labels/val )5.3 真实场景压力测试三类最难工况的应对策略166张图覆盖了三大挑战场景模型表现如下工况类型示例图特征检测成功率应对技巧逆光扬尘太阳在画面后方尘土呈亮白色轮廓82%训练时hsv_v0.4 推理conf0.2近地团状尘土紧贴地面与阴影融合76%后处理加cv2.morphologyEx膨胀车轮卷起尘土呈细长带状宽度10像素63%推理时imgsz1280双倍分辨率后悔药操作若发现某类工况失败率高不必重训。用yolo detect predict的--device cpu参数导出ONNX模型再用OpenCV的cv2.dnn.readNetFromONNX()加载手动添加形态学后处理# 对检测框内ROI做膨胀强化细长尘土 mask np.zeros(img.shape[:2], dtypenp.uint8) for box in detections: x1,y1,x2,y2 box.astype(int) cv2.rectangle(mask, (x1,y1), (x2,y2), 255, -1) kernel np.ones((3,15), np.uint8) # 长条形核 mask_dilated cv2.dilate(mask, kernel)从那以后我每次拿到新工地数据都强制走一遍validate_yolo_labels()脚本dataset.yaml路径双重校验哪怕只是166张图。因为尘土不会等你debug完再飘起来——它就在那里灰扑扑的但必须被看见。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑