ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLO斑马线目标检测数据集:真实场景、三种标签格式与训练全解

YOLO斑马线目标检测数据集:真实场景、三种标签格式与训练全解 简介面向目标检测入门与实战的YOLO斑马线目标检测数据集精选1000张真实场景高质量图片覆盖不同光线、角度和道路环境下的斑马线样本使用LabelImg标注标注框质量高。压缩包内共2000个文件大小约200.4MB包含1000个XML、990个TXT标签文件以及HTML教程、Python脚本和YAML配置其中VOC、COCO、YOLO三种格式标签分别放在独立文件夹无需额外转换即可接入YOLO系列目标检测训练流程省去自行转换标注格式的步骤。除数据集外还附赠Linux与Windows双平台的YOLO环境搭建和训练教程以及训练集、验证集、测试集划分脚本支持自动生成ImageSets下的txt文件用户可根据不同任务比例自行切分数据。整套资源目录结构清晰从环境配置、数据划分到模型训练都有对应文档和脚本支撑适合课程设计、毕业设计或算法对比实验。目前已有320人浏览学习对有标注数据获取与格式适配需求的开发者来说是一套能快速落地的实用资源。1. YOLO斑马线目标检测数据集一千张真实场景图三种标签格式一次配齐做目标检测最烦的不是调参是数据。尤其是斑马线这种交通场景下的目标网上公开数据集要么是国外街景、要么标注质量参差不齐想训练一个能用的YOLO模型光清洗数据就得耗掉两三天。这套YOLO斑马线目标检测数据集是我目前见过比较省心的一套资源——一千张真实场景图片标注框质量高而且VOC、COCO、YOLO三种格式标签一次配齐不用自己写转换脚本。适合正在做交通场景识别、辅助驾驶相关课题的学生和工程师也适合刚入门YOLO想跑通完整训练流程的新手——它连环境搭建教程和训练教程都给你备好了照着走就能出结果。2. 三种标注格式并存为什么一份数据要同时给VOC、COCO和YOLO2.1 三种标签格式的本质区别很多第一次接触目标检测数据集的人会问既然YOLO最终用的是txt文件为什么还要给VOC和COCO两种格式这得从工具链说起。VOC格式是xml文件每个目标一个节点记录类别名和bounding box左上角、右下角坐标COCO格式是json文件整套标注集中在一个json里用segmentation、bbox这类字段描述目标而YOLO格式是txt文件一行一个目标五个数字分别是类别id和归一化后的中心点x、y、宽、高。三种格式对应不同的训练框架和工具链。VOC格式配合voc2yolo.py这类脚本可以任意转换COCO格式是detectron2、mmdetection这类框架的原生输入YOLO格式则直接被darknet、ultralytics YOLOv5/v8加载。这套数据集把三个格式都整理好了放在不同文件夹下意味着你无论用哪个框架拿到手就能开始训练不用先花半天时间写格式转换脚本——这步我踩过坑转格式踩坑比训练本身还耗时。2.2 数据集目录结构与标注文件清单拿到压缩包解压后目录大致是这个结构├── VOC格式标签/ │ ├── 000001.xml │ ├── 000002.xml │ └── ... ├── COCO格式标签/ │ ├── annotations/ │ │ ├── train.json │ │ ├── val.json │ │ └── test.json ├── YOLO格式标签/ │ ├── 000001.txt │ ├── 000002.txt │ └── ... ├── JPEGImages/ │ ├── 000001.jpg │ ├── 000002.jpg │ └── ...图片和标签一一对应文件名一致直接替换到YOLO训练目录就能用。看一下YOLO格式的txt文件内容长这样0 0.452381 0.583333 0.309524 0.158333这行的含义是类别id为0即斑马线目标中心点在图片水平方向的归一化坐标是0.452垂直方向是0.583宽度占图片宽度的0.309高度占图片高度的0.158。注意YOLO格式的坐标都是归一化数值范围0到1不需要关心图片具体像素尺寸这也意味着训练时YOLO可以自由缩放输入尺寸而不用改标签。VOC格式的xml文件结构则需要多看一眼annotation folderJPEGImages/folder filename000001.jpg/filename sourcedatabaseUnknown/database/source size width1920/width height1080/height depth3/depth /size object namezebra_crossing/name bndbox xmin360/xmin ymin480/ymin xmax954/xmax ymax651/ymax /bndbox /object /annotationxml里的坐标是绝对像素值xmin、ymin是左上角xmax、ymax是右下角。COCO格式则更复杂一些主要看images和annotations两个数组annotations里每个目标有一个bbox字段格式是[x, y, width, height]跟VOC的[xmin, ymin, xmax, ymax]不一样转换时容易弄混——VOC转COCO时得做一次坐标换算很多人在这里翻车。2.3 标注质量的判断方法判断一套数据集能不能用不能只看标注框画得规整不规整还要看类别定义是否清晰。这套数据的标注类别是斑马线目标边界本身就比较规整属于矩形框能较好拟合的目标类型。用labelimg标注的框质量高不高可以用一个小技巧快速验证随机抽查几十个xml文件看xmin、ymin是否小于xmax、ymax如果出现翻转或者框超出图片边界说明标注过程有误。再检查width、height是否和JPG图片的实际尺寸一致不一致的话训练时YOLO会报警告。提示图片尺寸不一致不影响YOLO训练YOLO会把图片统一resize到网络输入尺寸但标签里的归一化坐标是严格按照原图尺寸计算的这一点VOC转YOLO时尤其要注意。3. 数据集划分脚本实战不写一行代码也能完成训练集、验证集、测试集划分3.1 三个划分脚本分别解决什么问题压缩包里附带三个划分脚本解决的是数据切分的三个经典需求。第一个是“训练集、验证集、测试集划分脚本”把图片和标签按比例写进新文件夹第二个是“训练集、验证集划分脚本”只做训练和验证两部分第三个是split_train_val生成ImageSets下txt文件划分脚本.py生成VOC风格的train.txt、val.txt文件——这是给老版darknet YOLOv3/v4用的Ultralytics YOLOv5之后的结构其实不太需要这个东西但是如果你用的框架需要索引文件这个脚本就能顶大用。以最常用的三分类划分脚本为例核心代码长这样import os import random import shutil image_dir JPEGImages label_dir YOLO格式标签 train_ratio 0.7 val_ratio 0.2 # test_ratio 0.1 # 剩余的10%作为测试集 all_images [f for f in os.listdir(image_dir) if f.endswith(.jpg)] random.shuffle(all_images) train_count int(len(all_images) * train_ratio) val_count int(len(all_images) * val_ratio) train_set all_images[:train_count] val_set all_images[train_count:train_count val_count] test_set all_images[train_count val_count:] for split_name, split_list in [(train, train_set), (val, val_set), (test, test_set)]: os.makedirs(f{split_name}/images, exist_okTrue) os.makedirs(f{split_name}/labels, exist_okTrue) for img_name in split_list: base_name os.path.splitext(img_name)[0] shutil.copy(os.path.join(image_dir, img_name), os.path.join(f{split_name}/images, img_name)) label_path os.path.join(label_dir, base_name .txt) if os.path.exists(label_path): shutil.copy(label_path, os.path.join(f{split_name}/labels, base_name .txt))这个脚本的逻辑是先列出所有图片文件random.shuffle打乱顺序再按比例切出三段。注意test_set这部分代码里没有单独给它算比例而是用总数减去训练集和验证集这样即使出现小数点误差三部分加起来也一定能等于总数不会漏图片也不会多图片。复制标签时用了os.path.splitext把后缀换成.txt保证图片和标签一一对应。注意脚本默认图片后缀是.jpg如果你的数据集里有.png、.jpeg图片记得把判断条件改成endswith((.jpg, .png, .jpeg))并且复制标签时也要对应调整后缀否则标签会丢失。3.2 划分比例怎么定数据量是关键变量拿这套斑马线数据集来说一共1000张图。按721划分就是700张训练、200张验证、100张测试。但这里有个现实问题斑马线在不同场景下的形态差异很大白天、夜晚、雨天、俯视、平视如果某个场景的图片在划分后集中到了测试集里训练集里没见过这种场景模型泛化能力就出问题。我一般会建议先按场景或者拍摄角度做一次分组再在分组内部分别划分# 按文件名前缀分组假设前缀代表拍摄场景 from collections import defaultdict groups defaultdict(list) for img_name in all_images: prefix img_name.split(_)[0] groups[prefix].append(img_name) for prefix, imgs in groups.items(): random.shuffle(imgs) # 在每个组内按7:2:1划分最后合并这个思路在数据量比较大的时候尤其重要。700张训练集、200张验证集用在YOLOv8这种数据增强很强的模型上够用了但如果训练集和验证集之间分布差异过大Loss曲线会震荡得很厉害验证集精度也上不去那时候别急着调超参数先回头看看数据划分是不是有问题。3.3 train_list.txt的作用和写法压缩包里还有一份train_list.txt这是老版YOLO训练时需要喂给模型的图片路径列表。darknet的YOLOv3/v4就是靠这个txt文件找到训练图片的。格式很简单每一行写一个图片的完整路径/home/user/dataset/JPEGImages/000001.jpg /home/user/dataset/JPEGImages/000002.jpg生成这个文件的方式也很直接find /home/user/dataset/JPEGImages -name *.jpg | shuf train_list.txt用shuf随机打乱顺序训练时模型每个batch取到的图片顺序也是随机的避免连续出现相同场景导致梯度方向偏置。注意如果用Ultralytics YOLOv5/v8不需要这个文件直接用--data dataset.yaml就能搞定train_list.txt是给darknet框架用的。4. 训练前的五个高频坑环境、路径、类别编号、数据增强和Loss异常4.1 环境搭建最容易翻车的三个位置压缩包里的HTML教程分别覆盖Linux和Windows两个平台的YOLO环境搭建。Linux版走的是Ubuntu NVIDIA驱动 CUDA cuDNN darknet的路线Windows版则是讲怎么在本地配置。环境搭建这套流程我复现过很多次最常翻车的不是CUDA装不上而是版本不匹配——CUDA版本和显卡驱动不匹配或者darknet编译参数里的GPU算力跟你显卡的实际算力对不上导致编译过了但一跑就段错误。另一个高频坑是虚拟环境问题。YOLOv5以上版本是基于PyTorch的PyTorch对CUDA版本要求是动态的如果系统里同时装了CUDA 11.8和12.1PyTorch编译时调用的可能是错误的那一套。# 推荐先确认当前可用的CUDA版本 nvidia-smi # 然后安装匹配的PyTorch版本 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu1184.2 类别编号从0开始还是从1开始这套数据集只有一个类别——斑马线看起来类别编号不会出问题但这里有个隐藏坑不同的标注工具和训练框架对类别id的起点定义不一样。labelimg默认把第一个画出来的类别记为0但有的自定义脚本会从1开始。YOLO格式的txt文件里第一列就是类别id如果数据集是单个类别id为0没问题但如果你以后自己标注多类别数据再有标签从1开始训练时就会报class id out of range。检查方法很简单直接统计txt文件里的类别值cat YOLO格式标签/*.txt | awk {print $1} | sort -u只要输出的最大值小于data.yaml里nc参数的值就说明没问题。4.3 验证集Loss不降或BN层崩溃训练YOLO模型时最常见的是两种异常情况。一种是验证集Loss一直不降、震荡幅度很大这种大概率是训练集和验证集分布差异过大或者是学习率设得太高。另一种是训练过程中出现nan这通常是梯度爆炸一般是学习率过高或者batch size太小导致的。还有一个比较隐蔽的问题是BN层崩溃现象是训练到一半Loss突然变成nan之后再也回不来。常见原因有两个一是训练集里混入了空白图片或全黑图片这类图片经过归一化后BN层统计值被污染二是标签里出现了超出图片边界的框导致anchor匹配时计算出非法值。# 快速检查标签是否合法 import os for f in os.listdir(YOLO格式标签): with open(os.path.join(YOLO格式标签, f)) as fh: for line in fh: parts line.strip().split() if len(parts) ! 5: print(f格式错误: {f}) cx, cy, w, h map(float, parts[1:]) if w 0 or h 0 or cx 0 or cy 0: print(f非法框: {f})4.4 数据增强不是越多越好Ultralytics YOLOv5/v8默认开了Mosaic、MixUp、HSV变换等一堆增强策略这对小数据集很友好。但这套斑马线数据集本身质量不错标注也规整增强开太猛反而会出现一个现象验证集精度不错但测试集上小目标检测效果变差。原因是Mosaic增强会把四张图拼一起目标被缩放的概率变大模型可能对目标尺寸产生错误偏好。我的习惯是如果是1000张这种量级的数据Mosaic开到0.5就够了Flip默认的0.5可以保留HSV变换S和V增益调低一点保持地面标线的颜色特征不被过度扰动。4.5 预训练权重选择YOLO训练中还有一个坑是预训练权重的选择。训练斑马线检测模型建议直接用yolov8s.pt或yolov8m.pt这种在COCO上预训练过的权重来热启动而不是从头训练。因为斑马线这种目标虽然COCO里没有专门类别但预训练模型学到的底层特征——边缘、纹理、几何形状——是通用的。使用预训练权重可以让模型在几十个epoch内就收敛到可用状态。如果是从头训练需要把pretrained参数关掉同时需要把学习率和训练轮数都调大不然前几十个epoch基本都在原地转。5. 训练自己的斑马线检测模型从数据yaml到mAP验证的完整链路5.1 写对dataset.yaml是训练的地基把数据集放进YOLOv8的训练流程里首先要写好data.yamlpath: /home/user/zebra_dataset # 数据集根目录 train: train/images val: val/images test: test/images nc: 1 names: [zebra_crossing]path字段指向数据集根目录train和val是相对路径nc是类别数量names是类别名列表。注意names里的索引必须和txt标签里的类别id对应这个数据集只有一个类别id为0names里第一个元素就是它。写错了的话训练能跑但是验证时的混淆矩阵全乱mAP也会显示异常这是那种让人最头疼的“训练没报错但结果不对”的玄学问题。训练命令很简单yolo detect train datazebra.yaml modelyolov8s.pt epochs100 imgsz640 batch16这里imgsz640是训练输入尺寸。斑马线检测的场景里如果图片里斑马线占的面积不大把imgsz提到960或者1280会有明显收益代价是显存占用和训练时间翻倍。5.2 训练过程中的三个关键信号训练开始后不要只盯着Loss数值要同时看三个信号。第一个是训练集Loss是否平稳下降这个信号反映模型拟合能力第二个是验证集Loss在第30到50个epoch之间是否出现上升拐点出现拐点说明开始过拟合该用早停第三个是P、R、mAP50指标在训练日志里的变化趋势mAP50涨到0.9以上之后再去追求mAP50-95的涨幅。yolo detect train datazebra.yaml modelyolov8s.pt epochs100 imgsz640 batch16 patience20patience20的意思是连续20个epoch验证集指标没有提升就自动停止训练这个参数能帮你省掉不少无效算力。训练结束后可以用yolo detect val单独跑一遍验证集确认最终指标能稳定复现而不是训练过程中出现了偶然的高分。5.3 模型导出与部署验证训练完成后输出目录的weights/文件夹下会有best.pt和last.pt两个权重文件best.pt是验证集指标最优的权重。部署形态如果不需要PyTorch、想要更高推理速度可以导出成ONNXyolo export modelbest.pt formatonnx opset12导出之后用一张测试集图片做完整推理确认类别名和置信度显示正常from ultralytics import YOLO model YOLO(best.pt) results model.predict(test/images/000101.jpg, conf0.25) boxes results[0].boxes if boxes is not None: print(f检测到 {len(boxes)} 个目标) for box in boxes: print(f类别: {int(box.cls[0])}, 置信度: {float(box.conf[0]):.2f}, 坐标: {box.xyxy.tolist()[0]})conf阈值在斑马线检测场景里建议设在0.25到0.3之间调太高会把一些被遮挡的斑马线漏掉调太低又会把类似白色人行横道边缘的物体误检出来。从那以后我每次拿到一套新数据集都强制先走一遍“检查标签合法性 → 观察数据分布 → 跑一轮短训练看baseline”这个流程确认数据质量没问题才继续调参资源本身质量高的话这一步帮你省下的时间是很明显的。希望帮到你。本文还有配套的精品资源点击获取
返回列表