YOLOV5雾天行人车辆目标检测数据集解析与训练实战
2026/9/14 14:14:14 网站建设 项目流程

简介:这份雾天下的行人车辆目标检测数据集,面向需要训练YOLOv5模型的研究者与开发者,解决雾天场景下标准格式数据不足、标注繁琐的问题。数据严格按YOLOV5目录结构组织,训练集与验证集分开存放,图像为分辨率400至1000的RGB图片,类别涵盖行人、轿车、公交车、自行车、摩托车共五类。除图像外,每张图均配有同名的txt标注文件,格式为标准YOLO坐标信息,可直接投入训练流程。下载包共两千个文件,以txt标注文件为主体,另附一个可视化show.py脚本,压缩包总体约123.5MB;该脚本无需任何修改,传入一张图片即可绘制边界框并保存,极大方便校对标签质量。数据集覆盖雾天马路上常见的车辆与人群,可用于算法复现、模型调优、毕业设计或竞赛练手,已有405人学习,适合目标检测入门及进阶者直接使用。

1. 雾天行人车辆目标检测,为什么要一个现成的YOLOV5格式数据集

雾天行人和车辆的目标检测,最缺的不是模型结构,而是标注质量可靠的数据集。雾天场景的检测需求往往出现在交通监控里,而公开数据集多是晴天,直接训练好模型到雾天工地,mAP容易掉一半。这个数据集把4320张训练图、100张验证图按YOLOV5的目录约定放好,五个类别:人、轿车、公交车、自行车、摩托车,图片分辨率400-1000,大小130MB,拉下来就能训练。对正在做YOLOV5落地的人来说,它省掉两件事:一是自己爬雾天图片再清洗标注,二是把VOC或COCO格式转成YOLO的txt。适合已经在跑YOLOV5的工程师,也适合刚入门做目标检测的学生拿去复现整个训练流程。下面从目录结构开始拆,看这个数据集到底准备到什么程度。

2. YOLOV5目录结构解析与标签txt编码:雾天5类数据集怎么组织

2.1 一眼看懂YOLOV5数据集的文件夹约定

YOLOV5的数据集并不强制要求统一根目录,只要把图片和标签分别放在 images 和 labels 下,并在 dataset.yaml 里指定路径即可。标准约定是:

  • datasets/images/train/xxxxxxxx.jpg
  • datasets/images/val/xxxxxxxx.jpg
  • datasets/labels/train/xxxxxxxx.txt
  • datasets/labels/val/xxxxxxxx.txt

图片和标签通过同名前缀关联。数据集作者保留了原始文件名,前缀类似QC_Bing_515HEB_Bing_027BJ_Bing_461,这些字号对应不同采集批次,训练时不影响读取。下表列出该数据集的目录结构:

子路径样本数内容
images/train/4320雾天场景RGB图片,分辨率400-1000
labels/train/4320同名前缀的txt标注文件
images/val/100验证集图片
labels/val/100验证集txt标注

注意,作者在根目录附了几份txt文件,比如GSGL_Baidu_896.txtHF_Google_283.txt,这类文件通常是网络采集时的图源清单,记录每张图来自哪个搜索渠道,方便追溯,但训练不需要它们。YOLOV5读取数据时只关心imageslabels目录。

2.2 标签txt的五个数字:类别、归一化中心和宽高

YOLO格式的txt每行描述一个目标,共5个字段:

class_id x_center y_center width height

例如下面的内容来自某个训练标签:

3 0.713564 0.417199 0.121696 0.066489 0 0.497645 0.734129 0.091076 0.182567

class_id 从0开始,对应数据集的5类:

class_id类别
0
1轿车
2公交车
3自行车
4摩托车

后4个参数都除以了图片自身的宽高,因此无论原图是400还是1000像素,都能共用同一套标注。读取时只要用原图尺寸乘回去,才能得到边界框像素坐标。这个数据集的边长在400-1000之间,宽高比不固定,所以标签里宽度和高度独立,不会互相限制。常见的错误是直接把归一化坐标当像素坐标画框,结果框全挤在左上角;改成乘以img.shape[1]img.shape[0]就好。

