首页 / 资讯中心 / 文章详情

斑马线检测YOLO数据集:格式转换、划分与训练避坑指南

斑马线检测YOLO数据集:格式转换、划分与训练避坑指南 ★ FEATURED ARTICLE
简介这是一套面向目标检测学习者的YOLO斑马线数据集真实道路场景采集数据场景丰富包含1000张高质量图片使用LabelImg标注标注框质量高。压缩包内共2000个文件主体为VOC格式的xml标签与YOLO格式的txt标签各约1000份另附COCO标签、3个Python划分脚本、6个环境搭建与训练教程页面及yaml配置xml/txt为标签文件py负责数据集划分html与yaml提供环境配置和运行指引整体约200.4MB。配套教程覆盖Linux与Windows双平台的YOLO环境搭建、训练案例修改与数据集划分流程帮助用户从零快速上手。附带的划分脚本支持按需生成训练集、验证集和测试集并可自动整理图片与标签到新文件夹适合课程设计、毕业设计或算法对比实验。已有320人学习适合希望直接获得标注数据与完整训练链路的中初级目标检测开发者。1. 斑马线检测为什么值得单独做一个YOLO数据集拿到这个标题第一反应可能是斑马线也值得单独做个目标检测数据集值得。斑马线在图像里往往是一条大面积、高重复纹理的地面标记和行人、车辆这类闭合轮廓目标完全不同——它没有固定形状被透视拉成长条后边界模糊阴雨天和晚间反光会让对比度骤降。通用目标检测模型在类别一多时很难给斑马线这种弱纹理目标留出足够容量专类数据集能把这一类做得很稳。这个资源包给的是人工标注好的1000张斑马线图片配套VOC、COCO、YOLO三种格式标签外加划分脚本和训练教程拿到手可以从数据体检直接做到训练出模型省掉标框、转格式、排目录这些琐碎活。适合两类人一是做辅助驾驶、智慧交通需要快速拿到一个斑马线检测基线的开发者二是第一次接触YOLO想用一套完整数据走通格式→训练→验证全流程的初学者。2. VOC、COCO、YOLO三种标签格式字段怎么存、怎么转换才不出错同一个标注框在三种格式里分别长成XML节点、JSON对象和TXT文本行。很多人在这一阶段吃过暗亏拿着COCO的json直接丢给YOLO训练器报错后四处找原因最后才发现格式和坐标约定全都对不上。这一章把三种格式逐层拆开再给一个可视化验证方案看完能少踩一半坑。2.1 VOC格式的XMLobject与bndbox是核心PASCAL VOC是最老也最直观的标注格式LabelImg这类目标检测常用标注工具默认就存成它。每张图片对应一个同名XML根节点是annotation里面记录图片尺寸、来源和一个个object。每个object包含name、pose、truncated、difficult字段最核心的是bndbox子节点给出左上角(xmin, ymin)和右下角(xmax, ymax)。坐标是像素值直接落在原图上人眼很容易核对。import xml.etree.ElementTree as ET xml_path zebra_0001.xml tree ET.parse(xml_path) root tree.getroot() # VOC XML 里已经带有原图宽高不需要另外去读图片 img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) print(图片尺寸:, img_w, img_h) for obj in root.findall(object): name obj.find(name).text bndbox obj.find(bndbox) xmin int(bndbox.find(xmin).text) ymin int(bndbox.find(ymin).text) xmax int(bndbox.find(xmax).text) ymax int(bndbox.find(ymax).text) print(f{name}: ({xmin}, {ymin}) - ({xmax}, {ymax})宽 {xmax-xmin}高 {ymax-ymin})逻辑说明这段代码把XML解析成树结构先读size子节点里的宽高再遍历所有object取bndbox四个角点。参数说明xmin/ymin/xmax/ymax在VOC里都是闭区间整数像素坐标画框时直接用不需要任何换算。注意部分标注工具会在XML里写入difficult或occluded字段训练时一般忽略但转YOLO格式时不要把difficult误当成类别名。2.2 COCO格式的JSONimages与annotations靠id关联COCO把全量信息压缩到一个JSON文件里。顶层通常有info、licenses、images、annotations、categories五个数组或对象。images数组存每张图的id、宽高、文件名annotations数组存每个框的image_id、bbox、area、iscrowdcategories是类别名字表。读取时靠image_id关联图片不像VOC那样一个文件对应一张图。import json with open(annotations.json, r, encodingutf-8) as f: coco json.load(f) # 建立 image_id - 文件名 的映射 id2name {img[id]: img[file_name] for img in coco[images]} for ann in coco[annotations][:5]: img_name id2name[ann[image_id]] x, y, w, h ann[bbox] # COCO 存左上角 宽高 cat_id ann[category_id] print(f{img_name}: class_id{cat_id}, x{x:.1f}, y{y:.1f}, w{w:.1f}, h{h:.1f})逻辑说明这段先把图片id映射到文件名再遍历前5个标注框。参数说明COCO的bbox是[x, y, width, height]像素坐标不是VOC的左上右下转格式时不少人直接拿xwidth当xmax方向没错但要注意COCO坐标取值是浮点四舍五入会导致框偏移一两个像素。area字段如果是从VOC转过来的常常是0或空U版YOLO训练不需要area但严格按COCO指标评估的框架需要重算。2.3 YOLO格式的TXT五个归一化数字class从0开始YOLO的标签是每张图片一个TXT文件名与图片名相同扩展名不同。TXT里每行五个数class_id、x_center、y_center、width、height。后四个数除以原图宽高做了归一化取值一般在0到1之间class_id从0开始。最大的坑就在这中心点坐标。很多人转格式时直接拿左上角坐标填进去模型能训练但预测框永远偏在目标右上角。# 把 VOC 的一个 bbox 转成 YOLO 格式 img_w, img_h 1920, 1080 xmin, ymin, xmax, ymax 100, 200, 500, 900 dw 1.0 / img_w dh 1.0 / img_h # 先算中心点再算宽高 xc (xmin xmax) / 2.0 yc (ymin ymax) / 2.0 w xmax - xmin h ymax - ymin # 全部归一化到 0~1 xc_norm, yc_norm xc * dw, yc * dh w_norm, h_norm w * dw, h * dh print(f0 {xc_norm:.6f} {yc_norm:.6f} {w_norm:.6f} {h_norm:.6f})逻辑说明中心点取左上和右下的中点宽高直接做差最后统一除以图片宽高。参数说明第一列的0是类别编号对应data.yaml里names列表的第0个元素严格从0开始。TXT标签里不保存图片尺寸信息所以训练器要知道原图宽高只能靠它自己去读图片文件这就是为什么图片路径和标签路径必须一一对应。2.4 转换与验证把三种格式画到同一张图上一眼看出对不对转换脚本写完后别急着训练先做可视化验证。常见做法是把同一张图的三种格式bbox分别画出来叠加或并排对比。如果三个框的位置和大小明显不一致一定是坐标定义搞错了而不是画图代码的问题。import cv2 def draw_boxes(image_path, boxes, color): img cv2.imread(image_path) for x1, y1, x2, y2 in boxes: cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) return img # 示例同一张图分别从 VOC、COCO、YOLO 三种格式提取 bbox # VOC 直接用 (xmin, ymin, xmax, ymax) # COCO 先转换 bbox: [x, y, w, h] - (x, y, xw, yh) # YOLO 先把归一化坐标乘回宽高中心点转左上角 # x1 (xc - w/2) * img_w, y1 (yc - h/2) * img_h # x2 (xc w/2) * img_w, y2 (yc h/2) * img_h逻辑说明可视化是格式转换的后悔药靠它能在十分钟内发现坐标语义问题。参数说明画框的颜色按格式区分VOC用绿色、COCO用蓝色、YOLO用红色排成一列对比。如果三种格式的框轮廓不重叠优先检查中心点对左上角归一化漏乘宽高写成右下角减左上角这三类错误。3. 划分脚本与数据体检1000张图怎么切train/val/test切完先查再用数据集划分看起来是小事实际上决定了训练结果有没有说服力。如果验证集里混进训练图片或者某个时序场景的图片全落在训练集模型指标会虚高上线后立刻现原形。这一章给出划分脚本的核心写法以及在划分前必须做的数据体检。3.1 划分脚本的核心逻辑与可调参数划分脚本要做的不是按数字砍三刀而是随机打乱后按比例抽取。比例上常见做法是7:1.5:1.5或8:1:11000张图规模下建议train不低于600张、val不低于100张否则验证指标波动太大。必须固定随机种子否则每次重跑划分结果不一样实验对不上。import os import random from pathlib import Path random.seed(42) # 固定随机种子划分结果可复现 image_dir Path(images) label_dir Path(labels) all_names [p.stem for p in image_dir.glob(*.jpg)] random.shuffle(all_names) train_ratio 0.7 val_ratio 0.15 # test 占剩余 0.15 n_total len(all_names) n_train int(n_total * train_ratio) n_val int(n_total * val_ratio) train_names all_names[:n_train] val_names all_names[n_train:n_train n_val] test_names all_names[n_train n_val:] def write_split(split_names, split_name): with open(f{split_name}.txt, w) as f: for name in split_names: f.write(f{name}.jpg\n) write_split(train_names, train) write_split(val_names, val) write_split(test_names, test) print(ftotal{n_total}, train{len(train_names)}, val{len(val_names)}, test{len(test_names)})逻辑说明先取所有图片的文件名主体随机打乱接着按索引切片最后把每个子集的图片名写入单独的TXT列表文件。参数说明seed不固定会导致每次运行划分结果漂移train_ratio和val_ratio两个参数决定三份比例改成0.8/0.1时test自动占0.1list文件里写的是图片名而不是绝对路径后续训练时再由data.yaml前缀拼接。3.2 切图前先做三查重复图片、坏文件、空标签划分脚本跑通后第一件事不是训练而是体检。在YOLOv8目标检测数据集处理流程里这一阶段的坑基本集中在标签没有对齐常见的有三类图片损坏打不开、标签文件内容为空、只有标签没有图片。写一个体检脚本一次性查完。from PIL import Image from pathlib import Path image_dir Path(images) label_dir Path(labels) # 第一查损坏图片 bad_images [] for p in image_dir.glob(*.jpg): try: Image.open(p).load() except Exception: bad_images.append(p.name) print(损坏图片:, bad_images) # 第二查空标签0字节或没有bbox行 empty_labels [] for p in label_dir.glob(*.txt): lines [l for l in p.read_text().splitlines() if l.strip()] if not lines: empty_labels.append(p.stem) print(空标签:, empty_labels) # 第三查标签与图片数量对应 label_names {p.stem for p in label_dir.glob(*.txt)} image_names {p.stem for p in image_dir.glob(*.jpg)} print(有标签没图片:, list(label_names - image_names)) print(有图片没标签:, list(image_names - label_names))逻辑说明三查分别覆盖图片无法解码TXT里没有任何bbox文件对不齐三类问题。参数说明PIL的load()会把图片真正读进内存能暴露截断的半张图TXT按行清洗后判断是否有有效标注空行和纯注释行不算数。体检结果如果出现异常优先人工看一眼对应文件不要直接进训练否则后半夜的报错都从这里来。3.3 切完检查目录结构YOLO官方能直接读的布局划分脚本跑完后数据集目录结构要符合训练器的预期。常见做法是镜像目录图片和标签分别放images与labels两个大目录下面再按train/val/test分。这样训练器在读取时会自动把same stem的图片和TXT配对。datasets/zebra/ ├── images/ │ ├── train/ 约700张.jpg │ ├── val/ 约150张.jpg │ └── test/ 约150张.jpg ├── labels/ │ ├── train/ 约700张.txt │ ├── val/ 约150张.txt │ └── test/ 约150张.txt ├── train.txt ├── val.txt └── test.txt检查时重点看两个地方一是images/train与labels/train的文件名一一对应二是三个子目录里图片和标签数量都大于0。有些教程习惯把所有图片平铺在同一个目录只靠train.txt列表区分那种布局也能训但对新手不推荐因为一旦TXT列表写错路径排查成本更高。3.4 配置data.yaml时最容易写错的三个字段目录结构确认后写data.yaml。这个文件是训练器的入口常见错误集中在path、names、nc三个字段上。下面这份以Windows路径为例。path: D:/datasets/zebra # 数据集根目录正斜杠最稳 train: images/train # 相对 path 的图片目录 val: images/val test: images/test nc: 1 # 类别数量斑马线只有一类 names: 0: zebra_crossing参数说明path写绝对路径省心但换机器要改写相对路径时要保证运行命令的工作目录在数据集根目录下否则找不到。train和val的值是相对path的路径不需要写前导斜杠。nc是names列表长度如果names有2个元素但nc写成1训练不会报错只是类别名错位指标照样假。4. YOLO训练与避坑排查环境配置到结果验证的5个高频现场数据准备妥当后进入正式训练。这一章先讲环境怎么搭、参数怎么设再用5个高频坑覆盖最常见的翻车现场。斑马线是单类目标训练本身不复杂真正浪费时间的基本都集中在环境版本和标签对齐两件事上。4.1 环境配置与预训练权重版本匹配是第一步YOLO环境配置的核心原则只有一个torch、CUDA、训练器三者的版本互相匹配别装最新版装组合最稳的版本。常见做法是用conda建独立环境再安装ultralytics训练器。yolo预训练模型下载这步训练器默认会自动下载权重网络不好就手动把.pt文件放到当前目录它优先读本地文件。conda create -n yolo python3.10 -y conda activate yolo # 先按机器CUDA版本装torch再装训练器 pip install torch torchvision pip install ultralytics安装完先做一件事确认GPU被正确识别。输入python -c import torch; print(torch.cuda.is_available())输出True再继续。如果输出False说明torch装成了CPU版或CUDA版本不匹配后面所有训练都会慢几十倍这时不要急着调参先回头修环境。4.2 训练启动命令与参数取值参考imgsz、batch、epochs、patience怎么设数据量只有1000张且是单类目标训练参数不需要激进。下面命令用YOLOv8作为示例预训练权重选nano版本就够斑马线这种大纹理目标用大模型收益很低反而增加过拟合和训练时间。yolo detect train \ datazebra.yaml \ modelyolov8n.pt \ imgsz640 \ batch16 \ epochs100 \ patience15 \ projectzebra_runs参数取值参考表格参数建议值说明imgsz640输入分辨率斑马线属于大目标640够用涨到1280收益不大但显存翻倍batch8~16根据显存调整单卡16G以下先试8epochs100配合early stopping不必真的等100轮训满patience15验证指标连续15轮不提升就自动停modelyolov8n.pt用预训练权重做迁移学习比从头训练收敛快很多逻辑说明从预训练权重开始训属于迁移学习模型已经会识别通用特征只需要在斑马线上做微调。参数说明patience是训练黑匣子里最实用的机制它会在val mAP不再提升时自动停掉省时间也防过拟合。imgsz提高会成倍增加计算量小显存优先保batch而不是保分辨率。4.3 训练与验证的5个高频坑现象、原因、处理以下5个问题覆盖了斑马线数据集训练中大多数踩坑现场按重要性排序。每条都按现象到原因再到处理来写可以直接对着排查。坑1训练loss在第几十轮突然变NaN现象训练日志里loss从正常值突然变成nan之后一直nan甚至整个训练崩溃。原因最常见两个来源一是学习率偏高导致梯度爆炸二是数据体检没做干净图片里混进了解码异常的黑图或全透明图。处理先把lr0从默认值调到0.001左右复跑一次如果还是nan回到2.2的数据体检步骤把坏图全部剔除后重训。坑2mAP一直是0但loss明显在下降现象训练正常跑完loss曲线很漂亮但val的mAP50和mAP50-95全部为0。原因绝大多数情况是类别编号错位。斑马线数据集的TXT里class_id是1而data.yaml的names只有0一个类别所有标签越界验证时模型不知道学的是什么。处理统计所有TXT首列最大值确认数据集类别编号范围。如果数据集标签里的class_id沿用了VOC的类别编号而不是从0开始需要写脚本重映射后再训。坑3预测框明显偏在目标左上角位置不对现象训练完成后用val图片测试框能框住斑马线但整体往左上角偏框的尺寸也偏小。原因YOLO标签没有做归一化或者归一化时把左上角坐标当成中心点填了。这是格式转换最常见的坑。处理抽查一个TXT把五列数值乘回原图宽高画到图上对比。如果中心点落在目标外按2.3的转换公式重写TXT然后再训一轮。坑4刚启动训练就报CUDA out of memory现象训练刚开始进度条没跑几个batch就报torch.cuda.OutOfMemoryError进程直接退出。原因batch或imgsz超出显存另一个隐藏因素是Windows下显存碎片化严重。处理先把batch减半imgsz降回640还不行就在训练前设置环境变量分段显存分配能缓解碎片问题。设置方式在bash里执行export PYTORCH_CUDA_ALLOC_CONFexpandable_segments:True。坑5每个epoch耗时越来越长日志像卡死现象第一个epoch正常后面每轮时间暴涨进度条半天不动。原因最常见是num_workers设置不当导致CPU数据加载成为瓶颈尤其是Windows系统下worker进程频繁重启。处理训练命令里加workers4Windows机器建议直接设workers0让数据加载在主进程跑。另外给训练命令加cacheTrue把图片一次性缓存进内存1000张图占不了多少内存但训练速度能快好几倍。4.4 训练产物解读best.pt、loss曲线和混淆矩阵训练完项目目录zebra_runs下会生成一系列文件。你需要关注的就四样best.pt是验证集上指标最好的权重last.pt是最后一轮的权重results.png是loss和mAP曲线confusion_matrix.png是混淆矩阵。评估时会犯的一个错误是拿last.pt去推理正确做法是直接用best.pt它才是整个训练过程中泛化能力最强的版本。results.png怎么看上面一行是训练loss下面一行是验证指标。training loss持续下降但val loss先降后升就是过拟合信号训练器的early stopping已经替你拦住了。混淆矩阵在单类目标的数据集上重点不是看类间混淆而是看背景那一列——如果背景被大量识别成斑马线说明训练集里负样本不够需要补充不含斑马线的图片或加大负样本增强。5. 验证与改进mAP、PR曲线之外斑马线检测的专项优化技巧5.1 验证方法不看loss看mAP的三大支柱loss曲线能反映收敛但不能直接说明检测效果。验证阶段我会固定看三个指标mAP50、mAP50-95和PR曲线。mAP50是IoU阈值0.5下的平均精度斑马线这种单类目标通常能到0.95以上才算合格mAP50-95是多个IoU阈值的平均数值会明显低于mAP50这是正常的如果它也能到0.7以上说明框的位置精度很好。PR曲线看的是置信度阈值变化时精确率和召回率的折中关系。对斑马线这类目标宁可损失一点精确率也要保住召回率因为漏检斑马线在辅助驾驶场景里的后果比误检严重得多。5.2 三个针对斑马线的可复现改进实验第一数据增强实验。斑马线是线性纹理目标训练时把Mosaic增强的mosaic概率保持默认0.5左右额外加大垂直方向的随机透视变换模拟不同俯仰角下的观感能明显提升雨天路口的泛化。第二检测框长宽比实验。斑马线天然是长条目标训练时用矩形推理模式少填充黑边让输入图片的短边不缩得太小。第三后处理实验。斑马线容易被遮挡或磨损推理时把NMS的IoU阈值从默认0.45放宽到0.5能救回部分被压掉的重复检测框对密集斑马线效果尤其明显。这三个实验我一般会每个单独开一版跑改两个以上参数就不清楚是哪个在起作用。自己曾经因为一次性把batch、imgsz、增强全改了结果指标涨了但找不到原因后来白复盘了一场。现在每次拿到新数据集第一件事永远是统计TXT首列最大值而不是直接开训这个习惯帮我省掉了大半的截图返工。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站