简介:这份资源面向夜间场景下的目标检测任务,提供约9000张已标注的交通车辆与行人图像,采用YOLO标注格式,适合从事自动驾驶、智能交通或夜间监控研究的开发者与算法学习者使用。数据集共含4个类别:bicycle、car、dog、person,并已按7:3比例划分训练集与验证集,可直接投入YOLO系列模型的训练与评估。压缩包共2000个文件,以1999个txt标注文件和1个py脚本为主,整体约371.05MB,其中txt文件对应每张图像的边界框与类别标签,py脚本可用于数据预览或格式检查。目前已有34人学习下载。资源配套了YOLOv5改进实战的系列内容,读者可结合自身项目快速复现夜间目标检测流程,并在此基础上尝试网络结构优化与调参,省去从零标注与划分数据的时间成本。
1. 夜间交通场景的目标检测数据集:9000 张已标注图像到底能解决什么问题
夜间交通场景的目标检测,一直是计算机视觉落地里最容易被低估的一块。白天跑得挺欢的 YOLO 模型,一到晚上就集体翻车——车灯眩光把车身轮廓吃掉、路灯下的行人只剩一团黑影、远处尾灯和刹车灯混在一起分不清是车还是反光。这不是模型不行,是训练数据里夜间样本太少,模型压根没见过这种光照分布。手上这份约 9000 张、已按 YOLO 标注格式整理好的夜间交通图像数据集,价值就在这里:它把车辆和行人这两类夜间高频目标,用统一的 txt 标签格式固定下来,省掉了从零采集、从零标注的大头成本。适合谁用?做自动驾驶感知预研的、做园区/路口夜间监控的、拿 YOLOv8 或更新版本练手想找个真实场景数据集的,都能直接上手。下面我按“先搞懂格式和分布,再跑通训练,最后避开夜间特有的坑”这条线,把这份数据怎么用讲透。
2. YOLO 标注格式拆解:9000 张数据到手先别急着训练
2.1 目录结构与标签文件的真实长相
一份规范的 YOLO 格式数据集,目录通常长这样,你拿到手第一件事是核对结构对不对:
dataset/ ├── images/ │ ├── train/ # 训练集图像 │ ├── val/ # 验证集图像 │ └── test/ # 测试集图像(可选) ├── labels/ │ ├── train/ # 与 train 图像一一对应的 txt │ ├── val/ │ └── test/ └── data.yaml # 数据集配置文件关键点在于 images 和 labels 必须严格同名同层级,images/train/0001.jpg对应labels/train/0001.txt。少一个对应文件,训练时不会报错,但那张图会被静默跳过,这是最常见的“数据明明有 9000 张,训练日志里却只加载了 8700 张”的原因。
单个标签 txt 的内容是每行一个目标,格式为:
<class_id> <x_center> <y_center> <width> <height>后四个值全部是归一化到 0~1 的浮点数,相对的是图像宽高,不是像素。比如一行0 0.512 0.634 0.087 0.152,意思是类别 0、目标中心在图像横向 51.2%、纵向 63.4% 处,框宽占图宽 8.7%、框高占图高 15.2%。夜间车辆和行人两类,常见约定是0=vehicle、1=pedestrian,但具体以 data.yaml 里的 names 为准,别想当然。
2.2 用脚本体检:三类必须提前发现的脏数据
拿到数据先跑一遍体检脚本,比训练到一半发现标签错位强得多。下面这段检查图像与标签配对、坐标越界、空标签:
import os from pathlib import Path IMG_DIR = Path("dataset/images/train") LBL_DIR = Path("dataset/labels/train") missing_label, empty_label, out_of_range = [], [], [] for img in IMG_DIR.glob("*.jpg"): lbl = LBL_DIR / (img.stem + ".txt") if not lbl.exists(): missing_label.append(img.name) continue lines = lbl.read_text().strip().splitlines() if not lines: empty_label.append(img.name) # 纯背景图,允许但需统计 continue for ln in lines: parts = ln.split() if len(parts) != 5: out_of_range.append((img.name, "字段数不对")) continue _, x, y, w, h = map(float, parts) # 归一化坐标必须落在 0~1,且框不能超出边界 if not (0 <= x <= 1 and 0 <= y <= 1 and 0 < w <= 1 and 0 < h <= 1): out_of_range.append((img.name, ln)) print("缺标签:", len(missing_label)) print("空标签:", len(empty_label)) print("越界/异常:", len(out_of_range))逻辑说明:遍历图像目录,逐个找同名 txt;空标签代表纯背景图,夜间数据集里适当保留能降低误检,但比例别超过 10%;坐标越界几乎都是标注工具导出时坐标系搞错(比如误用了像素值),必须在训练前修掉,否则 YOLO 会把这些框裁到边界,学出一堆畸形目标。参数上,0 < w <= 1而不是0 <= w,因为宽高为 0 的框是无意义的。
2.3 data.yaml 怎么写才不出错
配置文件是训练入口,写错一个字段就是几小时白跑:
path: /abs/path/to/dataset # 数据集根目录,建议绝对路径 train: images/train val: images/val nc: 2 # 类别数 names: 0: vehicle 1: pedestrianpath用绝对路径能避开“相对路径随启动目录漂移”的玄学问题。nc必须和 names 的条目数一致,多写一个类别、names 少一行,训练能启动但类别索引会错位,模型把行人学成车你还找不到原因。改完 yaml 用python -c "import yaml; print(yaml.safe_load(open('data.yaml')))"过一遍,确认解析无误。
3. 用 YOLOv8 把这份夜间数据集跑通:从环境到第一轮训练
3.1 环境配置与依赖版本
环境这块踩坑最多的是 CUDA 和 PyTorch 版本对不上。稳妥做法是先装匹配显卡驱动的 PyTorch,再装 ultralytics:
# 以 CUDA 11.8 为例,按自己驱动版本调整 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics # 验证 GPU 是否可用 python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"如果is_available()返回 False,别急着改代码,先看驱动版本和 CUDA 版本是否匹配。V100 这类卡跑 YOLOv8 训练绰绰有余,显存 16G 起步,batch 能开到 16~32。CPU 训练不是不能跑,但 9000 张图一轮要几小时,不现实。
3.2 训练命令与关键参数怎么设
最小可跑通的训练命令:
yolo detect train \ data=/abs/path/to/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ device=0 \ project=runs/night \ name=exp1逐项说参数:model=yolov8n.pt是官方预训练权重,从 nano 起步验证流程通不通,别一上来就上 x 版;imgsz=640是夜间场景的常用折中,再大对小目标和远距离行人有利但显存吃紧;batch=16按显存调,爆显存就降到 8;epochs=100配合早停(默认 patience=50)够用,夜间数据收敛通常比白天慢,别设 30 轮就下结论。想换更大模型,把 model 换成yolov8s.pt或yolov8m.pt,其余不动。
3.3 训练日志里该盯哪几个数
启动后重点看三行:box_loss、cls_loss、mAP50。box_loss 前期快速下降说明框回归在学;cls_loss 不降反升,多半是类别不平衡或标签有噪声;mAP50 在夜间数据上第一轮能到 0.3 以上就算正常起步。如果 mAP 一直卡在 0.05 以下,先回去查标签坐标是不是没归一化——这是新手最常翻的车。验证集 loss 开始上升而训练 loss 还在降,就是过拟合信号,该加数据增强或减轮数了。
4. 夜间数据集的避坑清单:5 个我踩过的真实坑
4.1 车灯眩光导致框漂移
现象:模型对近光灯直射的车辆框总是偏大或偏移,白天同类目标正常。原因:眩光区域像素饱和,边缘特征丢失,标注时人眼也容易把光晕算进车身。解决:训练时开hsv_v增强(YOLOv8 默认 hsv_v=0.4),模拟不同曝光;标注阶段对强眩光车辆,框只贴车身实体轮廓,别把光晕圈进去。
4.2 行人被误标成车辆
现象:混淆矩阵里 pedestrian 大量被判成 vehicle。原因:夜间行人穿深色衣服、被车灯拉出长影,标注员赶工时把影子当车身。解决:用 2.2 的脚本统计每类框的宽高比,行人框宽高比通常接近 0.3~0.5,车辆接近 1.0~2.0,比例异常的挑出来人工复核。
4.3 空标签比例过高拖垮召回
现象:模型召回率上不去,漏检多。原因:夜间数据集里纯背景图(无目标)占比过高,模型学到“大部分图没东西”的偏置。解决:统计空标签比例,超过 15% 就抽掉一部分;或在训练时用fraction参数控制采样比例。
4.4 验证集和训练集同源导致虚高
现象:验证 mAP 很高,实际部署一塌糊涂。原因:train 和 val 是从同一段视频连续抽帧,相邻帧几乎一样,等于变相泄漏。解决:按视频/时段切分,别按帧随机切;同一路口的图要么全进 train,要么全进 val。
4.5 归一化坐标用了像素值
现象:训练不报错但 mAP 极低,可视化框全挤在左上角。原因:标注导出时坐标系选错,写进去的是像素坐标而非归一化值。解决:跑 2.2 脚本,凡是坐标大于 1 的直接判定异常,批量除以图像宽高修正。
5. 让夜间检测再上一个台阶:增强策略与验证习惯
把基础流程跑通只是及格线,夜间场景真正拉开差距的是数据增强和验证方式。我一般会在 YOLOv8 默认增强基础上,针对夜间特点额外调三个参数:hsv_v拉到 0.5 模拟曝光波动,hsv_s提到 0.7 应对路灯色温差异,mosaic保持默认 1.0 但配合close_mosaic=10在最后 10 轮关掉,让模型在真实分布上收尾。如果显存允许,把imgsz提到 768,远距离行人的小目标召回会有肉眼可见的提升。
验证环节别只看一个 mAP 数字。我习惯把预测结果按光照强度分桶——强眩光、普通路灯、极暗三类各抽 50 张,分别算召回。往往整体 mAP 0.6,但极暗桶只有 0.3,这个短板才是部署时真正要命的。分桶验证的脚本思路是:用图像平均亮度做阈值分组,再对每组单独跑yolo detect val,把结果记成表:
| 光照分桶 | 平均亮度区间 | 车辆召回 | 行人召回 |
|---|---|---|---|
| 强眩光 | > 120 | 0.82 | 0.61 |
| 普通路灯 | 60 ~ 120 | 0.78 | 0.70 |
| 极暗 | < 60 | 0.55 | 0.38 |
看到极暗桶行人只有 0.38,就知道该补极暗样本或针对性做亮度增强,而不是盲目加轮数。这套分桶习惯是我被“整体指标好看、上线就翻车”坑过之后逼出来的,比任何调参技巧都值钱。9000 张夜间数据不算大,但用对方法,它足够让你把夜间检测这条路走扎实。希望帮到你。
本文还有配套的精品资源,点击获取