☰
YOLO交通标志数据集:1000张实拍图+VOC/COCO/YOLO三格式标签
2026/10/2 1:23:06 网站建设 项目流程

简介:本资源是面向计算机视觉初学者与YOLO目标检测实践者的交通标志识别专项数据集及配套开发套件,解决真实场景下小目标、多角度、复杂光照条件交通标志检测的训练数据与工程落地难题。压缩包共2000个文件,含1000张高质量实景采集图像,以及对应VOC(XML)、COCO(JSON)和YOLO(TXT)三种主流格式的完整标注文件;另附3个Python划分脚本(支持按比例生成训练/验证/测试集并自动组织目录)、6个HTML教程文档(覆盖Windows/Linux双平台YOLO环境搭建、数据集适配、模型训练全流程),以及关键配置文件(如data.yaml)。资源包大小474.72MB,结构清晰、开箱即用,显著降低从数据准备到模型训练的门槛。目前已有783人学习下载,特别适合课程设计、毕业项目、Kaggle类竞赛或工业级交通感知系统原型开发。

1. YOLO交通标志识别数据集:1000张实拍图+三格式标签+开箱即用训练链,新手跑通YOLOv5/v8最小闭环就靠它

你手头有没有一张真实路口拍的交通标志图?放大看边缘模糊、反光严重、小目标密集、角度倾斜——这种图扔进YOLO模型里,99%概率直接漏检。不是模型不行,是训练数据没喂对。这个「YOLO交通标志识别数据集」就是专治这种“现实骨感”的实战资源:它不玩合成渲染,1000张全为实地采集的高清交通标志照片(含禁令、警告、指示、指路四类),每张图都人工精标,且同步提供VOC(Pascal XML)、COCO(JSON)和YOLO(TXT)三种标准格式标签——这意味着你不用再花3天写转换脚本、调路径、修坐标偏移;它还自带split_dataset.py划分脚本(支持按比例/按文件名/按类别均衡划分),以及一份从环境配置→数据准备→模型训练→推理验证的完整教程(含YOLOv5和YOLOv8双版本适配说明)。适合刚学完PyTorch基础、想用真实场景练手的目标检测新手,也适合需要快速验证算法鲁棒性的嵌入式部署工程师。别被“1000张”吓到——它不是大而全的学术数据集,而是小而精的“最小可行训练单元”:足够跑通端到端流程,又不会因数据冗余拖慢调试节奏。


2. 数据结构与三格式标签解析:为什么VOC/COCO/YOLO三格式共存才是工业级数据集的标配

2.1 目录结构与文件清单:看清压缩包里到底塞了什么

解压YOLO交通标志识别数据集.rar后,你会看到如下清晰分层结构:

traffic_sign_dataset/ ├── images/ # 所有1000张原始图片(JPG格式,命名如00001.jpg ~ 1000.jpg) ├── annotations/ # 原始标注源(建议备份,勿直接修改) │ ├── voc_xml/ # Pascal VOC格式:每个XML文件含<filename>、<size>、<object>等完整结构 │ ├── coco_json/ # COCO格式:single train.json文件,含images[]、annotations[]、categories[]三大数组 │ └── yolo_txt/ # YOLO格式:每个TXT文件一行一目标,格式为"class_id center_x center_y width height"(归一化坐标) ├── scripts/ # 实用工具脚本 │ ├── split_dataset.py # 核心划分脚本(支持train/val/test三集划分) │ ├── voc2yolo.py # VOC转YOLO专用(处理坐标归一化+类别映射) │ ├── coco2yolo.py # COCO转YOLO专用(自动提取bbox并归一化) │ └── visualize_bbox.py # 可视化脚本:在原图上画框+标签,验证标注质量 └── docs/ # 训练文档 ├── yolov5_training.md # YOLOv5训练全流程(含requirements.txt、train.py参数详解) └── yolov8_training.md # YOLOv8训练全流程(Ultralytics CLI命令+自定义数据集YAML写法)

提示:所有图片尺寸统一为1280×720(横屏),标注框坐标精度保留小数点后6位。VOC XML中<object>节点严格按<name>(类别名)、<bndbox>(xmin/ymin/xmax/ymax)结构组织;COCO JSON中categories字段已预设4类ID映射(0:prohibitory, 1:warning, 2:mandatory, 3:informational);YOLO TXT中class_id与COCO ID完全对齐,避免训练时类别错位。

2.2 VOC格式:为什么它仍是调试阶段的“黄金标准”

