简介这份资源面向计算机视觉方向的学习者与算法工程师提供雾天场景下的行人、车辆目标检测数据集可直接用于YOLOv5训练省去自行采集与标注的成本。数据按YOLOv5标准目录组织图像为400至1000分辨率的RGB图片覆盖雾天马路上的常见车辆与人群共划分人、轿车、公交车、自行车、摩托车5个类别。包内共2000个文件以1999个txt标注文件与1个Python可视化脚本为主压缩包约123.5MB其中训练集含4320张图片及对应标签验证集含100张图片及对应标签并附类别说明文件。提供的show.py可随机读取一张图片绘制边界框并保存到当前目录无需修改即可运行便于快速核验标注质量。目前已有405人学习下载适合需要雾天检测数据、想验证模型鲁棒性或开展相关课题研究的中高级读者参考使用。1. 雾天行人车辆检测5 类标注的 YOLOV5 数据集到底怎么用雾天场景下的目标检测是自动驾驶和安防监控里公认的硬骨头。能见度下降、对比度衰减、目标边缘模糊模型在正常天气下 mAP 能跑到 0.85一到雾天可能直接掉到 0.5 以下。这个数据集针对的正是这个痛点雾天下的行人、车辆目标检测5 个类别YOLOV5 目录格式。它解决的不是“有没有数据”的问题而是“雾天数据怎么组织成 YOLOV5 能直接吃的格式、5 个类别怎么定义、训练时超参数怎么调”的问题。适合两类人一是手上有雾天图像但不知道怎么转成 YOLO 格式的工程师二是想用 YOLOV5 做恶劣天气检测但找不到合适数据集的研究者。下面从目录结构、标注转换、训练配置到踩坑排查一步步拆开讲。2. YOLOV5 目录格式拆解images 和 labels 到底怎么放2.1 标准目录结构与 5 类别定义YOLOV5 的数据集目录不是随便放几个文件夹就行的。它有一套约定俗成的结构训练脚本train.py会按这个结构去索引图像和标签。常见做法是长这样dataset/ ├── images/ │ ├── train/ │ │ ├── fog_0001.jpg │ │ ├── fog_0002.jpg │ │ └── ... │ ├── val/ │ │ ├── fog_1001.jpg │ │ └── ... │ └── test/ # 可选 │ └── ... ├── labels/ │ ├── train/ │ │ ├── fog_0001.txt │ │ ├── fog_0002.txt │ │ └── ... │ ├── val/ │ │ ├── fog_1001.txt │ │ └── ... │ └── test/ │ └── ... └── data.yaml关键点images/train/下的fog_0001.jpg对应labels/train/fog_0001.txt文件名必须一模一样只是扩展名不同。YOLOV5 在加载时会自动做这个映射如果文件名对不上训练时就会报“找不到标签”或者更隐蔽地跳过该样本。5 个类别通常是雾天场景下最常见的person、car、bus、truck、bicycle。具体类别名以data.yaml里的names列表为准顺序决定了标签文件里class_id的含义。比如names: [person, car, bus, truck, bicycle]那么标签里的0就是 person1是 car以此类推。这个顺序一旦定了就不能改改了就得重新映射所有标签。data.yaml的内容一般是这样path: /home/user/dataset # 数据集根目录 train: images/train # 相对 path 的训练图像路径 val: images/val # 相对 path 的验证图像路径 test: images/test # 可选 nc: 5 # 类别数 names: [person, car, bus, truck, bicycle]path可以用绝对路径也可以用相对路径。我一般写绝对路径避免训练时因为工作目录不同而找不到数据。train和val是相对于path的路径不是相对于当前工作目录。这一点新手很容易搞混结果训练脚本报“No images found”。2.2 标签文件格式一行一个目标归一化坐标YOLO 格式的标签文件是纯文本每行代表一个目标格式为class_id x_center y_center width height全部是归一化到 0~1 的浮点数。x_center和y_center是目标框中心点相对于图像宽高的比例width和height是目标框宽高相对于图像宽高的比例。举个例子一张 1920×1080 的雾天图像里有一个人站在画面左侧中间位置框的像素坐标是(400, 500)到(500, 800)那么中心点像素(450, 650)宽高像素100, 300归一化后x_center 450/1920 ≈ 0.2344y_center 650/1080 ≈ 0.6019width 100/1920 ≈ 0.0521height 300/1080 ≈ 0.2778标签行就是0 0.2344 0.6019 0.0521 0.2778如果原始标注是 VOC 的 XML 格式或者 COCO 的 JSON 格式需要写脚本转换。下面是一个 VOC 转 YOLO 的 Python 脚本片段import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, img_w, img_h, class_list): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_list: continue cls_id class_list.index(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) # 归一化并计算中心点、宽高 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) return lines逻辑说明先解析 XML拿到每个目标的类别名和边界框像素坐标。class_list是类别名列表顺序必须和data.yaml里的names一致。归一化时除以图像宽高保留 6 位小数足够。如果某个类别不在class_list里直接跳过避免引入未知类别导致训练报错。参数说明img_w和img_h必须从对应图像读取不能硬编码。常见做法是用 OpenCV 或 PIL 读一下图像尺寸。如果图像尺寸不一致每张图都要单独读。class_list建议从data.yaml里读保证一致。注意归一化后的坐标如果出现负数或大于 1说明标注框超出了图像边界。YOLOV5 默认会忽略这类框但最好在转换时做裁剪把坐标限制在 [0,1] 范围内。3. 用 YOLOV5 训练雾天数据集从环境到超参数3.1 环境配置与最小训练命令YOLOV5 的环境配置不算复杂但版本兼容性是个玄学。我一般用 conda 建一个干净环境conda create -n yolov5_fog python3.8 conda activate yolov5_fog git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txtPython 3.8 是比较稳的版本3.9 以上有时会和某些 torch 版本冲突。requirements.txt里会装 torch、torchvision、opencv-python 等。如果机器有 CUDA建议手动装对应版本的 torch比如pip install torch1.12.1cu113 torchvision0.13.1cu113 --extra-index-url https://download.pytorch.org/whl/cu113。CPU 训练也能跑但雾天数据集图像分辨率通常不低CPU 会慢到怀疑人生。最小训练命令python train.py --data data/fog_data.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --name fog_exp参数说明--data指向data.yaml的路径注意不是数据集根目录是那个 yaml 文件。--weights是预训练权重yolov5s.pt是最小的模型适合快速验证。--img 640是输入图像尺寸雾天小目标多的话可以调到 1280但显存占用会翻倍。--batch 16是批次大小显存不够就降到 8 或 4。--epochs 100是训练轮数雾天数据集如果只有几千张100 轮够了数据量大可以加到 300。--name是实验名称结果会保存在runs/train/fog_exp/下。训练开始后控制台会输出每轮的 loss、precision、recall、mAP0.5 等指标。重点看mAP0.5和mAP0.5:0.95。雾天场景下mAP0.5能到 0.6 以上就算不错了因为雾遮挡导致部分目标确实难以辨认。3.2 雾天场景的超参数怎么调YOLOV5 的超参数在data/hyp.scratch.yaml里训练时可以用--hyp指定自定义文件。雾天场景有几个参数值得调参数默认值雾天建议值原因lr00.010.005雾天数据噪声大学习率低一点更稳lrf0.010.02最终学习率略高避免后期震荡momentum0.9370.9略降减少对模糊目标的过拟合weight_decay0.00050.001增大正则化抑制雾天噪声mosaic1.00.5马赛克增强会加剧雾的混乱降低概率mixup0.00.1轻微 mixup 有助于泛化hsv_v0.40.6雾天亮度变化大增强亮度扰动hsv_s0.70.5饱和度扰动降低雾天本身饱和度低这些值不是拍脑袋来的是我在几个雾天数据集上试出来的。mosaic调到 0.5 是因为雾天图像本身对比度低四张图拼在一起后目标更模糊模型很难学。hsv_v调高是因为雾的浓度变化会导致亮度剧烈波动增强这个扰动能让模型更鲁棒。另外雾天小目标多--img建议至少 640有条件上 1280。如果显存不够可以用--multi-scale做多尺度训练让模型适应不同距离的目标。提示训练前先用python train.py --data ... --weights ... --img 640 --batch 16 --epochs 1跑一轮确认数据加载没问题。如果报错“No labels found”八成是data.yaml里的路径写错了或者标签文件名和图像文件名不匹配。4. 雾天数据集训练的避坑与排查4.1 标签文件里的隐藏坑现象训练时 loss 一直不降mAP 始终在 0.01 左右。原因标签文件里的坐标没有归一化还是像素值。YOLOV5 期望的是 0~1 的浮点数如果传了像素值模型会认为目标框巨大无比完全学不到东西。解决检查标签文件随便打开一个.txt看数值是否都在 0~1 之间。如果有大于 1 的数说明没归一化用前面的转换脚本重新生成。现象训练正常但验证时某些类别 mAP 为 0。原因data.yaml里的names顺序和标签文件里的class_id不对应。比如names里person是 0但标签里person写成了 1。解决统计标签文件里每个class_id出现的次数和names列表对照。写个脚本快速统计import os from collections import Counter label_dir dataset/labels/train counter Counter() for f in os.listdir(label_dir): if f.endswith(.txt): with open(os.path.join(label_dir, f)) as file: for line in file: cls_id int(line.split()[0]) counter[cls_id] 1 print(counter)如果某个class_id出现次数为 0说明该类没有样本或者标签写错了。4.2 图像与标签不匹配的排查现象训练时提示“ignoring corrupted image”或“missing labels”。原因图像文件损坏或者图像和标签文件名不一致。YOLOV5 会跳过这些样本但如果跳过的太多训练集就废了。解决写个脚本检查图像和标签的配对情况import os img_dir dataset/images/train label_dir dataset/labels/train img_files set(os.path.splitext(f)[0] for f in os.listdir(img_dir)) label_files set(os.path.splitext(f)[0] for f in os.listdir(label_dir)) missing_labels img_files - label_files missing_images label_files - img_files print(f有图无标签: {len(missing_labels)}) print(f有标签无图: {len(missing_images)})如果missing_labels很多说明标签没生成全如果missing_images多说明标签文件多余了。两种情况都要清理保证一一对应。现象训练时显存溢出CUDA out of memory。原因--img或--batch太大或者图像分辨率本身很高。解决先降--batch到 8 或 4再降--img到 416。如果还不行检查是否有异常大的图像比如 4K 图可以统一缩放到 1280 宽。4.3 雾天特有的过拟合问题现象训练集 mAP 很高验证集 mAP 很低差距超过 0.3。原因雾天数据集如果场景单一比如都是同一条路模型会记住背景而不是目标。解决增加数据增强尤其是hsv_v和hsv_s模拟不同雾浓度。另外可以加--multi-scale让模型适应不同尺度。如果数据量太少考虑用预训练权重冻结主干网络只训练检测头。注意雾天数据集的验证集一定要包含不同雾浓度的图像不能全是一种浓度。否则验证集 mAP 没有参考价值。5. 雾天检测的进阶技巧从推理到部署训练完模型下一步是推理和部署。YOLOV5 提供了detect.py做推理python detect.py --weights runs/train/fog_exp/weights/best.pt --source dataset/images/test --img 640 --conf 0.25 --iou 0.45--conf 0.25是置信度阈值雾天建议调到 0.3 以上因为模糊目标容易产生低置信度的误检。--iou 0.45是 NMS 的 IoU 阈值雾天目标重叠多可以适当降到 0.4。如果要在树莓派 5 上部署需要把模型转成 ONNX 或 TensorRT。ONNX 转换python export.py --weights runs/train/fog_exp/weights/best.pt --include onnx --img 640转换后可以用 ONNX Runtime 推理。树莓派 5 的 CPU 跑 YOLOV5s 大概 2~3 FPS如果要用 GPU得用 TensorRT但树莓派 5 的 GPU 支持有限实际提升不大。更现实的做法是用 YOLOV5nnano 版本牺牲一点精度换速度。验证模型是否真的学到了雾天特征可以做一个简单的消融把验证集图像加不同浓度的雾看 mAP 下降曲线。如果下降平缓说明模型鲁棒如果断崖式下跌说明训练时雾的多样性不够。我一般会保留一个“浓雾测试集”专门用来评估极端情况。最后说个血泪经验雾天数据集的标注质量比数量重要。我见过一个数据集标注框把雾也框进去了模型学出来的框比实际目标大一圈。标注时一定要贴着目标边缘雾遮挡的部分不要框。另外训练前用python utils/plots.py可视化一下标签确认框的位置和类别都对。这个习惯帮我省了至少两周的返工时间。希望帮到你。本文还有配套的精品资源点击获取