YOLOV5雾天行人车辆目标检测:数据集目录规范与训练排错全解析

发布时间:2026/9/15 0:14:24
YOLOV5雾天行人车辆目标检测:数据集目录规范与训练排错全解析 简介这套目标检测数据集面向雾天场景下的行人、车辆识别任务按YOLOV5标准目录格式整理包含人、轿车、公交车、自行车、摩托车五类标注适合训练雾天环境下的目标检测模型也可用于自动驾驶、智能交通等相关研究。包体为zip压缩包共2000个文件其中1999个为txt标注文件含类别信息与边界框坐标另附1个可视化py脚本可直接运行并绘制检测框压缩包整体约123.5MB。数据划分为训练集4320张图片及对应标签、验证集100张图片及对应标签图像分辨率为400~1000的RGB图片无需额外处理即可直接接入YOLOv5训练流程。已有405人浏览学习适合需要雾天场景数据扩充或快速搭建检测实验的研究者与开发者使用配套脚本还能帮助直观核查标注效果。1. 雾天数据集是一道“送分题”但多数人栽在目录格式上做目标检测的都知道模型在晴天数据上跑得很好一到雨雾天气就掉点严重。雾天意味着低对比度、细节退化、远处目标基本模糊成一团行人车辆这类目标又往往是安全监控和自动驾驶的核心对象。所以“雾天下的行人、车辆目标检测数据集”看着是个细分方向其实是很多落地项目躲不开的硬需求。这类数据集通常按 YOLOV5 目录格式组织5 个类别常见的是行人、骑行者、小轿车、公交车、卡车之类。但很多人下载了数据集第一反应是打开图片看内容却忽略了目录结构、label 格式和 yaml 配置。实际上YOLOV5 对数据集的读取完全依赖目录规范和标签文件的数值格式一个文件夹放错位训练直接报错或者类别全乱。这篇文章就从目录格式说起把雾天数据集从准备到训练的完整链路走一遍新手能照做老手也能看看边界和坑。2. YOLOV5 目录格式拆解5 类别数据集必须严格遵守的结构2.1 标准目录树与 images/labels 的强对应关系拿到一个号称 YOLOV5 格式的数据集先不要急着训练第一步是核对目录结构。YOLOV5 官方数据集的通用布局长这样fog_dataset/ ├── images/ │ ├── train/ │ │ ├── fog_001.jpg │ │ └── ... │ ├── val/ │ │ └── ... │ └── test/ # 可选通常不配 test 也可以 └── labels/ ├── train/ │ ├── fog_001.txt │ └── ... ├── val/ │ └── ... └── test/每个 images 下的图片必须在 labels 下对应同名、同子目录的 txt 文件。比如images/train/fog_001.jpg对应labels/train/fog_001.txt。文件名完全一致只是扩展名不同。这个对应关系是硬性的YOLOV5 通过路径前缀替换来找 label如果缺少 label训练时会输出WARNING: No labels found然后跳过该图。雾天行人车辆数据集最常见的问题是有的人把原始图片和标注混放在一个大目录里或者 labels 里放了 PASCAL VOC 的 xml这都不是 YOLOV5 能直接吃的格式。5 类别数据集的目录规范没有特殊之处只是你需要在 yaml 里明确 5 个类别的顺序且这个顺序必须和所有 txt 标签里的类别编号保持一致。2.2 label txt 文件格式每行 5 个数的顺序不能错label txt 每一行代表一个目标格式是class_id x_center y_center width height注意是归一化坐标数值范围 0~1。计算方式是像素坐标除以图片宽高。例如图片宽 1280、高 720某个行人的边界框左上角 (320, 180)右下角 (640, 540)那么x_center (320 640) / 2 / 1280 0.375 y_center (180 540) / 2 / 720 0.5 width (640 - 320) / 1280 0.25 height (540 - 180) / 720 0.5对应行就是0 0.375 0.5 0.25 0.5。这里有两个高频错误一是类别 id 从 1 开始而不是从 0 开始二是忘记归一化直接写像素坐标。YOLOV5 训练时不会报错但 loss 会直接爆炸或 mAP 为 0。5 类别的数据集class_id 应该是 0 到 4顺序要和 data.yaml 的 names 列表一致。2.3 data.yaml 配置5 类别名称与路径在 YOLOV5 项目根目录下自己的数据集需要一个 yaml 文件典型写法# fog_pedestrian_vehicle.yaml train: ./fog_dataset/images/train val: ./fog_dataset/images/val nc: 5 names: [pedestrian, cyclist, car, bus, truck]注意 train 和 val 指向的是 images 目录不是根目录也不是 labels 目录。YOLOV5 会自动把images替换成labels去找标注文件。nc是类别数量必须和 names 长度一致。名称顺序一旦固定不要随意调整否则训练出来的权重应用到推断时类别会错位。这里我给一个快速校验脚本训练前先跑一遍能省大量排错时间import os from pathlib import Path img_dir Path(./fog_dataset/images/val) label_dir Path(./fog_dataset/labels/val) img_files list(img_dir.glob(*.jpg)) list(img_dir.glob(*.png)) missing [] for img in img_files: label label_dir / (img.stem .txt) if not label.exists(): missing.append(img.name) print(fTotal images: {len(img_files)}, missing labels: {len(missing)}) if missing: print(First 10 missing:, missing[:10])脚本遍历 val 图片检查同名 label 是否存在。正常情况 missing 应为空。如果漏标比较多建议直接补标或删除对应图片而不是让 YOLOV5 内部忽略它们。3. 雾天下行人车辆数据集的构建路径采集、合成与标注3.1 真实雾数据不足时的替代方案大气散射模型合成雾真实雾天图像的采集成本高、时段受限想凑齐 5 类目标且数量均衡非常难。业界常用做法是拿清晰图像做雾霾合成用的大气散射模型import cv2 import numpy as np def add_fog(image, beta0.6, A200): 大气散射模型合成雾 image: BGR 图像 beta: 雾浓度系数越大雾越浓 A: 大气光值0~255 h, w image.shape[:2] # 生成与图像同尺寸的深度图模拟远近景差异 depth np.ones((h, w), dtypenp.float32) depth[:, w//2:] 0.6 # 右半边距离更远雾更浓 depth cv2.GaussianBlur(depth, (31, 31), 0) t np.exp(-beta * depth) # 透射率 fog A * (1 - t) # 大气光散射项 fog_image image * t[:, :, np.newaxis] fog[:, :, np.newaxis] fog_image np.clip(fog_image, 0, 255).astype(np.uint8) return fog_image img cv2.imread(clear_car.jpg) fog add_fog(img, beta0.8, A180) cv2.imwrite(fog_car.jpg, fog)这个模型里beta决定雾气浓度A是环境光强度。调整 beta 可以从薄雾到浓雾丰富训练样本。注意这里的 depth 是随意模拟的实际使用时可以利用图像分割或深度估计得到更真实的深度关系。生成雾图后原图对应的 label 坐标完全不变可以直接复用这对 5 类别标注数据来说是低成本扩充样本的好办法。3.2 5 类别的标注规范边界框定义与漏标问题雾天数据集的目标往往边界模糊标注员容易漏标后续帧或只标亮处的目标。5 类别人车混合场景下我一般建议按以下规则执行pedestrian行人包含走路、站立、奔跑不含骑自行车的人。cyclist骑自行车/电动车的人人和车作为一个整体框。car小轿车、SUV、面包车这类小型乘用车。bus公交车、大巴。truck卡车、货车。边界框要框住目标的最小外接矩形雾中目标如果只露出一部分只要可辨识就标完全看不清的跳过。使用 LabelImg 或 LabelStudio 导出 YOLO 格式即可但导出时一定要确认类别 id 顺序。标注完成后要用脚本统计类别分布。3.3 类别不平衡的应对不只为指标更要为有效训练真实雾天场景里行人数量往往远少于车辆5 类样本极不均衡。先统计python -c from collections import Counter import glob c Counter() for f in glob.glob(fog_dataset/labels/train/*.txt): for line in open(f): c[int(line.split()[0])] 1 print(c) 这个命令统计 train 标签里每个类别的目标总数。如果 car 有 12000 个而 cyclist 只有 400 个有两种常用策略一是对 minority 类做 oversampling复制包含该类别的图片到训练目录二是设置 YOLOV5 的cls损失权重但这需要修改 loss 代码对新手不友好。最直接的是通过图像增强增加少数类样本例如对包含行人和骑手的图片做水平翻转、随机裁剪、亮度扰动这比数据本身更可控。4. 用 YOLOV5 训练雾天行人车辆模型命令、参数与排错4.1 环境配置与数据划分准备训练前先确认 YOLOV5 运行环境通常需要 PyTorch 和 CUDA。推荐用官方仓库git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt数据划分建议使用脚本按比例拆分手动拖拽容易出错。下面这个脚本把图片和标签同步划分到 train/valimport random from pathlib import Path import shutil random.seed(42) root Path(./fog_all) train_ratio 0.8 imgs list((root / images).glob(*.jpg)) random.shuffle(imgs) split int(len(imgs) * train_ratio) for i, img in enumerate(imgs): sub train if i split else val dest_img root / images / sub / img.name shutil.move(str(img), dest_img) src_label root / labels / (img.stem .txt) shutil.move(str(src_label), root / labels / sub / (img.stem .txt))脚本会创建 train/val 子目录并移动文件。注意root/images是原始图片目录移动后你需要保留 train/val 子目录结构。实际操作中我会先建好目录再移动生产级脚本还要处理重复同名文件这里不再展开。4.2 训练命令与最重要的 4 个参数一切就绪后最简单的训练命令python train.py --data fog_pedestrian_vehicle.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --name fog_run1各参数含义--data指定我们刚才写的 yaml。--weights使用 COCO 预训练权重迁移学习能显著加速收敛尤其适合雾天这种边缘场景。如果从零训练写--weights 。--img训练分辨率雾天小目标多建议 640 起步显存够用可以上 1280但会加倍耗时。--batch根据显卡显存调整报 CUDA out of memory 就减半。--epochs100 轮是常见设置模型在 60 轮后基本收敛。有一个容易被忽略的参数是--cache它可以把图片缓存到内存加快数据读取。当数据集数千张时效果明显python train.py --data fog_pedestrian_vehicle.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --cache4.3 训练失败的高频原因路径、隐藏字符与类别数根据维护数据集的经历最常遇到的报错是assert labels.shape[-1] 5, flabeled boxes should have 5 values, but got {labels.shape[-1]}这个断言出错九成原因是 label 文件每行不足 5 个数要么是漏了最后一个 height要么是行尾有多余空格导致读取异常。检查方式是写个小脚本逐个文件数行内容长度。另一个坑是下载的数据集在 Windows 下解压目录名带了隐藏空格或全角字符YOLOV5 在 Linux 服务器上跑时找不到路径。用ls -la仔细看目录名或用find . -name *.txt | head确认实际路径。还有类别数问题有的压缩包里 label 有 6 类虽然 yaml 只写了 5但 label 中出现了 id5训练过程不会在开头报错而是在计算 loss 时索引越界。所以训练前要检查所有 txt 中出现的最大类别 idpython -c import glob max_id 0 for f in glob.glob(fog_dataset/labels/train/*.txt): for line in open(f): if line.strip(): max_id max(max_id, int(line.split()[0])) print(max class id:, max_id) 如果输出的最大 id 大于等于 nc那么不是少了标注就是 nc 配错了。5. 在雾天验证集上评估模型并针对低对比度场景做最后调优5.1 用 val 数据算 mAP别只看最后的训练曲线训练结束后YOLOV5 会在runs/train/fog_run1下生成results.png里面包含 mAP 曲线。但训练曲线有波动可靠的做法是单独跑验证python val.py --data fog_pedestrian_vehicle.yaml --weights runs/train/fog_run1/weights/best.pt --img 640 --task val输出会给出各类别的 P、R、mAP0.5 和 mAP0.5:0.95。对于雾天场景行人这类小目标通常 mAP 偏低不要只看整体的 0.7 就觉得完事要逐类看。我把常见的评估表列一下类别样本数PRmAP0.5pedestrian12000.720.680.71cyclist4500.610.550.58car32000.850.820.86bus3000.880.900.91truck8000.800.790.81cyclist 低是常见的因为雾天骑行者目标小、边缘模糊且有遮挡。如果 cyclist 只有几百个样本第一优先是补数据而不是调超参数。5.2 最后一招针对雾天的预处理和多尺度测试模型已经训练完如果还想提升雾天表现最有效的不是加大模型而是在推理时加入预处理。一种常用方法是先做去雾再做检测但去雾算法可能引入噪声更稳妥的是在测试时做多尺度预测把原图缩小再放大分别推理后合并结果python detect.py --weights runs/train/fog_run1/weights/best.pt --img 640 --source fog_test/ --augment--augment会启用测试时增强包括翻转和多尺度对模糊目标有一定增益。另外如果训练时用的是--img 640评估时不要突然用--img 1280期待变好这会让模型产生尺度偏移。除非你从一开始就用多尺度训练保持输入一致性比所谓“高分辨率更准”更重要。最后要提的是自适应锚框。雾天目标尺寸分布和 COCO 不同比如公交车长宽比接近 2:1而行人接近 1:2。训练时可以加--noautoanchor关闭自适应或直接让 YOLOV5 重新计算python train.py --data fog_pedestrian_vehicle.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --noautoanchor去掉--noautoanchor就是自动计算日志里会打印新锚框。如果你的验证集 mAP 卡在一些特定尺寸上检查锚框是否覆盖了对应宽高。雾天数据集的全流程做到这里剩下的就是跑通、看数据、迭代没有别的捷径。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

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

尧图内容编辑团队

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

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

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

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

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

网站改版的5个关键决策

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

获取专属建站方案

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

立即免费咨询