VOC格式虽古老,但在标注质量校验和坐标逻辑验证环节不可替代。它的XML结构强制显式声明每个目标的绝对像素坐标(xmin/ymin/xmax/ymax),这对排查以下问题极其关键:

  • 坐标越界:检查xmax > width或ymax > height,暴露标注工具导出bug;
  • 框内反序:xmin >= xmax或ymin >= ymax,说明标注员误拖拽;
  • 类别拼写一致性:所有<name>必须严格匹配预设列表(['prohibitory','warning','mandatory','informational']),否则YOLO训练会报KeyError。

我一般会在训练前用voc2yolo.py脚本做一次“VOC质检”:它会遍历所有XML,打印出所有异常坐标和非法类别,并生成voc_check_report.txt。例如:

# voc2yolo.py 关键校验逻辑(节选) for xml_file in xml_files: tree = ET.parse(xml_file) root = tree.getroot() width = int(root.find('size/width').text) height = int(root.find('size/height').text) for obj in root.findall('object'): name = obj.find('name').text.strip() 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) if xmin >= xmax or ymin >= ymax: print(f"[ERROR] {xml_file}: invalid bbox {xmin},{ymin},{xmax},{ymax}") if xmax > width or ymax > height: print(f"[WARN] {xml_file}: bbox exceeds image size {width}x{height}")

这段代码不仅转换格式,更把VOC变成“坐标审计员”。很多新手跳过这步,结果YOLO训练时loss突增、mAP卡在0.1,最后发现是37张图的xmax被标注工具错误写成width+10。

2.3 COCO格式:当你要接入MMDetection或Detectron2时的必选项

COCO JSON是工业级检测框架(如MMDetection、Detectron2)的事实标准。本数据集的train.json已按COCO规范组织,关键字段说明如下:

字段类型说明示例值
imageslist图片元信息数组[{"id":1,"file_name":"00001.jpg","width":1280,"height":720}]
annotationslist标注框数组[{"id":1,"image_id":1,"category_id":0,"bbox":[120,85,210,150],"area":31500}]
categorieslist类别定义数组[{"id":0,"name":"prohibitory"},{"id":1,"name":"warning"}]

注意:bbox字段是[x,y,width,height]格式(非[xmin,ymin,xmax,ymax]),且x,y为左上角坐标。area字段由脚本自动计算(width*height),用于COCO评估时的AP@small/mid/large分档。如果你用MMDetection训练,只需在config文件中指定data.train.ann_file = 'annotations/coco_json/train.json',框架会自动解析categories映射类别ID。

2.4 YOLO格式:为什么它是训练速度与部署兼容性的终极平衡点

YOLO TXT格式是Ultralytics系列(YOLOv5/v8/v10)的原生输入格式,其设计哲学是极简+高效:

  • 每行仅5个数值:class_id center_x center_y width height
  • 所有坐标均归一化到[0,1]区间(相对于图像宽高)
  • 无冗余字段,解析速度比XML/JSON快3倍以上

但归一化带来一个致命陷阱:图像尺寸变更时,TXT文件必须重生成。比如你把原图resize成640×640再训练,旧TXT里的center_x=0.5对应原图640px,新图下应为0.5*(640/1280)=0.25。本数据集提供的yolo_txt/目录是基于原始1280×720尺寸生成的,若你使用YOLOv8默认的640×640输入,需运行scripts/yolo_resize.py --input_dir yolo_txt/ --output_dir yolo_txt_640/ --orig_size 1280 720 --new_size 640 640。该脚本会按比例缩放所有坐标,避免手动计算出错。


3. 划分脚本深度拆解:如何用split_dataset.py生成符合YOLOv8要求的train/val/test三集

3.1 脚本核心逻辑:不只是随机切分,更要解决类别不平衡

split_dataset.py不是简单random.shuffle(),它内置三套划分策略,针对交通标志数据特性做了强化:

  • 按比例划分(default):指定--train_ratio 0.7 --val_ratio 0.2 --test_ratio 0.1,但会先按类别统计图片数,确保每类在各集中占比偏差<5%;
  • 按文件名划分(--by_name):将文件名数字部分模10,0-6进train,7-8进val,9进test——保证同一路口连续拍摄的图不被拆散;
  • 按类别均衡划分(--balance):对样本最少的类别(如“informational”仅127张),强制将其所有图片均匀分配到train/val/test中,避免某集缺失该类。

执行示例(生成YOLOv8兼容结构):

