新闻详情

新闻详情

首页 / 资讯中心 / 详情

真实道路车辆检测数据集:VOC/COCO/YOLO三格式标签与YOLO训练全流程

发布时间:2026/10/2 18:01:18来源:尧图网络
真实道路车辆检测数据集:VOC/COCO/YOLO三格式标签与YOLO训练全流程
简介本资源面向目标检测初学者与需要真实道路场景数据的开发者提供一套可直接用于YOLO系列训练的车辆目标检测数据集。数据均为真实道路场景采集覆盖多种路况与光照条件使用labelImg标注标注框质量较高并同时提供voc(xml)、coco(json)与yolo(txt)三种格式标签分别存放于不同文件夹便于直接接入不同训练框架。压缩包共约2000个文件以1000个xml标注、991个txt标签为主另含少量html教程、py划分脚本与yaml配置文件整体约115MB。资源还附赠YOLO环境搭建、Windows与Linux训练教程以及训练集、验证集、测试集划分脚本可按需自行划分并生成ImageSets下的txt列表。目前已有491人学习下载适合希望快速跑通车辆检测训练、验证模型效果或开展课程实践的用户参考使用。1. 真实道路车辆检测数据集1000 张图、三套标签、一条能跑通的训练链路手上有个真实道路车辆目标检测数据集1000 张图带 VOC、COCO、YOLO 三种格式标签外加划分脚本和训练教程——这个组合放在实际项目里价值不在“数据量”上而在“格式闭环”上。做过检测的人都知道公开数据集下载下来最耗时的从来不是训练而是标签格式对不上你拿到的可能是 XML但训练脚本要 TXT你想用 COCO 预训练权重但手头只有 VOC 标注。这套东西把三种格式和划分脚本一起给了等于把“数据准备”这段最枯燥的路先铺平了。它适合谁适合刚接触 YOLO 训练、想拿真实道路场景跑通全流程的人也适合手头有自采数据、想参照一套标准目录结构来组织自己数据集的人。下面我按“先看懂标签、再跑通训练、最后避开翻车点”的顺序把这条链路拆开讲。2. 三种标签格式到底差在哪VOC、COCO、YOLO 的坐标逻辑与选型2.1 VOC 的 XML 结构绝对坐标与 1-based 索引VOC 格式每张图对应一个 XML 文件核心信息在object节点里。它的坐标是绝对像素值且以图片左上角为原点xmin、ymin、xmax、ymax四个值直接对应框的边界。这里有个容易忽略的点VOC 的坐标是 1-based也就是说最小合法值是 1 而不是 0。很多转换脚本在处理边界框时如果按 0-based 写会在图片最左或最上边缘产生 1 像素偏移单张图看不出来但训练时 mAP 会莫名低一两个点。annotation folderimages/folder filenameroad_0001.jpg/filename size width1920/width height1080/height depth3/depth /size object namecar/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin312/xmin ymin450/ymin xmax689/xmax ymax702/ymax /bndbox /object /annotation上面这段 XML 里size记录原图宽高name是类别名bndbox是框。difficult字段在训练时通常用来标记难以识别的目标YOLO 训练中一般直接忽略或当作普通目标处理。truncated表示目标是否被截断如果做数据增强时可以据此决定是否保留该样本。2.2 COCO 的 JSON 结构归一化与类别 ID 映射COCO 格式把所有标注塞进一个 JSON 文件结构分images、annotations、categories三块。坐标是[x, y, width, height]且是归一化到 0-1 之间的浮点数。这里最大的坑是类别 IDCOCO 的category_id不一定是连续的官方 80 类里 ID 从 1 到 90 跳着来。如果你直接拿 COCO 的category_id当 YOLO 的类索引训练时类别会错位模型学出来的东西完全对不上。{ images: [{id: 1, file_name: road_0001.jpg, width: 1920, height: 1080}], annotations: [ { id: 1, image_id: 1, category_id: 3, bbox: [0.1625, 0.4167, 0.1964, 0.2333], area: 49284.0, iscrowd: 0 } ], categories: [{id: 3, name: car, supercategory: vehicle}] }bbox里的四个值是归一化后的[x_center, y_center, width, height]吗不是COCO 的bbox是[x_min, y_min, width, height]且都是归一化值。这一点和 YOLO 的[x_center, y_center, width, height]不同转换时必须先还原成绝对坐标再重新计算中心点。iscrowd为 1 表示该标注是密集人群或忽略区域训练时通常跳过。2.3 YOLO 的 TXT 结构归一化中心点与类别索引YOLO 格式每张图一个 TXT每行一个目标格式是class_id x_center y_center width height全部归一化到 0-1。class_id从 0 开始连续编号这是和 COCO 最大的区别。YOLO 不存图片尺寸所以转换时你必须自己从原图读取宽高来做归一化否则框会全部错位。0 0.2604 0.5333 0.1964 0.2333 1 0.7125 0.4889 0.1250 0.1778上面第一行表示类别 0框中心在图片宽度的 26.04%、高度的 53.33% 处框宽占图片宽度的 19.64%框高占高度的 23.33%。第二行类别 1以此类推。YOLO 的 TXT 文件必须和图片同名同目录或者按images/和labels/分开存放具体取决于训练框架的配置。2.4 三种格式的选型建议与转换优先级如果你用的是 YOLOv5 或 YOLOv8直接选 YOLO 格式省去转换步骤。如果你要用 MMDetection 或 Detectron2COCO 格式更顺手。VOC 格式现在主要用于兼容旧代码或某些特定评估脚本。这套数据集同时给了三种格式我的建议是训练用 YOLO 格式评估用 COCO 格式因为 pycocotools 的评估指标更细归档用 VOC 格式XML 可读性好方便人工核对。转换优先级上先从 VOC 转 YOLO 最稳因为 VOC 的绝对坐标最直观转换逻辑简单出错容易排查。3. 用划分脚本切分训练集与验证集比例、随机种子与类别均衡3.1 划分脚本的核心逻辑与参数说明划分脚本通常做三件事读取所有图片文件名、按比例随机分配到 train 和 val、把对应的标签文件也复制或移动到对应目录。下面是一个典型的 Python 划分脚本我加了详细注释。import os import random import shutil from pathlib import Path # 参数区按实际路径修改 IMAGE_DIR Path(datasets/images) # 所有图片存放目录 LABEL_DIR Path(datasets/labels) # 所有 YOLO 标签存放目录 OUTPUT_DIR Path(datasets/split) # 划分后输出根目录 TRAIN_RATIO 0.8 # 训练集比例 VAL_RATIO 0.2 # 验证集比例 SEED 42 # 随机种子保证可复现 random.seed(SEED) # 收集所有图片文件名不含扩展名 image_files [f.stem for f in IMAGE_DIR.glob(*.jpg)] image_files.sort() # 排序后再打乱避免文件系统顺序影响 random.shuffle(image_files) # 计算切分点 total len(image_files) train_count int(total * TRAIN_RATIO) train_list image_files[:train_count] val_list image_files[train_count:] # 创建输出目录 for split in [train, val]: (OUTPUT_DIR / split / images).mkdir(parentsTrue, exist_okTrue) (OUTPUT_DIR / split / labels).mkdir(parentsTrue, exist_okTrue) # 复制文件 def copy_files(file_list, split): for name in file_list: src_img IMAGE_DIR / f{name}.jpg src_lbl LABEL_DIR / f{name}.txt dst_img OUTPUT_DIR / split / images / f{name}.jpg dst_lbl OUTPUT_DIR / split / labels / f{name}.txt shutil.copy2(src_img, dst_img) if src_lbl.exists(): shutil.copy2(src_lbl, dst_lbl) else: print(f警告{name}.txt 标签缺失) copy_files(train_list, train) copy_files(val_list, val) print(f总图片数{total}训练集{len(train_list)}验证集{len(val_list)})这段脚本的关键参数是TRAIN_RATIO和SEED。TRAIN_RATIO设 0.8 是常见做法1000 张图的话训练集 800 张、验证集 200 张。SEED必须固定否则每次运行划分结果不同实验无法复现。脚本里先sort()再shuffle()是为了消除文件系统读取顺序的影响这个细节很多人忽略导致换台机器跑出来的划分结果不一样。3.2 类别均衡检查别让验证集里没有某类目标随机划分有个隐患某些稀有类别可能全部被分到训练集验证集里一个都没有导致评估时该类别的 AP 无法计算。1000 张图里如果某个类别只有几十个实例这个问题出现的概率不低。检查方法很简单统计训练集和验证集里每个类别的实例数。from collections import Counter def count_classes(label_dir): counter Counter() for txt_file in Path(label_dir).glob(*.txt): with open(txt_file, r) as f: for line in f: class_id int(line.strip().split()[0]) counter[class_id] 1 return counter train_counter count_classes(OUTPUT_DIR / train / labels) val_counter count_classes(OUTPUT_DIR / val / labels) print(训练集类别分布, dict(train_counter)) print(验证集类别分布, dict(val_counter)) # 检查验证集是否有类别缺失 all_classes set(train_counter.keys()) | set(val_counter.keys()) for cls in all_classes: if val_counter.get(cls, 0) 0: print(f警告类别 {cls} 在验证集中没有实例)如果发现验证集缺失某类解决办法有两个一是换随机种子重新划分二是手动把训练集里包含该类别的图片挪几张到验证集。我一般会先跑三次不同种子选一个类别分布最均匀的。3.3 划分后的目录结构验证划分完成后目录结构应该是这样的datasets/split/ ├── train/ │ ├── images/ (800 张 jpg) │ └── labels/ (800 个 txt) └── val/ ├── images/ (200 张 jpg) └── labels/ (200 个 txt)验证方法分别统计images和labels目录下的文件数量两者必须一致。如果 labels 比 images 少说明有图片没有对应标签训练时框架会报错或跳过。用一行命令就能查# Linux/macOS echo train images: $(ls datasets/split/train/images | wc -l) echo train labels: $(ls datasets/split/train/labels | wc -l) echo val images: $(ls datasets/split/val/images | wc -l) echo val labels: $(ls datasets/split/val/labels | wc -l)四个数字应该两两相等。如果不相等回到 3.1 的脚本里看警告信息找到缺失的标签文件。4. 从零跑通 YOLO 训练配置文件、超参与训练命令4.1 数据集 YAML 配置文件的写法YOLOv5 和 YOLOv8 都用一个 YAML 文件来描述数据集路径和类别。这个文件必须放在项目根目录或指定路径下内容如下# road_vehicle.yaml path: /home/user/datasets/split # 数据集根目录绝对路径 train: train/images # 训练集图片路径相对于 path val: val/images # 验证集图片路径相对于 path nc: 2 # 类别数根据实际修改 names: # 类别名称列表顺序必须和 class_id 对应 0: car 1: buspath建议写绝对路径避免训练时工作目录变化导致找不到数据。nc是类别数必须和 YOLO 标签里的最大class_id加一相等。names的顺序就是class_id的顺序写反了模型会把 car 认成 bus。如果类别多可以用列表形式names: - car - bus - truck - motorcycle4.2 训练命令与关键超参数YOLOv8 的训练命令最简洁yolo detect train \ dataroad_vehicle.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/train \ nameroad_vehicle_exp1逐参数说明data指向 4.1 的 YAML 文件model是预训练权重yolov8n.pt是最小的 nano 版本1000 张图用 nano 或 small 就够用 large 容易过拟合epochs100是训练轮数1000 张图通常 50-100 轮收敛imgsz640是输入分辨率如果原图是 1920x1080缩放到 640 后小目标会变模糊可以考虑 960 或 1280但显存占用会翻倍batch16根据显存调整8G 显存跑 640 分辨率大概能到 16lr00.01是初始学习率YOLOv8 默认用 SGD 时 0.01 是常用值patience20表示 20 轮验证指标不提升就早停省时间。YOLOv5 的命令类似但参数名略有不同python train.py \ --data road_vehicle.yaml \ --weights yolov5s.pt \ --epochs 100 \ --img 640 \ --batch 16 \ --project runs/train \ --name road_vehicle_exp14.3 训练过程监控与日志解读训练开始后控制台会输出每轮的指标。重点看三个box_loss、cls_loss、mAP0.5。box_loss是边界框回归损失正常应该持续下降cls_loss是分类损失同样下降mAP0.5是 IoU 阈值 0.5 时的平均精度应该上升。如果box_loss下降但mAP不升可能是学习率太大或数据标注有问题。如果cls_loss震荡不降检查类别是否均衡。训练日志会保存在runs/train/road_vehicle_exp1/下包括results.csv、weights/best.pt、weights/last.pt。best.pt是验证集 mAP 最高的权重推理时用这个。results.csv可以用 pandas 读取画曲线import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/train/road_vehicle_exp1/results.csv) df.columns df.columns.str.strip() # 列名可能有空格 plt.figure(figsize(12, 4)) plt.subplot(1, 2, 1) plt.plot(df[epoch], df[train/box_loss], labeltrain box loss) plt.plot(df[epoch], df[val/box_loss], labelval box loss) plt.legend() plt.subplot(1, 2, 2) plt.plot(df[epoch], df[metrics/mAP50(B)], labelmAP0.5) plt.legend() plt.savefig(training_curve.png)如果train/box_loss持续下降但val/box_loss先降后升说明过拟合了解决办法是增加数据增强、减少模型参数量或提前停止。5. 避坑与排查标签转换、显存、类别错位的血泪经验5.1 现象训练 loss 正常但 mAP 始终为 0原因YOLO 标签的class_id从 1 开始写了而 YOLO 要求从 0 开始。或者类别名称和 ID 映射反了。解决打开任意一个 TXT 标签确认第一列数字是否从 0 开始且最大值小于nc。如果是 VOC 转过来的检查转换脚本里有没有做class_id - 1。5.2 现象训练到一半报 CUDA out of memory原因batch或imgsz设太大或者验证时没有释放显存。解决先把batch减半如果还报错就把imgsz从 640 降到 416。另外 YOLOv8 默认在训练结束后跑验证如果显存紧张可以加valFalse跳过训练中验证但这样就没有best.pt了不推荐。5.3 现象验证集 mAP 很高但实际推理时框全错原因推理时的图片预处理和训练时不一致。比如训练用了 letterbox 填充推理时直接 resize导致坐标映射错位。解决用框架自带的推理接口不要自己写预处理。YOLOv8 用yolo detect predict modelbest.pt sourcetest.jpgYOLOv5 用detect.py它们内部会做和训练一致的预处理。5.4 现象某些类别完全检测不到原因该类别实例数太少或者验证集里没有该类导致早停时选了不包含该类的权重。解决先按 3.2 检查类别分布如果某类实例少于 50 个考虑用数据增强 mosaic、mixup 或过采样。另外patience设太小可能导致模型还没学好稀有类就停了可以适当增大到 30-50。5.5 现象VOC 转 YOLO 后框整体偏移原因VOC 坐标是 1-based转换时没有减 1或者归一化时用了错误的宽高比如用了缩放后的尺寸而不是原图尺寸。解决转换脚本里先读原图width和height用(xmin - 1) / width计算归一化中心点 x(xmax - 1) / width计算归一化宽度。减 1 这一步不能省。6. 用 1000 张图验证训练是否真的收敛三个可复现的检查技巧训练跑完不是终点你得确认模型是真的学到了东西而不是靠数据泄露或过拟合刷出来的指标。第一个技巧是单图推理对比从验证集里挑 10 张图用best.pt推理把预测框和真实框画在同一张图上肉眼看有没有系统性偏移。如果所有框都往一个方向偏说明坐标转换有问题如果框大小对但类别错说明类别映射有问题。from ultralytics import YOLO import cv2 model YOLO(runs/train/road_vehicle_exp1/weights/best.pt) results model(datasets/split/val/images/road_0001.jpg) for r in results: im_array r.plot() # 绘制预测框 cv2.imwrite(pred_road_0001.jpg, im_array)第二个技巧是混淆矩阵检查YOLOv8 训练结束后会自动生成confusion_matrix.png在runs/train/road_vehicle_exp1/下。看对角线是否明显深于其他格子。如果 car 和 bus 之间有很多误判说明这两个类在特征上太接近需要增加区分性强的样本或调整类别定义。注意热词里提到的“yolo混淆矩阵总合不唯一”问题——如果矩阵行和列的总和不一致通常是验证时conf阈值和iou阈值设置不同导致的统一用默认值即可。第三个技巧是小目标专项验证从验证集里筛出所有包含小目标框面积小于 32x32 像素的图片单独跑一遍推理统计召回率。如果小目标召回率低于 0.3说明imgsz640不够需要提高到 960 或 1280 重新训练。1000 张图里如果小目标占比高这一步不能省。我自己的习惯是每次训练完先跑单图推理再跑混淆矩阵最后跑小目标统计。三个都过了才认为模型可用。这套流程帮我省了很多次“指标好看但实际不能用”的后悔药。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

