
简介面向道路机器人视觉导航与自动驾驶场景该数据集围绕交通信号灯、马路、左右转标志、黄线、人行道、机器人等路面导航标志构建全部图像均使用YOLOv11进行目标标注。全包共815个文件其中包括407张JPG原始图像、407个对应的TXT标签文件以及1个YAML格式的数据集配置文件压缩包整体仅5.52MB轻量易用。每个图像与标签文件一一对应命名规范清晰可直接用于YOLOv11模型训练、验证及推理测试。目前已有746人学习下载适合计算机视觉学习者、机器人开发者与智能驾驶研究者参考使用。借助这套整理好的标注数据能够省去繁琐的人工采集与标注流程快速搭建多类路面目标识别模型进行训练调参和效果验证。1. 道路机器人导航识别为什么离不开yolov11这份数据集能解决什么做道路机器人的视觉导航最头疼的不是模型选型而是手里没有一套干净、带标注的“路面导航标志”数据。交通灯、马路边界、左右转箭头、黄线、人行道再加上机器人本体这些目标在真实路面场景里大小悬殊、光照多变稍微标注不齐训练出来的模型就分不清黄线和人行道边缘。yolov11作为当前目标检测里部署友好、训练门槛低的版本配合一份按视频帧抽好并完成标注的数据集能直接绕开“从零造数据”的坑。这份资源正是从实际行车视频里抽帧、用yolov11标记好的路面导航标志数据集适合正在做AGV、巡检机器人、园区无人车视觉导航的工程师也适合想拿真实数据练手yolov11训练全流程的初学者。它能帮你解决两个实际问题一是省掉人工标注的重复劳动二是提供一个可直接训练、验证导航标志识别效果的基线数据。2. 数据集的真实构成从视频帧到YOLO标注的格式与标签体系2.1 数据来源与文件命名里的信息量拿到资源后第一眼看到的是一长串jpg文件名例如output_video_mp4-0668_jpg.rf.158b362131cea9fe195c9fc58cb58625.jpg。这里能拆出三层信息output_video_mp4-0668原始来源是某个output_video.mp4视频的第0668帧说明数据来自真实行车视频抽帧不是人工合成的静态图。_jpg表示该帧以jpg格式导出压缩质量适合目标检测训练。.rf.后面跟一串哈希值这是经过Roboflow平台处理或导出的标记。Roboflow在导出数据集时会给每张图片生成唯一ID方便追溯原始样本。这批文件名跨度从-0199到-0728虽然中间有断号但基本覆盖了连续路面行驶场景。对训练而言连续帧的相似度较高建议训练前按场景做去重或按顺序划分训练验证集避免把同一段路的相邻帧同时分进训练集和验证集导致验证指标虚高。2.2 标签类别与YOLO标注格式项目标题里明确列出了要识别的类别交通灯、马路、左右转、黄线、人行道、机器人等共约6类。使用yolov11标记意味着每张jpg都对应一个同名的txt标注文件内容是YOLO格式的归一化坐标0 0.4532 0.3211 0.0522 0.0910 1 0.6120 0.7844 0.3820 0.0335每行含义是类别ID 目标中心点x坐标 中心点y坐标 目标宽度 目标高度四个坐标值都是相对图片宽高的比例0到1。第一行的类别0代表交通灯第二行的类别1代表马路。这种格式是ultralytics仓库直接支持的不需要额外转换。需要注意如果下载的资源里只有jpg没有txt说明你拿到的是未标注原图。此时需要先用标注工具如LabelImg、X-AnyLabeling按YOLO格式手动补标或者用预训练yolov11模型做预标注再人工修正。2.3 数据集质量判断看哪些文件判断一份数据集能不能直接用我一般会做三件事统计每类目标的标注框数量。如果某个类别只有几十个框训练时很容易欠拟合需要补充。检查标注框是否越界。用脚本扫描txT文件看有没有中心点坐标或宽高大于1的情况这类坏标注会直接导致训练loss异常。看图片分辨率。视频抽帧常见分辨率是1920x1080交通灯这类小目标在1080p下可能只有十几个像素宽yolov11默认输入640x640会进一步缩小目标需要考虑切图或调整tile策略。下表是常见路面导航标志在1080p视频帧中的典型尺寸范围类别典型像素宽典型像素高在640x640下的相对大小交通灯20-6040-120极小马路边界300-8005-20细长左右转箭头80-20080-200中等黄线400-9003-10极细长人行道200-500100-300中等机器人本体100-400100-400中等从这张表能看出来黄线和马路边界是典型的极端长宽比目标yolov11默认的anchor机制对这种目标不算友好后面第5章我会讲具体怎么处理。3. 用yolov11训练自己的路面导航标志模型从环境配置到训练参数3.1 环境配置ultralytics安装与0基础避坑yolov11在ultralytics版本里已经集成不需要单独下载网络结构代码。安装命令很简单pip install ultralytics如果你是纯小白建议用Python 3.9到3.11之间的版本别直接用3.12。常见翻车点是torch与CUDA版本不匹配安装完ultralytics后先跑一句验证python -c import torch; print(torch.cuda.is_available())显示True才说明GPU可用。如果为False说明你装的是CPU版torch需要到PyTorch官网按你的CUDA版本重新安装比如pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121这里cu121对应CUDA 12.1。显卡驱动版本较老的话换成cu118或cu113。环境这步卡住的人最多根源通常是先装了torch后装GPU驱动或者搞混了CUDA runtime和driver版本我一般建议先查nvidia-smi显示的Driver Version再决定装哪个wheel。3.2 数据组织把数据集改成YOLOv11能吃的目录结构ultralytics训练时默认按images和labels分目录存放并且要求训练集、验证集分开。推荐结构如下road_robot_dataset/ ├── images/ │ ├── train/ │ │ ├── output_video_mp4-0668_jpg.rf.158b362131cea9fe195c9fc58cb58625.jpg │ │ └── ... │ └── val/ │ └── ... ├── labels/ │ ├── train/ │ │ ├── output_video_mp4-0668_jpg.rf.158b362131cea9fe195c9fc58cb58625.txt │ │ └── ... │ └── val/ │ └── ... └── road_robot.yaml如果你手里的资源只是平铺的jpg需要自己写脚本按8:2划分并移动文件。用Python的shutil和random就能搞定关键代码import os, random, shutil all_jpgs [f for f in os.listdir(all_images) if f.endswith(.jpg)] random.seed(42) random.shuffle(all_jpgs) val_count int(len(all_jpgs) * 0.2) for i, jpg in enumerate(all_jpgs): txt jpg.replace(.jpg, .txt) tag val if i val_count else train shutil.copy(fall_images/{jpg}, fdataset/images/{tag}/{jpg}) if os.path.exists(fall_labels/{txt}): shutil.copy(fall_labels/{txt}, fdataset/labels/{tag}/{txt})逻辑说明先打乱文件列表按固定随机种子保证每次划分一致前20%作为验证集其余作为训练集。这里直接复制而不是移动避免操作失误弄丢原始数据。验证集只放20%是因为这类路面导航数据场景变化不大验证集太大反而浪费训练样本。划分后要检查images/val和labels/val里的文件一一对应不能有多余的txt或者缺失的txt。3.3 训练命令与参数说明数据准备好了编写road_robot.yaml文件path: /path/to/road_robot_dataset train: images/train val: images/val names: 0: traffic_light 1: road 2: turn_left 3: turn_right 4: yellow_line 5: crosswalk 6: robot然后执行训练yolo detect train dataroad_robot.yaml modelyolo11n.pt epochs150 imgsz640 batch16 device0 patience30参数说明modelyolo11n.pt使用nano版本预训练权重参数量小、训练快适合先用它跑通流程。imgsz640是输入分辨率默认640x640。如果原图是1080p直接缩到640会让小目标信息丢失严重建议先用640跑基线后续再尝试imgsz1280做对比。patience30表示30个epoch验证集指标没有提升就早停防止无效训练。batch16根据显存调整显存8G建议batch816G可以到16或32。这里有个容易忽略的细节patience不是越大越好路面导航数据类别多且目标尺寸差异大loss下降通常是震荡式的太小的patience会提前掐掉训练。30到50是比较稳的区间。3.4 常见训练问题排查训练过程中最常见的三个问题按现象和解决方式列一下loss输出为NaN最常见是学习率过大或标注框越界。检查你的txt文件是否有大于1的坐标值用脚本扫描并剔除问题文件。接着把默认学习率从0.01降到0.001。验证集mAP为0大概率是类别ID对应错误比如数据标注里类别0是交通灯但yaml里names[0]写成了robot导致所有预测全部错位。检查yaml和txt的类别编号是否一致。训练到一半显存溢出把batch减半或者开启cacheFalse而不是默认的RAM缓存。ultralytics会把图片缓存到内存加快读取内存不足时反而拖垮训练。训练完成后权重文件默认保存在runs/detect/train/weights/best.pt后面推理都用它。注意不是last.ptlast是最后一个epoch的权重可能在早停前已经过拟合。4. 推理与落地把模型接到道路机器人上的交通灯与黄线判断逻辑4.1 保存推理结果与视频抽帧训练好best.pt后第一步先跑静态图验证效果同时把两张关键结果图保存下来观察from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) results model.predict(sourcetest_road.jpg, saveTrue, conf0.35, imgsz640, projectruns/inference)saveTrue会把画好框的图片存到runs/inference目录。conf0.35是置信度阈值道路导航场景里漏检比误检更危险所以阈值不要太高0.25到0.35比较合适。跑完先看三张典型图一张有交通灯、一张有黄线、一张有人行道加左右转箭头的。对道路机器人来说实时视频流不是单帧推理而是要对视频帧连续做检测并保存结果。常见做法是用OpenCV逐帧读取视频每隔N帧推理一次import cv2 from ultralytics import YOLO model YOLO(best.pt) cap cv2.VideoCapture(road_video.mp4) fps cap.get(cv2.CAP_PROP_FPS) frame_skip int(fps / 10) # 每秒钟只检测10帧 frame_id 0 out_frames [] while True: ret, frame cap.read() if not ret: break if frame_id % frame_skip 0: results model.predict(frame, conf0.35, imgsz640, verboseFalse) annotated results[0].plot() out_frames.append((frame_id / fps, annotated)) frame_id 1 cap.release() cv2.destroyAllWindows()这段代码的含义是按视频帧率把检测频率压低到每秒10帧因为路面导航标志在机器人低速行驶时变化缓慢没必要每帧都跑模型降低频率能显著减轻嵌入式设备的计算压力。annotated results[0].plot()会在原图上叠加检测框和标签你可以把out_frames再写成视频做效果演示或汇报。4.2 结合导航标志的决策逻辑检测出来只是第一步实际道路机器人要根据标志的位置和类别做运动决策。我一般会写一个简单的规则层把检测结果转换成机器人行动指令检测类别关键判断条件机器人行为交通灯框中心点在画面顶部1/3且颜色为红色停车等待交通灯框中心点在画面顶部1/3且颜色为绿色继续前进左转箭头箭头框在画面左侧且置信度0.6左转右转箭头箭头框在画面右侧且置信度0.6右转黄线黄线框的横向跨度大于画面宽度50%禁止变道或压线人行道人行道框在车头前方且纵向距离小于阈值减速慢行机器人前方检测到机器人且框面积持续增大停车避让这里的核心是yolov11只负责输出“这里有什么、在哪”至于“该不该停、往哪转”需要你把检测框坐标和机器人当前状态结合。交通灯颜色其实可以单独做分类但如果你不想再训练一个分类器也可以直接对检测框内的图像区域用颜色阈值判断红绿。这个属于后处理逻辑和yolov11本身解耦方便替换算法。跑完一次推理后记得把预测结果保存成文本或JSON方便后续做坏样本分析。第6章我会讲怎么用这些结果反哺数据集。5. 避坑指南标注数据、小目标与类别混淆的三个翻车现场5.1 现象黄线与人行道边缘互相误检训练完第一版模型测试时发现黄线框经常把人行道斑马线的白色边缘一起框进来或者人行道检测框把黄线截断。原因是这两类目标在灰度信息上接近且都属于细长结构yolov11的特征图在小尺寸目标上分辨能力不足。解决这个问题的关键不是调模型而是检查标注。我遇到的情况是原始数据集里黄线标注框把整段黄线画成一个狭长矩形而人行道标注框也覆盖了同样的道路区域两者的IoU重叠严重。正确的做法是黄线只标注实线本身不延伸到人行道内部人行道标注斑马线的完整区域但不包括边缘的黄线。如果数据集里存在这种重叠标注需要手动修正或者删掉冲突样本。代码层面可以用脚本统计所有标注框之间的IoU找出不同类别之间高IoU的样本import os, numpy as np def iou(box1, box2): x1 max(box1[0], box2[0]) y1 max(box1[1], box2[1]) x2 min(box1[0] box1[2], box2[0] box2[2]) y2 min(box1[1] box1[3], box2[1] box2[3]) inter max(0, x2 - x1) * max(0, y2 - y1) area1 box1[2] * box1[3] area2 box2[2] * box2[3] return inter / (area1 area2 - inter 1e-6) label_dir labels/train for f in os.listdir(label_dir): boxes [] with open(os.path.join(label_dir, f)) as fp: for line in fp: parts list(map(float, line.strip().split())) boxes.append((parts[0], parts[1], parts[2], parts[3])) for i in range(len(boxes)): for j in range(i 1, len(boxes)): if boxes[i][0] ! boxes[j][0] and iou(boxes[i][1:], boxes[j][1:]) 0.3: print(f, boxes[i][0], boxes[j][0])这里IoU阈值设为0.3如果不同类别的两个框重叠超过这个比例十有八九是标注边界没切干净需要人工复核。5.2 现象小目标交通灯漏检交通灯在1080p原图里可能只有30x60像素缩放到640x640后变成18x36像素基本只剩十几个特征点。yolov11n的浅层特征图虽然能检测小目标但特征表达能力有限训练时如果正样本不足网络干脆忽略了这类目标。我当时踩坑的做法是把训练输入从640直接提到1280mAP从0.42涨到0.61但训练时间翻了4倍。后来发现性价比更高的方案是“两阶段处理”先检测小目标所在的区域再对区域放大识别。具体到交通灯可以在推理时把原图分成上下两半只在图像上半部分做一次额外的yolov11检测。这个方法不需要重新训练代码量小适合机器人算力足够但模型精度不够的场景。另一个有效手段是在训练时开启ultralytics的mosaic增强虽然默认是开启的但对小目标来说mosaic把多张图拼在一起进一步缩小了目标。对包含大量小目标的数据集我一般会调低mosaic概率甚至关闭它yolo detect train ... augment.hsv_v0.2 augment.mosaic0.3这样让模型多看到完整尺寸的交通灯而不是每次都被切碎。如果你用hcanet这类注意力机制改进yolov11的小目标检测头可以把主干网络的最后一个特征图分辨率从20x20提升到40x40代价是显存占用增加边缘设备上不一定跑得动。5.3 现象左右转标志与机器人本体混淆路面上的左转箭头和机器人本身在形状上有共性比如箭头尖角、机器人外壳轮廓训练数据不足时模型很容易把机器人外壳上的装饰条当成左右转标志。这个问题在没有足够多“负样本”时特别明显数据集里正样本多、负样本少模型没有机会学会“这不是左右转”。我的解决思路是主动收集误检样本加入训练集。具体做法推理时把置信度在0.3到0.6之间的模棱两可样本全部保存下来然后人工看把确实不是目标的对象单独存为一个“背景”类别或者直接删掉标注。yolov11训练时会把没有标注的区域当作背景所以只需要把误检图片放进训练集但不加任何标注就能告诉模型“这里不是目标”。逻辑很简单假如模型把机器人外壳识别成左转你就把这张图放到images/train里同时确保labels/train里没有对应的txt文件。ultralytics在读到无标注图片时会将其作为纯背景样本参与训练下一次推理时模型对这个区域的响应会明显降低。5.4 数据增强与hcanet优化思路如果你已经用nano模型跑通了基线想提升精度可以按这个顺序尝试换更大的模型yolo11s.pt 或 yolo11m.pt参数量上升带来精度提升但注意推理速度。调整YOLO的输入分辨率从640到960或1280适合小目标场景。用ultralytics的fliplr、scale增强参数路面导航标志里左右转箭头是方向敏感的fliplr会把左翻成右翻完label也要同步翻转。ultralytics自动处理了label翻转但你要知道训练时fliplr0.5意味着模型看到一半的左右转方向是反的这对区分左右转箭头反而有害。建议对这类方向敏感数据集设置fliplr0.0只保留上下翻转flipud0.0避免方向语义被破坏。hcanet这类注意力网络作为yolov11的neck改造选项适合研究小目标优化但工程上直接换用yolo11l加更大的imgsz往往收益更直接。如果你不想折腾网络结构先把第4点做了能避免一个很伤的准确性陷阱。6. 进阶用YOLOv11预测结果反哺数据集提升道路机器人识别鲁棒性6.1 自动标注与人工复核模型跑通后你的best.pt本身就是一个高效的标注工具。对新的路面视频先用模型自动预测生成标注框再人工修正比完全手工标注快三到五倍。实现起来很简单from ultralytics import YOLO model YOLO(best.pt) results model.predict(sourcenew_road_video.mp4, save_txtTrue, conf0.5, imgsz640) for r in results: with open(r.save_dir, a) as f: for box in r.boxes: cls int(box.cls[0]) xywhn box.xywhn[0].tolist() f.write(f{cls} {xywhn[0]:.6f} {xywhn[1]:.6f} {xywhn[2]:.6f} {xywhn[3]:.6f}\n)注意conf0.5要调得比实际部署高因为自动标注只保留高置信度结果低置信度的留给人工判断。save_txtTrue会自动生成YOLO格式的txt但文件名与图片对应关系需要你自己核对。自动标注完成后务必做一轮人工复核。别偷懒省这一步否则把错误标注扩到几千张训练出的模型会学到更多偏差。我一般每200张自动标注图抽查20张确认交通灯类别和左右转方向没有标反。6.2 mAP验证与坏样本分析扩充数据集后用验证集跑一次正式的指标评估yolo detect val modelbest.pt dataroad_robot.yaml输出里重点看每个类别的mAP50和mAP50-95。如果某个类别mAP50明显低于其他类别说明这个类的训练样本不足或标注质量差。把该类的误检和漏检图导出来存到bad_cases目录再决定是补标注还是调参数。6.3 让模型自己告诉你数据缺什么yolov11预测结果里带有置信度这个值能作为数据挖掘的信号。统计所有预测框的置信度分布把置信度低于0.5的检测框对应的图片抽出来按类别计数。你会发现某个时段、某个角度的图片置信度普遍偏低这些就是你的数据盲区。把这些盲区样本单独补充进训练集比无脑增加随机数据更有效。从那以后我每次训练路面导航识别模型都会把“预测结果 → 坏样本筛选 → 补充标注 → 重训”当成一个固定闭环而不是训一次就完事。道路机器人在不同园区、不同光照条件下的路面标志差异真的很大数据闭环才是保证鲁棒性的长效手段。希望这些基于这套yolov11标注数据集的实战经验帮到你少走我走过的弯路。本文还有配套的精品资源点击获取