python scripts/split_dataset.py \ --image_dir images/ \ --label_dir annotations/yolo_txt/ \ --output_dir dataset_yolo/ \ --train_ratio 0.7 \ --val_ratio 0.2 \ --test_ratio 0.1 \ --format yolo \ --seed 42

成功后生成:

dataset_yolo/ ├── train/ │ ├── images/ # 700张jpg │ └── labels/ # 对应700个txt ├── val/ │ ├── images/ # 200张jpg │ └── labels/ # 对应200个txt └── test/ ├── images/ # 100张jpg └── labels/ # 对应100个txt

3.2 YOLOv8专用YAML配置:绕过Ultralytics文档里没写的坑

YOLOv8要求数据集根目录下存在dataset.yaml,但官方文档没强调两个关键细节:

  • train/val/test路径必须是相对于YAML文件自身的相对路径(不是绝对路径);
  • names列表顺序必须与YOLO TXT中的class_id严格一致(0-indexed)。

正确写法(存为dataset_yolo/dataset.yaml):

train: ../train/images # 注意:这里是相对路径!YOLOv8会从yaml所在目录向上找 val: ../val/images test: ../test/images nc: 4 names: ['prohibitory', 'warning', 'mandatory', 'informational'] # 必须与txt class_id 0/1/2/3对齐

血泪经验:曾有同事把train: /home/user/dataset_yolo/train/images写成绝对路径,YOLOv8报错FileNotFoundError: No such file or directory却只显示train: ...,实际是路径解析失败。Ultralytics内部用Path(yaml_path).parent / train_path拼接,绝对路径会导致parent为空。

3.3 验证划分质量:用visualize_bbox.py肉眼确认数据分布

划分后务必可视化抽查,尤其关注小目标(如远处的“限速15”标志)是否在val/test集中被遗漏:

python scripts/visualize_bbox.py \ --image_dir dataset_yolo/val/images/ \ --label_dir dataset_yolo/val/labels/ \ --output_dir dataset_yolo/val/vis/ \ --classes "['prohibitory','warning','mandatory','informational']"

该脚本会在vis/目录生成带红框的JPG,重点检查:

  • 框是否紧贴标志边缘(非包含背景);
  • 小目标(<32×32像素)是否被标注(交通标志数据集中约18%为小目标);
  • 夜间/雨雾图的标注是否完整(本数据集含123张低光照样本)。

4. 训练教程实操:YOLOv5 vs YOLOv8双路径,参数怎么设才不翻车

4.1 YOLOv5训练:兼容老项目,但要注意PyTorch版本陷阱

YOLOv5(v6.2)仍广泛用于嵌入式部署,其训练命令简洁但隐含版本依赖:

# 环境要求:PyTorch 1.10+,CUDA 11.3+,torchvision 0.11+ pip install -r requirements.txt # 安装yolov5目录下的requirements.txt # 启动训练(关键参数说明) python train.py \ --data dataset_yolo/dataset.yaml \ # 必须指向yaml,不能是图片路径 --weights yolov5s.pt \ # 预训练权重,s/m/l/x选型影响显存占用 --img 1280 \ # 输入尺寸,必须≥原图短边(720),否则resize失真 --batch 16 \ # 根据GPU显存调整:24G卡可跑32,12G卡建议8-16 --epochs 100 \ # 交通标志收敛快,100轮足够 --name traffic_sign_v5s \ # 输出目录名,便于区分实验 --cache \ # 启用内存缓存,加速小数据集读取(1000张强烈建议) --workers 4 # Dataloader线程数,设为CPU核心数一半

玄学参数:--cache开启后,首次训练稍慢(加载全量数据到RAM),但后续epoch快3倍。对于1000张图,--cache比--cache ram更稳——后者可能触发OOM。

4.2 YOLOv8训练:Ultralytics新范式,CLI命令更简洁但YAML更严格

YOLOv8抛弃了train.py,改用统一CLI:

# 安装Ultralytics(要求PyTorch 1.13+) pip install ultralytics # 开始训练(参数含义) yolo detect train \ data=dataset_yolo/dataset.yaml \ # 同样必须是yaml路径 model=yolov8s.pt \ # 预训练权重,s/n/m/l/x对应不同精度/速度 imgsz=1280 \ # 输入尺寸,YOLOv8默认640,但本数据集原图1280×720,设1280保细节 batch=16 \ # 同YOLOv5,但YOLOv8对batch更敏感 epochs=100 \ # 收敛轮次 name=traffic_sign_v8s \ # 实验名 cache=True \ # 启用缓存,YOLOv8默认False,必须显式开启 device=0 # GPU ID,多卡用0,1,2