2.3 训练与验证划分:4320和100是怎么配比的

4320张训练图和100张验证图放在不同目录,验证集只占约2.3%,对单纯测试来说够用;但如果要拿来做模型选型或调超参数,最好再从中切一部分出来做测试。原结构里没有 test 目录,这也是大多数小型数据集的特点。拿到压缩包后,第一件事是统计文件数,并检查每个图片是否有对应txt。推荐用下面的Python脚本:

import os from pathlib import Path from collections import Counter img_dir = Path("datasets/images/train") label_dir = Path("datasets/labels/train") exts = {".jpg", ".jpeg", ".png", ".bmp"} missing_label = [] class_counter = Counter() for img_path in sorted(img_dir.iterdir()): if img_path.suffix.lower() not in exts: continue label_path = label_dir / (img_path.stem + ".txt") if not label_path.exists(): missing_label.append(img_path.name) continue for line in label_path.read_text().strip().splitlines(): class_id = int(line.split()[0]) class_counter[class_id] += 1 print("missing label count:", len(missing_label)) print("class distribution:", class_counter.most_common())

这段代码遍历训练图片,检查同名txt是否存在,同时统计每个类别的标注框数量。参数说明:img_dirlabel_dir要改成数据实际路径;exts定义可识别图片后缀;class_counter用于统计所有目标框的类别频次。如果日志里出现大量缺失标签,通常两个原因:一是下载过程中丢失文件,二是有人用txt后缀写了别的格式。最直接的办法是重新解压,或向发布方要对应批次的清单。

2.4 文件名前缀与采集场景的关联

从输入文件可以看到QC_Bing_515HEB_Bing_027BJ_Bing_461这类命名,前两位字母是城市缩写,中段是搜索来源,数字是采集顺序号。这种命名方式在自建数据集中很常见,方便按地域或渠道做子集评估。训练时文件名不参与计算,YOLOV5只靠 stem 匹配图片和标签。但如果你后续想做极端场景测试,可以按前缀提取子集,比如只看BJ_*的雾天效果,能更快暴露地域性分布差异。

3. show.py可视化原理与雾天场景下的标注核对

3.1 一段等价的可视化循环

作者提供的show.py可以在不修改条件下随机读取一张图片并绘制边界框,说明脚本内部完成了以下事情:读取图片路径、读取同名txt、解析每一行、用cv2画矩形和标签。直接复制作者的脚本即可,但如果想指定某一张图查看,或者想改框颜色,可以自己写一段等价实现:

import cv2 import numpy as np from pathlib import Path classes = ["person", "car", "bus", "bicycle", "motorbike"] colors = [(0, 255, 0), (255, 0, 0), (0, 0, 255), (255, 255, 0), (0, 255, 255)] def draw_yolo_label(img_path, label_path, output_path): img = cv2.imread(str(img_path)) h, w = img.shape[:2] with open(label_path, "r", encoding="utf-8") as f: for line in f: parts = line.strip().split() if len(parts) != 5: continue cls_id = int(parts[0]) x_c, y_c, bw, bh = map(float, parts[1:]) x1 = int((x_c - bw / 2) * w) y1 = int((y_c - bh / 2) * h) x2 = int((x_c + bw / 2) * w) y2 = int((y_c + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), colors[cls_id], 2) cv2.putText(img, classes[cls_id], (x1, max(0, y1 - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, colors[cls_id], 2) cv2.imwrite(str(output_path), img) print("saved to", output_path) draw_yolo_label("datasets/images/train/BJ_Bing_461.jpg", "datasets/labels/train/BJ_Bing_461.txt", "output.jpg")

代码说明:x_c/y_c/bw/bh是归一化坐标,这里乘以原图尺寸得到像素坐标。cls_id直接映射到类别列表,与2.2节的类别表保持一致。colors列表给出每个类别的BGR颜色,OpenCV中顺序是蓝绿红,注意红色在BGR里是(0,0,255)draw_yolo_label函数接收三个路径,输出绘制后的图片,不弹出GUI,适合在无桌面环境的服务器上运行。如果你的实际文件名不是BJ_Bing_461,替换成数据集中存在的图片即可。添加表格说明参数:

参数含义建议值
img_path输入图片路径数据集内任意jpg
label_path同名txt路径与图片stem一致
output_path绘制结果输出路径当前目录下可写路径

3.2 坐标越界与空标签两个坑

雾天图像边缘的行人经常不完整,标注框会有一部分超出图像边界。YOLO训练对超出边界的框一般能容忍,但可视化时会出现框画到画面四边之外的情况。show.py如果没做裁剪,输出图里看到边框贴边甚至超出,不代表数据错误。更好的做法是给坐标加边界限制:

x1 = max(0, min(w, int((x_c - bw / 2) * w))) y1 = max(0, min(h, int((y_c - bh / 2) * h)))

另一个常见异常是空txt,即图片存在但标签无内容。这种样本相当于纯负样本,在YOLOV5中会直接跳过损失计算,不报错,但会浪费一次迭代。可视化脚本遇到空txt时不会画出任何框,需要单独统计。空标签多出现在雾很浓、确实没有可标注目标的图上,保留它们反而有利于抑制误检。

3.3 重点核对自行车与摩托车的类别混淆

在低可见度下,自行车和摩托车的轮廓接近,如果标注时快速框选,类别错误会集中在bicyclemotorbike这一对。建议用下面的抽样检查脚本,自动找出类别分布异常的图:

from pathlib import Path import random label_dir = Path("datasets/labels/val") for txt in random.sample(list(label_dir.glob("*.txt")), 10): rows = [l.strip().split() for l in txt.read_text().strip().splitlines() if l.strip()] cls_ids = [int(r[0]) for r in rows] if (3 in cls_ids) and (4 in cls_ids): print(txt.name, cls_ids)

这段代码在验证集里随机抽10个标签,如果同一张图同时包含自行车(3)和摩托车(4),就打印出来,便于重点检查这类容易混淆的样本。参数10表示抽样数量,可以调成20或50。运行时不会修改数据,只作为人工复核的筛选工具。实际使用中往往抽5次就能遇到一辆远处摩托车,这类样本是训练mAP上不去的主要原因之一。

4. 雾天图像退化特性与YOLOV5训练参数调整

4.1 雾天图像为什么难检:大气散射模型

雾天图像可以看作清晰图经过大气散射后的结果:

I(x) = J(x) * t(x) + A * (1 - t(x))

其中J是干净图,t是介质透射率,A是大气光。t(x)随距离衰减,远处目标的对比度和饱和度都下降,所以在YOLOV5的卷积层看来,远处的车和背景纹理变得越来越像。该数据集有5类目标,其中行人和摩托车属于小目标,在雾天中轮廓更模糊,因此训练难度主要在低对比度下的小目标召回。同一张图里,近处轿车的检测难度通常明显小于远端的行人,这是雾天场景的自然属性。

4.2 要不要在训练前做去雾增强

直接在数据集上跑YOLOV5通常能得到能用的模型,但如果你发现车辆余影多、行人漏检多,可以考虑在训练时加入去雾预处理。常见做法是使用OpenCV的CLAHE作为Mosaic增强的一部分,而不是先离线去雾再训练。离线去雾会让模型只见过增强后的图,部署时遇到自然雾天仍然退化;在线增强则让模型同时见过有雾和无雾版本,泛化更好。可以先跑一个对比实验:

python train.py --data fog.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --augment

说明:--augment打开YOLOV5的在线数据增强,包括HSV、平移、翻转等。若要在增强里加CLAHE,需要改数据加载器的代码,工作量不大但要测试前后mAP。我的经验是先不加任何去雾,用原图画一个baseline,再对比增强后的效果。不要一开始就引入复杂的去雾网络,因为130MB的数据量不足以端到端学习一张雾天退化图。

4.3 anchor尺寸调整:从数据集中重新聚类

YOLOV5的默认anchor按COCO的物体尺寸设计,对正常天气的车辆行人比较合适,但雾天图片距离远,目标更小,默认anchor可能覆盖不了小目标。训练时建议先让YOLOV5自动聚类。第一次运行时,YOLOV5会对data.yaml里的训练集图片做K-Means,并在日志里打印类似AutoAnchor: 5.98 anchors/target, 0.32 Best Possible Recall的信息。快速跑一个epoch即可看到:

python train.py --data fog.yaml --img 640 --batch-size 16 --epochs 1

上面的命令没有显式传--weights,会使用默认预处理权重并触发autoanchor计算。如果Best Possible Recall低于0.98,需要在data.yaml中覆盖anchors字段,向小尺寸方向调整,因为雾天场景中小目标占比更高。我的建议是先用默认结果跑完整实验,再根据混淆矩阵中person的漏检率决定是否改anchor,不必上来就调。

4.4 雾天数据集的超参数倾向

训练时几个超参数值得单独调:

  • --img:输入尺寸不要定太低。图片分辨率在400-1000,如果训练用416会损失原本就模糊的细节,建议用640。
  • --batch-size:130MB数据量,16或32都可行。显存不够就降batch,不用依赖梯度累积。
  • --hyp:默认hyp.scratch-low.yaml适合中低数据量,不要上来用hyp.scratch-high.yaml,小数据容易过拟合。

下面是我训练这类雾天数据常用的data.yaml:

train: datasets/images/train val: datasets/images/val nc: 5 names: ['person', 'car', 'bus', 'bicycle', 'motorbike']

使用这个文件时,YOLOV5会直接从指定目录读取图片和标签,不需要把图片文件拷贝到YOLOV5项目里。注意trainval要用绝对路径或相对整个工作目录的路径,否则会报错"No labels in ..."。

超参数推荐值说明
img640保留雾天细节,避免丢失小目标
batch-size16针对130MB数据量的均衡选择
hyphyp.scratch-low.yaml小数据防过拟合

5. 从出生到部署:一次完整的雾天目标检测训练验证

5.1 跑通训练并保存最优权重

假设已经把数据集解压到/datasets/foggy,将上面的data.yaml保存为fog.yaml,进入YOLOV5官方仓库目录,执行:

python train.py --data fog.yaml --weights yolov5s.pt --img 640 --batch-size 16 --epochs 150 --cache

参数说明:--cache将图片提前加载到内存,加速小数据集的迭代;--weights yolov5s.pt从COCO预训练模型开始迁移学习,比从零训练收敛更快。训练结束后,runs/train/exp/weights/best.pt就是验证集上mAP最高的权重。训练日志里的P/R/mAP@.5可以快速判断雾天效果的底线。

5.2 用混淆矩阵定位雾天易错类别

训练后运行验证:

python val.py --data fog.yaml --weights runs/train/exp/weights/best.pt --task val --verbose

--verbose会打印每个类别的AP值。通常人(person)的AP会低于车辆,自行车和摩托车则互相渗漏。此时可以回看runs/train/exp/confusion_matrix.png,如果主要错误集中在bicycle ↔ motorbike,解决路径有两个:一是收集更多这两类的样本,二是把这两类合并成“两轮车”。从业务需求看,如果最终应用只需要区分机动车和非机动车,合并类别会明显提升整体mAP。

5.3 混合天气数据提高鲁棒性的做法

最后一个技巧是不要只拿这个雾天数据集单独训练。把正常天气的公开数据(如COCO中对应类别)按一定比例混入,构成混合数据集,能有效防止模型对雾天背景过度拟合。常见做法是在同一个data.yaml里写多个根路径:

train: - /datasets/foggy/images/train - /datasets/normal_weather/images/train

YOLOV5会把两个目录下的图片合并训练。混合后要注意类别总数保持5类,正常天气数据也要映射到相同的class_id。建议雾天数据与正常数据按1:2混合,这样模型既学到有雾条件下的特征,又不会丢失正常天气的泛化能力。验证仍用本数据集的100张雾天图,可以看到混合训练后雾天mAP通常会提高2到5个百分点,而且不会出现晴天场景掉点。具体的混合比例可以用5.2的--task val来做小规模对比。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询