真实道路车辆检测数据集:VOC、COCO、YOLO格式转换与YOLO训练实战
发布时间:2026/10/11 22:07:19 锦皓数字建站

简介面向目标检测入门者、课程学员及算法工程师这份RAR压缩包提供了1000张真实道路车辆场景图片及高质量标注。数据场景丰富使用LabelImg标注框体质量有保障同时给出VOC(xml)、COCO(json)、YOLO(txt)三种格式标签可无缝接入YOLO系列训练流程免去自行转换的麻烦。压缩包共2000个文件以1000个XML标注文件和991个TXT标签文件为主附带YAML配置、Python脚本和HTML教程文档总体积约115MB。配套内容覆盖Windows/Linux两种系统的YOLO环境搭建与训练教程含GPU显卡驱动版本说明并随包提供训练集/验证集/测试集划分脚本可自动生成对应文件夹及ImageSets下的txt索引方便按需组织数据。目前已有491人学习下载适合希望用真实道路数据快速跑通YOLO训练管线的读者。1. 为什么一份带三种标签的道路车辆数据集值得你花时间拿到一个声称含1000张图片voc、coco和yolo三种格式标签划分脚本训练教程的rar压缩包很多人的第一反应是又要解压半天倒腾格式了。但公路真实场景车辆检测这件事真正的门槛从来不在模型结构而在数据——你是否有一批真实光照、真实遮挡、真实路况下的标注图并且能直接喂给YOLO训练管线。这份数据集的聪明之处在于它把训练前最烦琐的三件事——格式统一、数据划分、环境教程——在压缩包里一次性解决让你从解压到看到第一个mAP数字可能只需要一个下午。适合谁刚把YOLO环境跑通但还在用COCO预训练权重凑数的人想验证真实道路车辆检测在自己电脑上到底能不能跑起来的从业者以及被课程或毕业设计要求做一个检测Demo的学生。和动辄几万张的BDD100K、Cityscapes不同1000张图是刻意控制的规模让一张T4甚至CPU都能完成一轮完整训练先把工程链路走通再谈扩充数据。下面按我自己的落地习惯把这个压缩包从打开到训出模型的全过程拆开讲。2. 三种标注格式不是重复劳动VOC、COCO、YOLO各管一段2.1 VOC格式xml里存的是像素坐标人工抽查最友好Pascal VOC格式的组织方式是一张图片对应一个同名xml文件xml里核心节点是object每个object包含name类别名和bndbox子节点下的xmin、ymin、xmax、ymax。这四个值是原始像素坐标不是归一化结果所以你可以直接对照图片检查框是否标歪。这个格式最大的优势是肉眼可读、脚本解析简单很多标注工具比如labelImg导出的默认格式就是VOC。对新手来说如果你怀疑某个标注标错了用文本编辑器打开对应xml就能直接定位到坐标值。它的问题在于数据组织比较散——一张图带一个xml文件数量翻倍传输、拷贝都费事。另外xml里没有直接给出图片的宽高解析时你得额外用PIL或cv2读取图像尺寸否则后面转YOLO归一化坐标时无从下手。2.2 COCO格式json全家桶评估和分割任务的地基COCO格式把所有标注聚合到一个json文件里顶层通常有images、annotations、categories三个数组。images里记录每张图的id、file_name、width、heightcategories是类别ID与名称的映射表annotations是核心每条标注包含image_id、category_id、bbox、area其中bbox是[x, y, width, height]四元组原点在图像左上角。COCO格式天生为评估而生——pycocotools库直接吃这种json计算mAP、mAP50、mAP75不用你自己写IoU匹配逻辑。如果你后续想往实例分割方向延伸annotations里的segmentation字段是现成的多边形标注能直接用于Mask R-CNN或YOLOv8-seg。缺点也很明显json嵌套深人类肉眼几乎没法核验而且不同工具生成的COCO json字段版本有差异有的带info、licenses元信息有的没有解析时不能把字段写死。2.3 YOLO格式每张图一个txt归一化坐标直接满足训练器胃口YOLO格式是三者中最机器友好的每张图片对应一个txt文件每行表示一个目标格式固定为category_id x_center y_center width height坐标全部归一化到0到1之间。比如一张宽高为1920x1080的图某辆车框的像素坐标是(960, 540, 200, 100)归一化后就是类别ID然后接0.5 0.5 0.104 0.093。Ultralytics框架在训练时默认的读取方式就是到images目录的同名路径下找labels目录里的txt。归一化坐标让模型训练时不需要关心输入图片尺寸变化但代价是人工审查几乎不可能。你盯着0.5443 0.6211 0.1832 0.2077看不出任何问题。所以我的习惯是从VOC或COCO转YOLO时转换脚本里必须带一个回画函数把归一化坐标还原成像素框画在原图上输出成一张带框的jpg肉眼确认没有错位。这一步看着笨但真能抓出坐标系的低级错误。2.4 三种格式互转的工程要点映射表与边界clip是命门数据集同时提供三种格式真实意图是让你在不同的工程阶段自由切换不必临时找转换代码。你可以先用COCO算mAP评估再用VOC做人工抽查最后转成YOLO喂给训练器。但互转时有两个命门类别映射表和边界裁剪。我先给出一段VOC转YOLO的核心脚本这是整个压缩包里最值得你逐行研究的代码import xml.etree.ElementTree as ET import os # 类别顺序表下标就是YOLO的category_id CLASSES [car, truck, bus, motorcycle, bicycle, person] def voc2yolo(xml_path, out_txt_path, img_w, img_h): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): name obj.find(name).text if name not in CLASSES: print(f跳过未定义类别: {name} in {xml_path}) continue cat_id CLASSES.index(name) bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) # 防止标注越界超出图像宽高的坐标裁剪到边界 xmin max(0, min(xmin, img_w - 1)) xmax max(0, min(xmax, img_w - 1)) ymin max(0, min(ymin, img_h - 1)) ymax max(0, min(ymax, img_h - 1)) # 归一化中心点坐标和宽高 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h lines.append(f{cat_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) with open(out_txt_path, w) as f: f.write(\n.join(lines) \n if lines else )逻辑说明先定义CLASSES列表它的顺序直接决定YOLO txt里第一列类别ID的编号。转换时读取每个object的name查表得到数字ID再把bndbox四个角点换算成中心点加宽高的归一化值。max/min那两行是边界裁剪防止标注框因为人工手滑超出图像范围训练时越界坐标会导致YOLO的anchor匹配逻辑计算出负数或大于1的值直接tensor报错。参数说明img_w和img_h需要用PIL.Image.open(img_path).size或cv2.imread读取不能用xml里可能存在的size节点因为很多标注工具写的不准。转换跑完后建议加一个校验函数遍历所有txt检查每行五个数值是否全部在[0,1]区间、width和height是否大于0。这段校验代码几行就能写完但能避免训练到一半才爆出assertion failed的尴尬。3. 划分脚本的工程门道分层抽样与固定随机种子3.1 纯随机切分是偷懒做法同源泄漏会让你白高兴一场很多新手拿到1000张图直接random.shuffle按7:2:1切分这个做法在真实道路场景里是有隐患的。道路数据集通常来自连续视频抽帧或同一路段多角度拍摄同一辆车的多张照片大概率在文件名上只有序号差异。如果纯随机切训练集里可能出现某辆车在1秒前的画面验证集里出现同一辆车1秒后的画面——这属于同源泄漏会让验证mAP虚高真实部署时遇到没见过的车效果立刻打回原形。更稳妥的第一步是看文件名结构。如果文件名是类似frame_000001.jpg这种连续抽帧应该按每隔N张抽一张进验证集的方式切分如果文件名没有明显规律就退而求其次按文件名字面排序后等间隔抽样。等间隔抽样虽然不如按视频片段切分那么严谨但比纯随机能显著降低同源泄漏风险。3.2 1000张图的切分比例75/20/5还是80/10/10切分比例没有绝对标准取决于你拿验证集做什么。如果只是训练时监控mAP验证集2成就够了——200张图在1000张规模下已经能给出相对稳定的mAP评估。如果你后续要调阈值、做模型选择我建议单独留出1成测试集训练过程中完全不碰它最后才用测试集跑一次终极报告。我一般用75/20/5750张训练、200张验证、50张测试。测试集小一点没关系因为真实道路场景的评估重点不是数据量而是多样性分布——50张如果涵盖晴天、阴天、逆光、隧道出口这几种典型光照已经足够看出模型短板。切分时还要检查每个子集的类别分布。假如bus在全集中只有30个实例随机切分后验证集可能只分到3个算出来的bus类mAP波动极大。这时候需要做分层抽样确保每类物体在每个子集中的出现比例与全集尽量一致。3.3 一份带固定随机种子和分层逻辑的划分脚本rar里自带的划分脚本常见做法是纯Python实现不依赖numpy和pandas。我按自己常用的逻辑给你一份可用的骨架它保证同一个人在不同机器上跑出完全一样的划分结果import os import random from collections import defaultdict random.seed(20240601) # 固定种子让划分结果可复现 image_dir images label_dir labels train_ratio, val_ratio 0.75, 0.20 images [f for f in os.listdir(image_dir) if f.endswith(.jpg)] images.sort() # 排序后等间隔打底降低连续帧同源泄漏 # 按每张图的类别组合做分组 groups defaultdict(list) for img in images: txt_path os.path.join(label_dir, img.replace(.jpg, .txt)) cat_set set() with open(txt_path) as f: for line in f: if line.strip(): cat_set.add(line.split()[0]) groups[tuple(sorted(cat_set))].append(img) train, val, test [], [], [] for cat_group in groups.values(): random.shuffle(cat_group) n_train int(len(cat_group) * train_ratio) n_val int(len(cat_group) * val_ratio) train cat_group[:n_train] val cat_group[n_train:n_train n_val] test cat_group[n_train n_val:] # 写入三个列表文件供YOLO的data.yaml引用 with open(train.txt, w) as f: f.write(\n.join(os.path.join(image_dir, x) for x in train)) with open(val.txt, w) as f: f.write(\n.join(os.path.join(image_dir, x) for x in val)) with open(test.txt, w) as f: f.write(\n.join(os.path.join(image_dir, x) for x in test))逻辑说明先把文件名排序再按每个txt里的类别ID组合分组每个组内部做随机shuffle切分。这样保证只含car的组和含cartruck的组各自被独立按比例切分任何类别组合都不会在验证集里消失。random.seed(20240601)是固定的你重跑多少次结果都一样这和调参时的可复现性直接相关——改了模型结构以后如果数据划分变了你就说不清mAP提升是模型贡献还是划分运气。参数说明train_ratio和val_ratio按需调整但要保证val至少有100张。如果你的数据集本身某个类别分布极不均衡可以在分组后打印每个组的数量对少于5张的组做特殊处理——比如直接全放进训练集因为这类稀有组合在验证集里只有1到2张算出来的mAP波动太大没有参考价值。生成的train.txt和val.txt每行是图片路径但YOLO的data.yaml需要的是图片所在目录所以这里有两种用法要么把txty路径列表直接传给train:字段要么按目录方式组织文件结构。我建议在data.yaml里用目录方式组织路径处理更省心。4. 从零跑通YOLO训练环境配置、data.yaml与关键参数4.1 用PyCharm搭环境虚拟环境、PyTorch、ultralytics很多新手死在这一步——不是模型不行而是环境装了三遍都没跑通。我建议直接用PyCharm的Terminal按以下顺序执行conda create -n yolo python3.10 -y conda activate yolo pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics逻辑说明第一行创建干净的虚拟环境避免和系统里其他Python项目互相污染。第三行指定了CUDA 11.8版本的PyTorch这是目前ultralytics官方测试覆盖最全面的版本如果你的显卡是40系且驱动已升级到支持CUDA 12.1可以把cu118换成cu121。最后一行安装Ultralytics它会自动带上YOLOv8和YOLOv5的模型定义。参数说明Python版本选3.10而不是3.12因为部分旧版onnxruntime和opencv-python对3.12支持还不完善。装完后运行python -c import torch; print(torch.cuda.is_available())看是否输出True。这一步不做后续训练报错你分不清是数据问题还是CUDA没打通。4.2 写data.yaml类别ID必须与txt标签对齐YOLO训练前要准备一个数据集描述文件data.yaml放在你当前工作目录下内容如下path: /your/absolute/path/to/dataset train: images/train val: images/val test: images/test names: 0: car 1: truck 2: bus 3: motorcycle 4: bicycle 5: person逻辑说明path是数据集绝对路径train、val、test是相对path的图片目录路径。Ultralytics会自动去这些目录里找图片然后根据labels目录结构找对应txt你不需要在配置里写明标签目录路径。这个默认行为是图片在images/train下标签就必须在labels/train下。names的映射顺序是最容错的地方。txt里每行的第一列是数字0到5对应names里的索引。如果你把0: person写在前而txt里0实际代表car训练出的模型会在推理时把人标成车、车标成人。这类错误不会报错只会静默地让你得到一堆离谱的预测结果。解压数据集后你应该先抽取三个文件夹里各一个txt手动对照data.yaml验证一遍类别ID顺序三分钟的事省掉一整轮训练后复盘的时间。4.3 训练命令从yolov8s起步参数按显存逐步调yolo detect train datadata.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0 projectruns namevehicle_exp参数说明modelyolov8s.pt是下载COCO预训练权重并做迁移学习s版本在1000张数据规模下是合理的平衡点——n版本太小容易欠拟合m版本以上在这么少的数据下容易过拟合。epochs100是常见起步值训练到30轮时观察验证集mAP如果已经趋平可以手动CtrlC后用--resume续训。imgsz640是检测网络的输入尺寸如果你发现真实道路场景里远处车辆只占几十像素把imgsz提高到960能明显改善小目标召回但显存占用约增长2.5倍按你的显卡决定。batch16在12GB显存下基本够用如果显存溢出优先降batch到8而不是降imgsz因为imgsz对精度影响更直接。训练过程中你还会看到loss曲线和mAP曲线的输出。这里有个判断信号如果训练集loss继续下降但验证集mAP在20轮后不再上升说明模型在过拟合训练集此时可以增加数据增强强度比如调大hsv_h、degrees等超参或者直接提前停止训练取验证集最佳的那个权重文件weights/best.pt。yolo损失函数由分类损失、回归损失和置信度损失三部分组成Ultralytics默认超参已经对COCO类别的均衡性调得较好道路车辆检测不需要你手动调整损失项权重。第一轮训练先用默认参数跑通再根据失败案例的分布去调整这才是正确的调参顺序。4.4 训练完成后立即做一次可视化验证训练结束后一行命令直接看模型在真实道路图上的效果yolo detect predict modelruns/vehicle_exp/weights/best.pt sourceyour_test_images/ saveTruesource可以指向一个文件夹也可以指向一个视频文件。saveTrue会把带框的结果图保存到runs/detect/predict目录。不要只看控制台输出的mAP数字一定要打开至少10张结果图用肉眼确认车辆框的位置是否贴合车身、有没有把路牌或树影误检成车。目标检测项目的第一个常识就是mAP是统计指标它可以被骗但你的眼睛不会。5. 训练中的常见翻车现场与排查手册5.1 现象训练到一半报错 Assertiont 0 t nfailed原因标签txt里出现了越界坐标比如x_center大于1.0或width为负数。这通常发生在从VOC或COCO转YOLO时没有做边界clip或者某些xml里bndbox的xmin和xmax写反了导致归一化后width为负。解决写一段脚本批量遍历所有txt检查每行的五个数值是否在[0,1]区间、第三和第四个数是否大于0遇到异常直接打印出文件名和原始行。修复方式是重新生成该txt或删除对应标签不要留着坏数据训练因为YOLO在数据加载阶段就会崩溃。5.2 现象验证集mAP不低但实测视频里小目标全部漏检原因这是imgsz设置太小的典型症状。训练用640没问题但真实道路里一辆50米外的小轿车在1080P画面上可能只有40x30像素640输入尺寸下这个目标在特征图里只剩不到3个像素模型根本没机会学到它的特征。解决先把imgsz提升到960重新训练验证一轮如果显存不够考虑用Tiling策略——把大图切成640的瓦片分别推理再合并结果。还可以选择yolov8m以上的模型其高分辨率特征图对密集小目标更友好但推理速度会下降约50%看你的实际部署约束取舍。5.3 现象框的位置对但整体偏移半个车身类别置信度却很高原因转换脚本里坐标换算公式错了。比如把x_center算成(xmin xmax) / 2后忘了除以图像宽度或者把y和x调换了。置信度高是因为分类损失和回归损失是分开优化的模型可以类别判断正确但框不准地收敛。解决不查loss直接用yolo detect predict跑10张训练图看框的位置。如果发现框整体偏左或偏上99%是归一化公式错误回到VOC转YOLO脚本里检查每条除法式。我见过不少项目在转换阶段粗心导致整个数据集白训练两周。5.4 现象在当前设备上训练很吃力显卡占用率不高但很卡原因检测出了瓶颈。device0指定了单个GPU如果batch已经16但训练还是慢很可能是数据加载成了瓶颈——磁盘读取图片来不及。解决检查数据是否放在机械硬盘把数据集拷到SSD或直接用cacheTrue参数让Ultralytics把图缓存进内存。还可以用workers8提高数据预取线程数但要小心workers开太多导致CPU打满。另外训练时你不用开任何可视化工具Ultralytics的输出保存到runs目录看实时日志就够了。5.5 现象推理正常但类别互相混淆车标成货车原因数据集中部分类别的样本数差异太大。比如car有800个实例truck只100个模型为了降低整体loss会把不确定的样本都靠向car。解决先统计训练集中每类实例数量打印出来如果差距超过10倍考虑做两类处理一类是降低car的样本权重另一类是对truck做mosaic增强并复制多半。数据不平衡在道路车辆场景里非常常见你不可能要求实拍路段里卡车和轿车一样多但可以通过采样策略把比例拉近。在data.yaml同级目录里Ultralytics支持loss_scale参数把它调大到1.5到2.0能有效提升少样本类别的召回率。6. 训完别急着部署三个进阶验证技巧模型训完mAP数字还没来得及开心你要先做一次更狠的验证。拿摄像头或手机拍一段你所在城市的真实道路视频注意不要和数据集的拍摄地域重叠然后用best.pt跑一遍检测。如果发现某个方向的车流量位置正好是检测盲区比如公交车线路和轿车重叠的复杂场景不要急着加数据先在现有数据上检查是不是标注框过小导致的。这轮验证的目标是找到模型的认知边界——哪些场景是1000张图覆盖不到的这才是你后续补充数据的方向。第二个技巧是导出ONNX做部署可行性测试。用yolo export modelbest.pt formatonnx opset12把模型转成ONNX格式再用onnxruntime写一段推理脚本测量单帧推理延迟并确认输出shape是[1, 84, 8400]以640输入为例8400是三个检测头的总anchor数84是5个类别加4个框坐标的拼接。如果延迟在CPU上超过100ms部署时就要考虑TensorRT或INT8量化而不是继续堆参数。第三如果你有D435i这类深度相机可以把检测框和深度值结合做测距验证。核心技巧是不要取整个框内所有像素的深度平均值——道路场景里框内常包含背景、路面甚至部分天空平均值会严重漂移。正确做法是取框底边向上约20%区域内的深度中位数抗干扰能力最强。这其实就是多模态AI分析思路里的具体一环检测框负责定位深度信息负责测距后端再判断是否有碰撞风险。我的个人习惯是任何一个新数据集拿到的第一周不急着调参而是先把解压、格式检查、划分、训练、可视化验证这一整套流程完整跑两遍。第一遍全用默认参数目标是把所有工程坑踩一遍第二遍再开始针对漏检场景调参。这个习惯陪我躲过了不少训练20小时结果输在格式转换的无效劳动。希望这篇梳理能让你少走我走过的弯路也祝你的真实道路车辆检测项目第一轮训练就顺利出图。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。