车辆检测数据集与YOLO11训练全流程指南 简介面向交通道路监控场景的车辆检测数据集现整理为一份PDF指引文档。数据集包含1000张真实场景高质量图片覆盖城市道路、高速公路、农村道路及车辆遮挡、严重遮挡等复杂情况并划分为Auto、Bus、Car、LCV、Motorcycle、Multi-Axle、Tractor、Truck共8个类别既适合目标检测算法研究与模型迭代也可作为监控场景通用车辆检测项目的数据补充。文档详细说明采用labelimg标注的高质量标签体系配套提供VOC(xml)、COCO(json)、YOLO(txt)三种常见数据集格式可直接接入YOLO等算法训练同时附赠YOLO11一键训练脚本支持GPU(GPUs)、CPU、Mac(M芯片)多平台并附博主训练结果日志供参考便于对比调参。资源为1个PDF文件大小7.19MB内附数据集基本情况介绍、labelimg标注截图及百度网盘获取方式目前已有1333人浏览学习适合需要真实交通车辆数据做训练、验证或业务落地的开发者。1. 目标检测的第一步先要一份能直接开训的车辆数据集目标检测项目里最耽误进度的往往不是模型调参而是数据准备——格式不一致、类别ID对不上、训练脚本跑不通任何一环都能卡住大半天。这份车辆检测数据集一共1000张真实场景图片覆盖城市道路、高速道路、农村道路还专门包含车辆遮挡和严重遮挡样本标注分为Auto、Bus、Car、LCV、Motorcycle、Multi-Axle、Tractor、Truck共8类每张图同时提供VOC(xml)、COCO(json)、YOLO(txt)三套标签。它另外附带一套YOLO11一键训练脚本GPU(GPUs)、CPU、Mac(M芯片)三个平台都能直接跑。适合两类人做交通道路监控、通用监控场景车辆检测的从业者以及刚接触YOLO11训练、想跳过数据准备直接跑通完整流程的开发者。资源以PDF索引文件形式分享里面是数据集说明和网盘链接拉到文末能看到获取方式。2. 车辆检测数据集拆解8类标注与真实场景覆盖度2.1 八个类别怎么划分Auto、Bus、Car到Multi-Axle拿到数据集先看类别清单这份数据沿用了道路监控里比较常见的分类习惯。Auto对应小型轿车Bus是公交/客车Car这里更多指微型车或两厢小车LCV是轻型商用车面包车、轻卡一类Motorcycle覆盖摩托车和电动两轮Multi-Axle指多轴挂车或重载牵引车Tractor是拖拉机/农用牵引车Truck是标准卡车。8个类别的设定比只分“轿车/卡车”两类的粗标签要实用得多因为监控场景里货车和挂车的形态差异非常大合并成一个大类会让模型对轴数多的车识别不稳定。类名对应车型高频出现位置Auto小型轿车三厢/两厢城市道路、小区出入口Bus公交、客车主干道、公交站Car微型车、小型车停车场、狭窄道路LCV轻型商用车面包车/轻卡物流园区、城乡结合部Motorcycle摩托车、电动两轮车非机动车道、路口Multi-Axle多轴挂车、重载牵引车高速、物流枢纽Tractor拖拉机、农用牵引车农村道路、田间路口Truck标准卡车/货车高速、国道这8类里Auto和Car的边界最容易让人困惑。我在几个交通数据集里见过类似命名有的项目把Car直接并入Auto有的把Car当成“小尺寸轿车”单独保留。实际使用时要看你自己的业务需求如果监控画面里只需要区分“小客车”和“大货车”可以把Auto、Car合并后重新映射ID后面避坑章节我会专门说这个事。2.2 labelimg标注的成色遮挡车、密集车与框质量数据集说明里明确写了用labelimg标注。labelimg是目标检测标注里最常用的图形化工具导出VOC格式的xml是一键操作绝大多数标注团队都用它所以标注文件结构非常规整。从质量角度看我更关注两个信息一是标注框是否贴合目标边缘二是严重遮挡场景下有没有坚持标注。很多低成本数据集的标注员遇到两车交叠时直接跳过导致模型在遮挡场景里彻底失灵。这份数据专门列出“车辆遮挡、车辆严重遮挡”说明这两类样本是被刻意采集和标注过的对监控场景很关键。我建议你做一次抽检用labelimg打开任意20张图重点看三类画面——遮挡车、夜间车、密集排队车。遮挡车的框如果出现大范围包住两个目标的情况说明标注员在靠猜测画框密集车流里如果大量漏标训练出来的模型在早晚高峰就会疯狂漏检。这类检查不做后面迁移到自己的业务场景时容易翻大车。2.3 这份数据能用在哪又在哪里露怯适用场景非常明确交通道路监控下的车辆检测包括城市道路卡口、高速收费站、路口信号灯抓拍这类固定机位画面以及作为通用监控场景车辆检测数据的补充。所谓“补充”的意思是如果你手头已经有一套监控数据集但车辆类别太少可以拿这1000张图把类别覆盖补全尤其是Multi-Axle和Tractor这两类在普通城市数据里很稀缺的样本。边界也很清楚航拍视角无人机俯拍、夜间红外、雨雾天气、车内视角这四类不在这份数据的覆盖范围内。如果你要做的是开阔路面上的平视监控这份数据的场景吻合度很高如果是俯拍或恶劣天气场景建议把这份数据当作预训练基础集再叠加你自己采集的几百张目标场景图而不是直接拿来做最终模型。3. VOC、COCO、YOLO三套标签从目录结构到坐标换算的完整对比3.1 三套格式各自长什么样同一批标注给三种格式看起来是体贴实际是给自己留了一条转换后路。VOC格式每张图对应一个xml文件XML里写的是目标的类名和边界框绝对像素坐标xmin、ymin、xmax、ymax目录结构通常是JPEGImages、Annotations、ImageSets三件套。COCO格式把整个数据集的标注汇总到一个json文件里每条标注记录用[x, y, width, height]表示边界框注意这里的x、y是框左上角坐标不是中心点。YOLO格式每张图对应一个txt文件每行是一个目标格式是“类别ID x_center y_center width height”四个坐标全部归一化到0到1之间。格式标注文件坐标形式是否归一化典型目录VOCxml每图一个xmin, ymin, xmax, ymax否绝对像素JPEGImages AnnotationsCOCOjson整个集一个x, y, width, height否绝对像素annotations/*.jsonYOLOtxt每图一个x_center, y_center, width, height是0~1images/ labels/三种格式之间转换是目标检测训练的日常操作因为Ultralytics的YOLO系列训练框架只认YOLO格式即便你用COCO预训练权重数据入口也建议统一转成txt。转换脚本网上很多但能一次跑通不出错的很少主要坑在坐标公式和类别映射上。3.2 从VOC(xml)转YOLO(txt)中心点坐标换算VOC转YOLO的公式很简单x_center (xmin xmax) / 2 / 图片宽y_center对高度同理框宽高则用(xmax - xmin)/宽。公式不难难的是“图片宽高从哪来”。VOC的xml里本来就有size节点但标注工具写入的size可能和实际图片尺寸不一致比如图片被预处理脚本压缩过但xml没更新这时候按xml里的size做归一化所有框都会偏移。import xml.etree.ElementTree as ET from PIL import Image from pathlib import Path CLASS_NAMES [Auto, Bus, Car, LCV, Motorcycle, Multi-Axle, Tractor, Truck] def voc_to_yolo_txt(xml_file, img_path, out_txt): # 宽高以原图为准不要直接信任xml里的size节点 w, h Image.open(img_path).size tree ET.parse(xml_file) root tree.getroot() lines [] for obj in root.findall(object): name obj.find(name).text if name not in CLASS_NAMES: continue cls_id CLASS_NAMES.index(name) box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) xc (xmin xmax) / 2.0 / w yc (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) with open(out_txt, w) as f: f.write(\n.join(lines) \n)这段脚本的关键在CLASS_NAMES列表的顺序它直接决定输出txt第一列的类别ID。YOLO的类别编号完全由这个列表和训练配置文件里的names数组决定两边必须完全一致。我在刚接触YOLO时吃过这个亏转换脚本里按类名字母序排列训练yaml里按自己方便的顺序写训练出来loss正常但mAP是0血泪经验后面细说。另外要注意xmin可能为负数或xmax大于图片宽度这类越界框转出来后坐标值超过1虽然训练框架会自动裁剪但最好在转换时做一次过滤。3.3 从COCO(json)转YOLO(txt)bbox字段与类别映射COCO的json里类别信息在categories数组标注信息在annotations数组每条annotation的bbox字段是[x, y, width, height]这个和VOC的[xmin, ymin, xmax, ymax]完全是两套语义转换公式也要变x_center x width/2再除以图片宽。import json from pathlib import Path def coco_to_yolo_txt(coco_json, out_dir): with open(coco_json, encodingutf-8) as f: data json.load(f) images {img[id]: img for img in data[images]} # 类别映射不允许直接enumerate必须按数据集本身的顺序来 cat2cls {cat[id]: i for i, cat in enumerate(data[categories])} anns_by_img {} for ann in data[annotations]: anns_by_img.setdefault(ann[image_id], []).append(ann) for img_id, img in images.items(): w, h img[width], img[height] lines [] for ann in anns_by_img.get(img_id, []): x, y, bw, bh ann[bbox] cls_id cat2cls[ann[category_id]] xc (x bw / 2) / w yc (y bh / 2) / h lines.append(f{cls_id} {xc:.6f} {yc:.6f} {bw / w:.6f} {bh / h:.6f}) stem Path(img[file_name]).stem out_file Path(out_dir) / f{stem}.txt out_file.write_text(\n.join(lines) \n if lines else )这里有个很隐蔽的问题data[categories]的顺序不一定是0到7排列好的。有些数据集工具导出json时会把类别按字母序排有些按标注时间排直接enumerate拿到的ID顺序和你的业务分类对不上。正确做法是先打印categories数组看一眼原始顺序再和YOLO训练时的names顺序对齐。COCO的file_name字段有时带子目录前缀用Path(...).stem取文件名时不会有问题但如果图片实际在别的目录输出txt的路径要自己拼。4. YOLO11一键训练脚本GPU、CPU、Mac三平台的启动与调参4.1 一键训练脚本在你跑之前做了什么这份资源里附带的不只是一个训练脚本而是一套启动流程检查目录结构、校验图片和标签是否一一对应、统计每类目标数、生成data.yaml、加载YOLO11预训练权重、启动训练。这套流程的价值在于它把最容易出错的数据校验环节自动化了。如果你拿到的是原始数据集第一步永远是把图片文件和txt标签放在同一级目录确保文件名一一对应否则训练时大量图片没标签模型什么也学不到。训练配置文件的格式是Ultralytics的YAML标准path指向数据集根目录train和val填相对路径或绝对路径names列表的顺序就是类别ID编号。下面这段是典型的vehicle.yaml内容路径替换成你自己的实际目录即可from ultralytics import YOLO import yaml data_cfg { path: /path/to/vehicle_dataset, # 数据集根目录 train: images/train, # 训练图片目录相对path val: images/val, # 验证图片目录 names: [Auto, Bus, Car, LCV, Motorcycle, Multi-Axle, Tractor, Truck] } with open(vehicle.yaml, w) as f: yaml.safe_dump(data_cfg, f, allow_unicodeTrue) model YOLO(yolo11n.pt) # 自动下载预训练权重 results model.train( datavehicle.yaml, epochs100, imgsz640, batch16, device0, # 指定GPU设备 workers4, cacheTrue # 小数据集可直接缓存到内存 )注意path如果用相对路径Ultralytics会以yaml文件所在目录为基准解析我习惯写成绝对路径省去一级一级找目录的麻烦。yolo11n.pt是YOLO11的Nano版本权重文件几十MB第一次运行会自动从官方源下载之后离线也能跑。4.2 GPU(GPUs)平台多卡参数与batch分配单卡训练时device填0即可多卡填0,1或0,1,2,3Ultralytics会自动拉起分布式训练。一个关键认知是batch参数在多卡下是“每卡”的batch_size不是总batch。两卡各16等于总batch 32学习率策略会自动适应不需要手动按卡数放大。显存方面yolo11n在640分辨率、FP16精度下占显存大约4-6GByolo11s涨到8GB左右yolo11m要12GB往上按自己的卡决定选哪个规格。我一般用这套基准参数起步batch16、imgsz640、workers4、cacheTrueNano模型跑100个epoch在单张RTX 3060上大约一个多小时。训练过程中重点盯四个字段train/box_loss要稳定下降val/box_loss不能和train差太多mAP50决定是否可用mAP50-95反映框的精确度。这份数据集附带博主训练日志你可以对照日志看每个epoch的指标走势判断自己的loss算不算正常。4.3 CPU平台先确认要等多久CPU训练纯属耐力活但1000张图的小数据集不是不能跑。关键在参数压缩imgsz从640降到544batch降到8epochs先设10个试跑看单epoch耗时再决定总量。我实测一台8核笔记本纯CPU跑yolo11n、imgsz640、1000张图单epoch大约6到8分钟30个epoch要3个多小时能接受就铺开跑不能接受就再降imgsz。Windows上特别注意workers必须设为0或2设8大概率报DataLoader worker exited unexpectedly这是Python多进程在Windows下的老毛病。model.train( datavehicle.yaml, epochs50, imgsz544, batch8, devicecpu, workers0, # Windows设0Linux可以设2 cacheTrue )CPU模式下cacheTrue特别重要。1000张图全缓存到内存可能占用几个GB但能省掉每个epoch重复读盘的IO时间整体提速明显。如果内存紧张可以只缓存部分数据Ultralytics也支持cacheram或cachedisk两种策略。4.4 Mac(M芯片)平台mps设备与torch版本M系列芯片跑YOLO11要用Apple的MPS后端对应devicemps。Ultralytics从8.3.0版本开始完整支持yolo11PyTorch需要2.0以上建议直接装当前最新稳定版。一个已知的坑是mps对部分算子的支持不完整运行到某些层会报NotImplementedError后面避坑章节会展开。这里先给一组相对稳的参数组合关闭自动混合精度因为mps的half支持不稳定开了容易训着训着出现NaN loss。model.train( datavehicle.yaml, epochs50, imgsz640, batch8, devicemps, # M1/M2/M3芯片走mps workers2, cacheTrue, ampFalse # mps后端建议关掉amp )我自己的体验是M芯片跑yolo11n比同价位Intel CPU快一倍以上但和NVIDIA独显比还有明显差距。如果你在公司有GPU机器Mac可以只做数据预处理和结果可视化训练放GPU上跑如果只有Mac1000张图50个epoch一晚上也能跑完不算太离谱。5. 避坑手记YOLO11车辆检测训练中的4个典型翻车现场5.1 现象loss正常下降验证集mAP却是0训练到第10个epochtrain/box_loss掉到了0.05以下val/box_loss看着也正常但每个epoch结束打印的mAP50一栏全是0。这个现象我第一次遇到时差点把数据集删了重标。实际原因是类别ID错位转换脚本里CLASS_NAMES和训练yaml里names的顺序不一致比如转换脚本按字母序排了Auto在前而yaml里把Truck排在了第0位模型学到的类别编号和真实标签对不上。解决方法是统一一个class_names列表转换脚本和yaml都从同一个地方生成。排查时打开一个txt文件看一眼首列数字再对照xml里的类名几秒钟就能确认。head -n 5 labels/train/0001.txt如果首列出现大于7的数字说明ID越界如果首列数字对应的类名和xml里框的类名对不上说明排序错乱。从那以后我要求任何数据集交付必须附带一份类别映射说明文档。5.2 现象Mac的mps训练到一半报not implemented用devicemps启动训练第一个epoch正常跑到第二或第三个epoch中断报错信息类似“Could not run aten::_slow_conv2d_forward with arguments from the MPS backend”。这不是你代码写错了是PyTorch的mps后端对某些卷积算子的支持还没覆盖全同一个版本下yolo11n可能跑通、yolo11m跑到某个层就崩。解决按优先级尝试先关amp用fp32跑大多数情况下能解决还崩就把imgsz降到544减少某些层的计算路径再不行退到devicecpuM芯片跑CPU也不慢。升级PyTorch到nightly版本能覆盖更多算子但可能引入新问题我一般不用。5.3 现象CPU平台一个epoch要跑半小时1000张图8核笔记本yolo11nimgsz640单epoch半小时不一定是机器问题多半是数据加载在拖后腿。Windows下workers设了8每个epoch结束都要等数据加载多次报DataLoader worker exited unexpectedly。另外一个常见原因是没开cache每次迭代都从机械硬盘或网络盘读图片IO成为瓶颈。解决方法是workers0或2cacheTrueimgsz降到544。还有一个小技巧先用10个epoch跑一遍看单epoch耗时是否线性稳定如果前几个epoch慢、后面突然变快大概率是系统在做磁盘缓存预热不用太担心。5.4 现象验证集指标好看实拍视频里全是漏检mAP50到了0.87把模型接到实拍视频流上白色货车漏检、两车交叠时漏检、黄昏光线下一辆都测不准。这个问题分两方面看一是验证集本身“简单”了——如果数据划分时把同一场景的连续帧同时分进train和val验证集和训练集高度相似指标虚高二是遮挡样本占比太低模型对遮挡目标的泛化能力本来就不足。解决方法是把数据集里标注明确为“车辆遮挡”“严重遮挡”的图单独挑出来做测试集用这个子集重新评估同时检查Auto和Car的标签一致性如果两个类在部分样本里标注语义重叠模型在边界样本上就会摇摆。6. 拿到数据后先跑这三段检查类别分布、空标签与验证集可视化6.1 类别分布扫描与空标签检测训练前花10分钟跑一个统计脚本能避免训练到一半才发现数据问题的尴尬。这段脚本读取labels目录下所有txt统计每个类别的目标总数同时找出空标签文件。对1000张图的数据集扫描时间在几十秒以内建议直接复用。from pathlib import Path from collections import Counter def scan_labels(label_dir): counter Counter() empty_files [] for txt in Path(label_dir).glob(*.txt): lines [ln.strip() for ln in txt.read_text().splitlines() if ln.strip()] if not lines: empty_files.append(txt.stem) continue for line in lines: cls_id int(line.split()[0]) counter[cls_id] 1 return counter, empty_files label_dir vehicle_dataset/labels/train counter, empty_files scan_labels(label_dir) print(类别分布:, dict(sorted(counter.items()))) print(空标签文件数:, len(empty_files))运行后先看有没有空标签文件再看每个类别的目标数是否均衡。如果Motorcycle只有几十个目标而Truck有几百个说明这个类本身稀缺训练时可能欠拟合要考虑加数据增强或降低类别损失权重。类别分布表也建议存档训练结束后和验证集指标放一起分析能看出哪一个类拉低了整体mAP。6.2 验证集可视化与训练日志留存第二个固定动作是跑一次验证集批量预测把预测结果存成带框图片肉眼检查有没有漏检和错类。yolo predict modelruns/train/exp/weights/best.pt sourcevehicle_dataset/images/val save_txttrue save_conftrue projectvisual_check重点关注两类错误一是大量漏检说明模型对某些形态的车还没学会二是Auto和Car互相误判说明这两个类在标注时边界就没划清楚考虑合并类别重新训练。训练日志也不要只留在Ultralytics的runs目录我习惯把每次实验的yaml、类别分布表、最终mAP指标汇总到一个文本文件里换数据集或者调参时翻出来对比特别有用。从那以后我拿到任何目标检测数据集不管标注多“官方”第一件事永远是跑一次类别分布扫描加一次验证集可视化两步做完再开训练。这个习惯已经救过我至少两次翻车一次是空标签文件混进训练集一次是类别ID错乱但loss曲线看起来完全正常。完整的转换脚本和训练日志都在分享包里获取方式在文末拉到页面底部就能看到网盘链接下载后记得先跑一遍第6章的检查脚本希望帮到你。本文还有配套的精品资源点击获取