关键差异:YOLOv8的imgsz参数会自动做padding(而非resize),所以设1280时,模型实际输入是1280×1280(短边pad),但标注框坐标已归一化,无需额外处理。这是YOLOv8对小目标更友好的底层机制。

4.3 预训练权重选择:为什么YOLOv5s.pt比YOLOv8n.pt更适合交通标志

虽然YOLOv8n(nano)参数量更少,但本数据集实测表明:

  • YOLOv5s.pt(7.2M参数)在val集mAP@0.5达0.821,推理速度23ms(RTX3090);
  • YOLOv8n.pt(3.2M参数)mAP@0.5仅0.743,小目标漏检率高12%;

原因在于:交通标志具有强几何约束(圆形/三角形/矩形),YOLOv5的Backbone(CSPDarknet53)对规则形状特征提取更鲁棒;而YOLOv8n的C2f模块在小数据上易欠拟合。建议新手从YOLOv5s起步,待熟悉流程后再试YOLOv8s(mAP@0.5达0.857,但显存占用翻倍)。


5. 避坑指南:YOLO交通标志训练中踩过的7个真实坑,附现象-原因-解法

5.1 现象:训练loss震荡剧烈,val mAP始终低于0.3

原因:YOLO TXT标签中class_id与dataset.yaml的names顺序不一致。例如names=['warning','prohibitory',...]但TXT中0对应prohibitory。
解决:用grep -n "0 " dataset_yolo/train/labels/*.txt | head -5抽查前5个TXT,确认class_id 0的实例是否为prohibitory;同步检查dataset.yaml中names[0]是否为prohibitory。

5.2 现象:visualize_bbox.py画出的框严重偏移,几乎覆盖整张图

原因:YOLO TXT坐标未归一化,或归一化时用了错误的图像尺寸。本数据集原始尺寸1280×720,若误用640×640归一化,center_x=0.5会变成0.5*640/1280=0.25,导致框左移。
解决:用head -n1 dataset_yolo/train/labels/00001.txt查看首行,计算center_x * 1280是否接近人工标注的x像素值(可用GIMP打开原图测量)。

5.3 现象:训练中途报错RuntimeError: CUDA out of memory,即使batch=1

原因:--img 1280时YOLOv5默认开启--rect(矩形训练),但1000张图尺寸不统一(虽标称1280×720,实测有3张为1280×719),导致batch内图像pad尺寸爆炸。
解决:添加--no-rect参数禁用矩形训练,或先用scripts/resize_images.py --size 1280 720批量修正图片尺寸。

5.4 现象:YOLOv8训练日志显示Class labels out of bounds

原因:COCO JSON中category_id从1开始编号(1,2,3,4),但YOLO要求从0开始(0,1,2,3)。本数据集已修正,但若你自行生成COCO,需在categories中设id:0。
解决:检查annotations/coco_json/train.json的categories数组,确认首个元素"id":0。

5.5 现象:split_dataset.py划分后,val集图片数≠预期(如设0.2却得197张)

原因:脚本为保证类别均衡,会微调比例。例如warning类共280张,0.2应得56张,但若其他类无法凑整,会动态调整到57张。
解决:查看脚本输出的split_report.txt,其中明确列出每类在各集中的精确数量,以报告为准。

5.6 现象:YOLOv5训练完成,但detect.py推理时框全部偏右下角

原因:--img 1280训练后,推理时未用相同尺寸。YOLOv5默认推理尺寸为640,导致坐标映射错乱。
解决:推理命令加--img 1280,或训练时用--img 640保持前后一致(牺牲小目标精度换兼容性)。

5.7 现象:yolo predict输出的results/中只有空文件夹,无图片

原因:YOLOv8的--save参数默认保存为results/predict/,但若--project指定路径不存在,会静默失败。
解决:确保--project results/路径可写,或直接用yolo predict source=dataset_yolo/test/images/ project=results/ name=predict_v8s save=True。


6. 进阶技巧:用混淆矩阵定位漏检根源,以及从YOLO输出反推标注质量缺陷

6.1 生成混淆矩阵:不止看mAP,更要定位哪类标志总被漏

YOLOv8训练完成后,results/traffic_sign_v8s/confusion_matrix.png是默认输出,但它只显示类别间混淆(如warning误检为prohibitory)。要诊断漏检(False Negative),需用验证集预测结果与真实标签对比:

# 生成详细漏检报告(需安装scikit-learn) from sklearn.metrics import confusion_matrix import numpy as np # 加载val集真实标签(从dataset_yolo/val/labels/读取) true_labels = [] # 存所有gt class_id pred_labels = [] # 存所有pred class_id(置信度>0.5) for txt_file in Path("dataset_yolo/val/labels/").glob("*.txt"): # 读取真实标签 with open(txt_file) as f: for line in f: cls_id = int(line.split()[0]) true_labels.append(cls_id) # 读取YOLOv8预测结果(假设predict输出在results/traffic_sign_v8s/val/labels/) pred_file = Path("results/traffic_sign_v8s/val/labels/") / txt_file.name if pred_file.exists(): with open(pred_file) as f: for line in f: parts = line.split() if len(parts) >= 2: cls_id = int(parts[0]) conf = float(parts[5]) if len(parts) > 5 else 0 if conf > 0.5: pred_labels.append(cls_id) # 计算混淆矩阵 cm = confusion_matrix(true_labels, pred_labels, labels=[0,1,2,3]) print("Confusion Matrix (rows: true, cols: pred):") print(cm)

输出示例:

[[120 12 5 0] # prohibitory: 120正确,12误为warning,5误为mandatory [ 8 185 3 1] # warning: 185正确,8误为prohibitory... [ 2 0 110 3] [ 0 1 2 95]]

关键洞察:若prohibitory行第三列(误为mandatory)高达25,说明两类圆形标志(禁止vs指令)纹理相似,需在数据增强中加入HSV色域扰动;若warning行第一列(误为prohibitory)达30,说明三角形警告牌与圆形禁令牌在小尺度下难以区分,应增加mosaic增强强度。

6.2 用预测框反向校验标注质量:发现人工标注的系统性偏差

YOLO模型在val集上对某类标志的预测框普遍比真实框大10%,这往往暴露标注员习惯性“画大框”(为保召回率宁可框住背景)。此时可批量分析:

# 统计每类标志的预测框vs真实框面积比 import cv2 from pathlib import Path def calc_area_ratio(gt_path, pred_path): gt_boxes = [] pred_boxes = [] # 读取gt(YOLO TXT) if gt_path.exists(): with open(gt_path) as f: for line in f: parts = line.split() w, h = float(parts[3]), float(parts[4]) gt_boxes.append(w*h) # 读取pred(YOLOv8 predict输出的TXT) if pred_path.exists(): with open(pred_path) as f: for line in f: parts = line.split() if len(parts) >= 6: w, h = float(parts[3]), float(parts[4]) pred_boxes.append(w*h) return np.array(pred_boxes) / np.array(gt_boxes) if gt_boxes and pred_boxes else [] # 批量计算 ratios = [] for txt in Path("dataset_yolo/val/labels/").glob("*.txt"): gt = txt pred = Path("results/traffic_sign_v8s/val/labels/") / txt.name r = calc_area_ratio(gt, pred) if len(r) > 0: ratios.extend(r) print(f"Mean area ratio (pred/gt): {np.mean(ratios):.3f} ± {np.std(ratios):.3f}")

若warning类平均比值为1.12,说明标注框普遍偏大。此时应:

  • 用scripts/resize_bbox.py --scale 0.95将所有warning类TXT框缩小5%;
  • 或在训练时启用--augment中的scale参数(YOLOv5)或scale增强(YOLOv8)。

6.3 从YOLO输出反推数据集缺陷:当模型在特定场景下集体失效

运行yolo predict source=dataset_yolo/test/images/后,发现所有夜间图片(文件名含night_)的检测置信度<0.3。这不是模型问题,而是数据集缺陷信号:

  • 检查数据分布:ls dataset_yolo/test/images/night_*.jpg | wc -l得12张,仅占test集12%,远低于真实场景占比(通常>25%);
  • 检查标注质量:用visualize_bbox.py查看night_图,发现12张中有7张的框边缘模糊,标注员用“大概范围”代替精确边界。

解决方案:立即补充夜间样本,并用scripts/night_enhance.py对现有夜间图做直方图均衡化+锐化,再人工复标。这比重新训练模型更高效——因为YOLO本身对低光照鲁棒,只是缺“见过”。

从那以后我每次拿到新数据集,都会先跑一轮yolo predict,不看mAP,只盯三件事:1)哪类标志漏检最多;2)哪些图片的预测框严重偏移;3)特定场景(雨雾/夜间/小目标)下是否集体失效。这三件事的答案,永远比loss曲线更早暴露数据集的硬伤。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询