RAG检索不准九成在入库:分类型语义切分与混合检索实战 2026/10/2 18:43:35

RAG检索不准九成在入库:分类型语义切分与混合检索实战

1. 为什么说 RAG 检索不准,九成的锅不在向量1.1 一个被反复验证的现场观察做过 RAG 实战的人大概率都经历过这个场景:知识库明明塞了几百份文档,用户问一个答案就在某份 PDF 第三页的问题,检索出来的却是另外一份毫不相干的文件里…

阅读更多 →
MySQL数据类型选型实战:从底层存储到索引性能的全面解析 2026/10/2 18:43:35

MySQL数据类型选型实战:从底层存储到索引性能的全面解析

MySQL 数据类型,很多人在学习 MySQL 的时候都会忽略这个基础知识,觉得就是几个类型而已,背一背就过去了。但实际上,我在实际项目中见过太多因为类型选错导致的线上事故:一张表存几年数据就膨胀到几十个GB,查…

阅读更多 →
HTML春节跨年代码实战:Canvas烟花与倒计时实现 2026/10/2 18:43:35

HTML春节跨年代码实战:Canvas烟花与倒计时实现

简介:这套HTML跨年互动页面源码包面向前端初学者与节日页面爱好者,用轻量代码解决了在除夕营造倒计时、零点烟花与背景音乐一体化的庆祝需求。压缩包共5个文件、约8KB,包含4个html页面与1个txt说明,各html文件分别承担零点烟花主效…

