夜间车辆检测数据集:三格式标签与YOLO训练实战 简介YOLO夜间车辆检测数据集专门面向目标检测学习者与算法工程师提供真实夜间道路场景下的高质量车辆图像解决夜间光照不足、标注格式不一等训练痛点。包内共2000个文件包含1986个XML标签文件、3个Python划分脚本、5个训练列表及6个HTML教程文档压缩包约209MB标签涵盖VOC、COCO、YOLO三种格式可直接接入主流YOLO系列模型训练图像场景丰富、标注框质量高可有效缓解夜间样本稀缺与泛化能力不足的问题。另附环境搭建与训练案例教程覆盖Windows与Linux双平台并配套训练集、验证集、测试集划分脚本便于灵活自定义数据切分。已有448人学习下载适合需要真实夜间数据提升模型鲁棒性的计算机视觉开发者。1. 夜间车辆检测为什么比白天更难——数据集的出发点夜间车辆检测在实际项目中远不是把白天模型直接迁移就能用的。路灯交替、车灯眩光、暗部噪点和运动模糊同时出现目标边界与背景的对比度被大幅压缩白天表现还不错的YOLO模型在夜间会漏掉大量距离远的车辆而且车头灯造成的亮斑会被误判成目标。这个数据集包含5000张真实夜间场景的车辆图片用labelimg逐框标注同时保留VOC XML、COCO JSON和YOLO TXT三种标签格式可以不经格式转换直接喂给YOLOv5、YOLOv8以及后续更新的YOLO系列。适合两类人一是要快速构建夜间车辆检测原型二是做自动驾驶感知或城市交通监控场景迁移。数据里还附带了环境搭建、训练教程和三个划分脚本省掉了从零整理数据集的麻烦。2. 三格式标签并存VOC XML、COCO JSON 与 YOLO TXT 的字段映射同一张图只标一次却同时存在三种标签文件关键要搞清它们表达的是同一个标注框的不同坐标编码。很多人在拿到这种数据集后直接挑一个文件夹里的标签丢给YOLO结果发现类别对不上、坐标越界其实问题都出在格式转换上。2.1 三种格式的坐标编码差异VOC XML使用像素绝对坐标记录xmin、ymin、xmax、ymax四个整数值COCO JSON的segmentation和bbox也都基于像素但bbox记录的是左上角x、y和宽度w、高度hYOLO TXT则是归一化后的中心点坐标cx、cy、w、h都是0到1之间的小数。以一张1280×720的图片为例一个左上角在(320,180)、宽640、高360的车辆框在YOLO txt里会写成0 0.5 0.5 0.5 0.5第一位是类别ID后面四个数是除以图片宽高后的归一化结果。三种格式的定位逻辑可以用下面这个表格快速对照格式文件后缀坐标含义坐标范围类别记录方式VOC.xml边框左上角xmin/ymin右下角xmax/ymax像素绝对值标签名如car、truckCOCO.jsonbbox为[x,y,w,h]像素绝对值存在categories数组的id映射YOLO.txt中心点坐标cx,cy,宽高w,h归一化到[0,1]类别对应的整数id训练YOLO系列时必须用txt验证mAP时经常需要转回COCO JSON而做标注审核时看VOC XML最直观。三个格式之间的转换不建议手写最好用现成脚本统一转换避免归一化时把边框算出图片边界。尤其要注意YOLO txt中的cx和cy是相对图片宽高的比例如果训练时用了resize到640而标签依然按原图尺寸归一化模型会学到错误的坐标分布。2.2 用Python快速核对三份标签是否一致实际处理数据集时我一般会先写一段小脚本把三份标签都读出来对比同一张图片的标注框数量和坐标值确认数据集在制作时没有因为中途改格式丢掉标注。下面这段代码可以同时解析三种标签并打印面积和类别import json import xml.etree.ElementTree as ET # 解析 YOLO txt每行是 类别ID cx cy w h全部为归一化坐标 def load_yolo_txt(txt_path, img_w, img_h): boxes [] with open(txt_path, r, encodingutf-8) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cls_id int(parts[0]) cx, cy, w, h map(float, parts[1:]) # 还原为像素坐标便于和VOC、COCO比较 boxes.append([cls_id, cx * img_w, cy * img_h, w * img_w, h * img_h]) return boxes # 解析 VOC xml根节点是 annotation每个 object 里是 bndbox def load_voc_xml(xml_path): tree ET.parse(xml_path) root tree.getroot() boxes [] for obj in root.findall(object): name obj.find(name).text bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) boxes.append({name: name, xmin: xmin, ymin: ymin, xmax: xmax, ymax: ymax}) return boxes这段代码里YOLO txt解析时要传入图片宽高才能转回像素坐标VOC XML解析返回的是每个object的name和bndbox。核对时只需要把同一张图片的三份输出打印出来看类别和边框数量是否对得上。如果发现某个XML有对象但TXT缺行说明转换脚本漏框要和原标注核对。另一个常见问题是COCO JSON里有些标注的bbox是空数组这种情况多半是标注时不小心画了零宽度的框需要过滤掉。COCO JSON的结构相对复杂需要先建立images数组里图片ID到文件名的映射再通过annotations里每个标注的image_id找到对应图片with open(annotations.json, r) as f: coco json.load(f) img_id_to_name {img[id]: img[file_name] for img in coco[images]} for ann in coco[annotations]: if img_id_to_name[ann[image_id]] target_name: # ann[bbox] 是 [x, y, w, h]像素坐标 x, y, w, h ann[bbox]COCO的bbox和VOC的xmin/ymin表达的是同一个左上角但VOC的右下角要换算成xw、yh才能对比。标签目录里三种文件分别放在不同文件夹文件名与图片名保持了一致直接按名字拼接路径就能对应上。2.3 类别定义与标签文件夹的组织方式labelimg标注时自定义的类别名称会直接写进VOC XML的name节点而YOLO TXT只存整数ID同时需要一个classes.txt来确定ID与名称的对应关系。这个数据集的车辆检测场景通常只用vehicle这一类也可以细分car、truck、bus等具体看原始数据集的类别定义。拿到数据集后先打开标签文件夹里的classes.txt或者查看任意一个XML里的name确认类别顺序再训练。否则一旦类别ID与名称错位训练的损失看起来正常实际上模型把卡车和轿车全混成一类。提示如果训练时发现验证集mAP异常低先检查classes.txt里的类别顺序是否和YOLO TXT里的ID对应这是三格式数据集训练时最容易踩的坑。3. 训练集/验证集/测试集划分脚本的运行方式与路径约定数据集自带的三个划分脚本解决的是同一个问题让图片和标签以相同比例进入不同子集并生成供训练使用的文件列表。很多项目会忽略测试集的独立性直接把全部数据用来训练导致最后上报的精度虚高这里给的三个脚本恰好能规避这个习惯。3.1 三个脚本的差异与适用场景第一个脚本「训练集、验证集、测试集划分脚本图片标签划分写入新文件夹.py」会把图片和对应标签复制到train/val/test三个目录下适合直接用于YOLO训练。第二个脚本只划分训练集和验证集不含测试集适合先不保留最终测试集、把全部数据投入交叉验证的场景。第三个脚本名字是split_train_val生成ImageSets下txt文件划分脚本.py它不会复制文件而是在ImageSets目录下生成train.txt、val.txt、test.txt每个txt里写的是图片路径或图片名列表VOC系列的训练代码可以用这种txt组织数据。第三类脚本本质上是为PASCAL VOC训练流程准备的YOLO官方训练脚本不直接消费它但你可以把它生成的txt作为train_list.txt的替代。3.2 改路径参数而不是改代码逻辑打开脚本后顶部通常是几个路径常量和一个比例参数。常见做法是直接修改下面的变量再运行# 原始图片目录 image_source_dir D:/data/night_vehicle/images # 标注文件目录这里存放的是YOLO格式的txt label_source_dir D:/data/night_vehicle/labels # 输出目录脚本会在其中创建 train/val/test 子目录 output_root D:/data/night_vehicle/split # 划分比例三者之和应为1 train_ratio 0.7 val_ratio 0.2 test_ratio 0.1这段配置里image_source_dir指向所有原图label_source_dir指向YOLO TXT标签目录。脚本会遍历图片文件列表用random.shuffle打乱顺序再按比例切出三段同时把图片和同名txt复制到output_root的对应子目录。为了防止图片和标签数量不匹配脚本内部一般会检查同名文件是否存在跳过那些没有标签的图片。实际做数据工程时我会把 train_ratio 从0.7提高到0.8测试集固定留0.1验证集0.1因为夜间车辆场景的负样本和遮挡情况需要在训练阶段给模型足够多帧数。如果训练集图片过少也可以把测试集临时并回验证集先跑通完整链路再补数据。3.3 生成train_list.txt与手动划分的核心逻辑train_list.txt是训练时用来枚举图片路径的列表文件。许多YOLO训练流程支持把数据参数指向一个txt其中每行一个图片路径。数据集里提供的train_list.txt应该是从首次划分后导出的但如果你自己改了划分比例需要重新生成。可以用下面这段脚本从划分后的目录重建列表from pathlib import Path image_dir Path(D:/data/night_vehicle/split/train/images) txt_path Path(D:/data/night_vehicle/train_list.txt) # 获取所有jpg按名排序保证可复现 imgs sorted(image_dir.glob(*.jpg)) with txt_path.open(w, encodingutf-8) as f: for img in imgs: # 写入绝对路径训练时可以跨目录读取 f.write(str(img.resolve()) \n) print(f写入 {len(imgs)} 张训练图片路径)这段脚本遍历split/train/images目录下所有jpg把绝对路径写入train_list.txt。使用绝对路径可以避免训练时工作目录不一致导致找不到图片。如果你后续要移动整个数据集推荐改成相对路径配合训练脚本的root_dir一起使用。验证集列表和测试集列表可以用同样的方式生成只需把image_dir换成对应目录。注意glob匹配的文件名后缀要和实际图片格式一致如果图片是png却只匹配jpg生成的列表会是空的。三个脚本都没有采用命令行参数而是直接改顶部配置这是很多早期标注数据集的做法。运行前建议先复制一份原始数据避免脚本里用了os.remove清空已有文件时误删原图。我遇到过脚本在Windows下把路径反斜杠处理错的情况如果报找不到文件把脚本里的路径统一改成Path对象或使用正斜杠字符串。4. 从环境搭建到 YOLO 训练启动Ubuntu/Windows 双路径YOLO系列在Linux和Windows上的配置思路基本一致区别主要在PyTorch的CUDA依赖安装方式。数据教程里带了Linux和Windows两套环境搭建说明说明作者默认受众可能同时接触服务器和本地开发机。先解决环境问题再谈训练否则后面参数调了也跑不起来。4.1 环境搭建Anaconda PyTorch CUDA在Ubuntu上先安装显卡驱动和CUDA再用conda创建独立环境避免把系统Python搞乱。Windows上优先使用官方安装包安装CUDA和cuDNN再通过pip安装PyTorch。以YOLOv5为例Linux下的标准命令如下conda create -n yolo python3.8 -y conda activate yolo # CUDA 11.8 对应的PyTorch安装命令 pip install torch2.1.1 torchvision0.16.1 --index-url https://download.pytorch.org/whl/cu118 pip install -r requirements.txt先创建Python 3.8环境再安装与CUDA版本匹配的PyTorch最后安装项目运行依赖。--index-url字段指定PyTorch的官方CUDA版本源如果你使用AMD显卡在Linux下可以尝试PyTorch的ROCm版Windows下则通常只能CPU训练。环境搭建的教程里一般会包含nvidia-smi确认驱动版本以及用下面命令验证CUDA是否对PyTorch可用python -c import torch; print(torch.cuda.is_available())这一步卡住的概率最高大多数情况是CUDA版本与PyTorch不匹配。常见错误是torch.cuda.is_available()返回False但nvidia-smi显示驱动正常此时需要检查PyTorch的cu版本是否与驱动支持的CUDA版本兼容。如果你不打算用GPU直接把torch替换成CPU版训练速度会慢很多但流程能走通。AMD显卡在Windows下没有官方ROCm支持常见的做法是使用DirectML版PyTorch或者把训练任务放到云GPU上。数据配置部分需要自己新建一个每个项目独立的yaml文件里面指向划分后的图片目录# night_vehicle.yaml train: D:/data/night_vehicle/split/train/images val: D:/data/night_vehicle/split/val/images test: D:/data/night_vehicle/split/test/images nc: 1 names: [vehicle]train和val指向对应图片文件夹。实际训练时YOLO会按图片名自动找同名的txt标签因此labels目录必须有与图片一一对应的文件。如果之前用的是VOC XML格式需要先转成YOLO格式并放在labels目录中才能让这个yaml生效。这里的nc是类别数names是类别名称列表顺序必须与classes.txt里的ID一致。4.2 训练命令与关键参数启动训练使用训练脚本自带入口YOLOv5为train.pyYOLOv8为yolo train。这里以YOLOv5命令为例python train.py \ --data night_vehicle.yaml \ --weights yolov5s.pt \ --epochs 300 \ --batch-size 16 \ --imgsz 640 \ --device 0 \ --patience 50--data指向刚才写好的yaml--weights指定预训练权重--patience 50表示验证集mAP连续50轮不提升就提前停止。训练期间可以观察到终端输出的box_loss、cls_loss和obj_loss夜间数据集上obj_loss通常下降最慢因为这对应目标置信度预测是漏检和误检的直接来源。常用参数建议汇总如下参数示例值作用夜间场景建议--epochs300最大训练轮数5000张图300轮足够配合早停使用--batch-size16每批图数受显存限制8GB显存用164GB用4--imgsz640训练输入尺寸夜间小目标多可提到768显存占用同步上升--device0指定GPU多卡用0,1CPU训练设cpu--patience50连续N轮无提升则停止防止过拟合建议开启--cacheram图片加载到内存加速显存够时优先ram小内存用disk--augment默认开启训练时数据增强夜间场景降低mosaic强度关闭mixup参数说明--imgsz决定输入分辨率夜间远处车辆可能只有几十个像素从640提升到768能让模型学到更多细节但显存占用会接近翻倍。--batch-size与--imgsz互相制约如果出现CUDA out of memory优先降batch-size而不是降分辨率。--weights使用coco预训练权重可以显著降低夜间小目标的收敛难度因为模型已经见过丰富的物体边缘特征迁移到夜间场景时只需要微调分布差异。训练过程中不要只看loss绝对值要结合验证集指标判断。如果loss持续下降但mAP长期为0先查数据配置和标签是否对应。如果某个类别的AP远低于平均把对应类别的图片数量统计一下通常是不均衡。训练日志里的P和R是precision和recall夜间场景漏检多R偏低灯光明亮区域误检多P偏低。两者差距大时说明模型学到的是亮度特征而不是车辆结构特征。5. 夜间场景的验证指标与漏检调优技巧训练结束后用验证命令得到COCO或VOC格式的mAP。以YOLOv5为例python val.py --data night_vehicle.yaml --weights runs/train/exp/weights/best.pt --batch-size 16 --conf-thres 0.15 --iou-thres 0.5--conf-thres降低到0.15后能检出一部分置信度偏低的夜间远距离车辆代价是误检增多需要结合precision-recall曲线决定。后处理流程中NMS的作用是把重叠框合并夜间灯光造成的重影会让同一辆车出现多个高IoU框这时适当提高--iou-thres到0.6可以减少误删如果两个目标靠很近反而应该降低。验证时建议关闭TTA否则会引入额外变量。漏检调优顺序我一般固定为先看验证集PR曲线确认召回率上限再调整confidence阈值最后才改数据增强。夜间场景不要把mosaic和mixup同时开到最大这会让本就缺少纹理的目标变得更难学。建议关闭mixup把mosaic边值从1.0降到0.5让模型更多看到完整车辆而不是被裁剪的碎片。另一个技巧是给yaml数据配置里增加hsv_h、hsv_s的增强幅度夜间低饱和度的特点会使模型对亮度更敏感适度降低HSV增强反而能提升稳定性。一个很实用的做法把原图亮度直方图均衡化后加入训练作为额外一个数据源或者将RGB图转成YUV后取Y通道增强亮度再与原图拼接输入。这样模型在低照度下更容易提取轮廓。但注意不要对测试集做相同操作否则验证结果失真。训练时在--hyp参数指向的mosaic增强里将obj_loss的增益调高0.1可以加快置信度收敛。跑验证时分类别分析单独看car/truck的AP夜间卡车被灯照得发白类别AP往往比轿车低定位到具体类别后可以对该类别的标签权重加权或补充gamma随机调整的增强数据。本文还有配套的精品资源点击获取