阅读更多 →
Flutter插件鸿蒙适配实战:image_picker_plus移植OpenHarmony全记录 2026/10/2 18:43:35

Flutter插件鸿蒙适配实战:image_picker_plus移植OpenHarmony全记录

最近我把一个持续维护两年多的 Flutter 项目往 OpenHarmony 上迁移,业务层面倒还好说,最后卡在了一个绕不开的三方库上:image_picker_plus。这个库在 Android/iOS 上几乎一条龙包办了图片和视频选择、相机拍摄、多选、压缩、缩略图&#xff0…

阅读更多 →
Codex接入Jev实战:API Key配置、Skill编写与401报错排查指南 2026/10/2 18:43:35

Codex接入Jev实战:API Key配置、Skill编写与401报错排查指南

1. 为什么“Codex Jev”这个组合值得认真折腾 第一次看到“给Codex配上Jev,直接起飞”这个说法,我的反应是:又是一个听起来很爽、实际踩坑无数的组合。但真正动手把 Codex 和 Jev 接起来跑通之后,我承认这句话不算夸张——前提是…

阅读更多 →
大模型API聚合平台选型与落地:协议兼容、故障路由、密钥治理全解析 2026/10/2 18:43:29

大模型API聚合平台选型与落地:协议兼容、故障路由、密钥治理全解析

过去两年我一直在帮团队做大模型 API 的接入和网关建设,接触了不少第三方大模型 API 聚合平台,也自己动手搭过、替换过、踩过坑。到了 2026 年,市面上的模型更多了,API 聚合平台也不再是简单的“转发工具”,协议兼容、…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