资讯动态

10300张人行道检测数据集:YOLO格式标注的智慧城市场景实战

发布时间:2026/10/27 22:42:57 来源:尧图企业网站定制
人行道场景检测这几年在智慧城市项目里越来越吃香但真正做过的人都知道它远没有拿个YOLO模型跑一跑那么简单。行人遮挡、小目标密集、光照剧变、车辆与非机动车混行这些现实问题一上来很多公开数据集根本扛不住。这也是我整理这份10300张人行道场景检测数据集的原因——一边做项目一边攒的图按YOLO标注格式逐张审核过目的很直接让人行道检测模型训练有真正可用的数据基础而不是自己从头爬图、清洗、标注、排查白耗两周时间。这套数据集适合谁正在做智慧城市项目、需要训练行人检测/人行道违规占用识别模型的算法工程师也适合刚入门YOLO、想拿一份格式规整的数据集完整跑通训练流程的初学者。下面我把数据集的构成思路、标注细节、训练实操以及踩过的坑完整拆开讲。1. 人行道检测为什么这么难——先说清楚这个数据集解决了什么1.1 智慧城市项目里最容易被低估的检测任务先讲个真实经历。去年朋友接了一个智慧城市项目需求是人行道违规占用监测包括行人闯红灯、电动车驶入人行道、共享单车乱停放、盲道被占用等等。他一开始觉得简单心想不就是检测人嘛YOLOv8拿COCO预训练权重微调一下几天就能出效果。结果一测真实摄像头画面问题全来了。人行道不是一个干净的场景。它不像工业质检背景固定、光照稳定、目标种类单一也不像自动驾驶的公开数据集那样主要关注车、人、交通标志。人行道上是行人、电动车、自行车、摩托车、汽车、摊贩、宠物、杂物混在一起的。你要检测的目标经常被半遮挡尺寸忽大忽小而且同一个类别在不同城市、不同摄像头角度下外观差异极大。更麻烦的是客户真正关心的往往不是有没有人而是有没有违规——这要求模型不仅能检测目标还要有足够高的精度去支撑后续的行为判断。所以人行道检测本质上是一个多目标、多尺度、强遮挡、弱纹理混杂的场景检测任务。拿通用数据集训练出的模型直接部署到人行道场景最常见的表现是站在远处的行人漏检、被遮挡的行人漏检、电动车和自行车误判。这些不是调个阈值能解决的数据本身必须贴近真实场景。1.2 人行道场景的四大视觉杀手我做了这么多年检测项目人行道场景的难点可以归结为四类这也是我在整理数据集时重点针对的问题。遮挡密集。人行道不像机动车道行人之间距离很近经常出现人挤人的情况。一个行人可能被另一个行人挡住半边身体或者被停在路边的车辆、树木、广告牌挡住。如果标注时没有刻意纳入大量遮挡样本模型训练后对只露了一半的人基本无感。尺度跨度大。同一个画面里近处的行人可能占据几百像素远处的行人可能只有二三十像素。检测模型对小目标的敏感性本来就差YOLO系列虽然在小物体上不断优化但训练数据里如果没有足够的小目标样本效果照样拉胯。类别混杂。人行道上最常出现的不是行人而是电动车和自行车。这两类目标外形相似、体积相近、角度多变很容易互相误判。更难受的是很多数据集的类别定义模糊一个骑车的人到底算行人还是车辆这种标准不统一会导致训练出来的模型在真实场景中非常不稳定。光照和天气突变。白天强光下的阴影、傍晚的逆光、雨天的路面反光都会极大影响检测效果。人行道检测要全天候运行数据里必须覆盖这些变化否则模型在晴天训练、阴天就崩。1.3 10300张意味着什么数据量级的底气很多人问10300张图片到底够不够我说一个算账逻辑按YOLO训练常用的划分方式数据集的80%用于训练也就是8200多张。每张图里平均有5到8个有效标注目标总共标注目标数在5万到8万个之间。这个量级已经超过了很多中等规模公开数据集的可用样本量足够让YOLOv8这类模型在特定场景下达到相对理想的收敛效果。对比来看自动驾驶常用的BDD100K虽然总量大但真正属于人行道场景的帧数有限且类别重心偏向车辆。COCO数据集的person类虽然目标多但拍摄视角多样人行道街景的占比并不高而且标注风格和真实监控场景存在差距。我自己实测下来纯用COCO预训练权重微调到人行道场景比直接用这份人行道数据集从头训练加微调mAP高了大概4到6个百分点不同模型略有差异。数据匹配场景带来的提升往往比模型结构的调整更明显。2. 数据集的血肉——类别体系与标注规范详解2.1 类别怎么定的从业务目标反推标注对象很多人整理数据集时第一反应是能标的东西都标上我反而建议反着来先问自己一个问题你要检测这些目标是为了什么业务如果只是做交通流量统计对应的类别就是行人和车辆如果做人行道违规占用监测就要细分成行人、骑行者电动车/自行车、机动车、乱停放的车辆如果想进一步做盲道占用识别还要单独标注盲道区域甚至在类别层面区分盲道上是否有障碍物。这份数据集在整理时我把类别定义拆分成了七个主类行人、骑行人电动车和自行车合并、小型机动车三轮车、老年代步车等、大型机动车轿车、SUV、非机动车单独停放状态的自行车/电动车、交通标志红绿灯、人行横道标志、障碍物锥桶、石墩、违规堆物等。为什么这么分因为实际项目里最常遇到的误检就是电动车和自行车分不清、行人和骑行人混在一起。把骑行人单独拎出来模型就不用纠结这个人算行人还是算骑车的学习起来明确得多。类别划分有个原则要记住宁可合并相似类别也不要强行细分。比如电动车和自行车从检测框外形上看几乎无法稳定区分强行分成两类只会给模型制造矛盾标签。骑行人统一成一类后续如果需要细分再用分类模型或者目标跟踪来补。2.2 标注规范里藏着三个关键决策标注质量直接决定模型上限尤其是这三个规格在真正动手标注前必须定死。第一个是遮挡目标的标注策略。我的原则是目标可见面积超过30%就正常标注低于30%但能明确判断类别也标但如果只是露出一个车把或者半只脚就不标。为什么定30%太低了会给模型引入大量半截目标的噪声标签反而干扰学习太高了又会漏掉真实世界中大量被遮挡的完整目标模型对遮挡的鲁棒性上不去。30%是一个实测下来比较平衡的点。第二个是截断目标的处理。目标在画面边缘被截断这类标注要注意即使目标只露出30%在画面内也要按完整目标的尺寸估算框的位置并且框要尽量贴合可见部分。前提是你能明确判断被截断部分的大致范围。比如一个人只有上半身在画面内可以正常标出他的框但如果只露出一条手臂那就不标。第三个是极小目标的处理。人行道场景里远处的人经常只有二十多像素这类目标如果全部标注会给训练带来大量低质量正样本如果完全不标模型对远处目标的召回率又会很差。我的做法是小于20像素的目标不标20到40像素的照常标同时保证整张图片中有足够多的中距离目标。这套组合拳下来模型对小目标的敏感度反而更好。2.3 场景多样性数据集的隐藏价值在人眼看不见的地方图片数量重要但场景多样性更重要。我曾经拿一张只有8000张但场景分布均匀的数据集打赢过一张15000张但全是晴天白天路口的模型这个对比很能说明问题。这份数据集的图片来源覆盖了几个关键维度一天中的多个时段白天强光、傍晚逆光、夜间灯照、不同天气晴天、阴天、雨天、雨后路面反光、不同城市风格商业街区、老旧小区周边、学校门口、地铁站出口以及不同的摄像头安装高度和角度高视角监控、低视角球机、手机街拍视角接近的人眼高度。硬件设备上素材主要来自1080P以上的高清摄像头部分夜间图片做了亮度增强处理。分辨率方面统一缩放到1920×1080这个尺寸对YOLOv8来说训练成本可控同时保留了足够的细节。如果你的项目需要训练更大分辨率的模型这份数据集作为底料也完全够用。3. YOLO格式的技术细节——拿到手就能训练的关键3.1 标签文件到底长什么样YOLO格式的标注核心是每张图片对应一个同名txt文件文件里每一行代表一个目标五个数字依次是类别ID、目标框中心点x坐标归一化值、中心点y坐标归一化值、框的宽度归一化值、框的高度归一化值。我随意取一个真实标签示例看起来是这样的4 0.583334 0.421296 0.108333 0.277778 1 0.264583 0.879630 0.062500 0.138889 5 0.678472 0.550926 0.075000 0.254630这行数字的含义可以手工还原假设图片宽度是1920高度是1080则第一行对应的中心点坐标为 (0.583334 × 1920, 0.421296 × 1080)即约 (1120, 455)框的宽高约为 (208, 300)类别ID是4。如果要用OpenCV画出来需要转换为左上角和右下角坐标x1 int((x_center - width / 2) * img_width) y1 int((y_center - height / 2) * img_height) x2 int((x_center width / 2) * img_width) y2 int((y_center height / 2) * img_height)最容易出错的地方就在这里有人直接把中心点坐标当成左上角坐标用画出来的框全偏了训练出来的模型也跟着歪。我刚接触YOLO时也踩过这坑。3.2 目录结构与数据集划分YOLO系列包括v5/v8训练时通常要求这样的目录结构dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/图片和标签必须严格同名图片是IMG_001.jpg标签就是IMG_001.txt一个都不能少、一个都不能错。划分比例我建议按约8:1:1来切分也就是训练集约8240张、验证集约1030张、测试集约1030张。划分的时候要注意来自同一场景连续帧的图片要整体放在同一个集合里不能把同一地点同一时段的图一部分放训练集、一部分放测试集否则评估结果会虚假偏高。我一般按场景文件夹为单位划分而不是按单张图片随机划分。配置文件方面YOLOv8用起来很简单直接建一个YAML文件指向数据路径path: D:/datasets/sidewalk/ train: images/train val: images/val test: images/test names: 0: pedestrian 1: rider 2: small_motor_vehicle 3: large_motor_vehicle 4: non_motor_vehicle 5: traffic_sign 6: obstacle注意names的索引必须和txt文件里的类别ID一致。如果txt里标的是2names里第3个才对应上。这类低级错误会直接导致类别标签全部错位训练能跑完但结果完全不可用而且极其隐蔽——loss看着很正常精度却上不去。3.3 训练前的数据自检别省这一步每次拿到新的数据集我第一件事不是训练是写脚本自检主要是找出这四类常见问题。图片和标签数量是否一致、文件名是否完全对应只要文件对不上训练时就可能不报错但某张图没有标签模型等于在看空标注。检查标签里的坐标是否越界比如x_centerw/2大于1.0、y_center为负数这样的标注会造成训练loss异常。检查类别ID是否超出范围比如定义了7个类标签里却出现了7从0开始计数的话最大只能是6。检查是否有空标签文件完全没目标的图片建议直接从数据集里剔除。下面是个最基础的自检脚本我几乎每个数据集都会跑一遍import os from pathlib import Path for split in [train, val, test]: img_dir Path(fdataset/images/{split}) lbl_dir Path(fdataset/labels/{split}) imgs {p.stem: p for p in img_dir.iterdir() if p.suffix in [.jpg, .jpeg, .png]} lbls {p.stem: p for p in lbl_dir.iterdir() if p.suffix .txt} missing_lbl set(imgs) - set(lbls) missing_img set(lbls) - set(imgs) print(f{split}: missing labels{len(missing_lbl)}, missing images{len(missing_img)}) for stem in imgs: with open(lbls[stem], r) as f: for line in f: parts line.strip().split() if len(parts) ! 5: print(fbad line: {stem}.txt - {line}) break cls, x, y, w, h map(float, parts) if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): print(fcoordinate out of range: {stem}.txt - {line}) break if cls 0 or cls 6: print(fclass id out of range: {stem}.txt - {line}) break跑一遍用不了两分钟但可以避免后面几个小时的无效训练。4. 用这份数据集跑通YOLOv8的完整实操记录4.1 环境准备没装对环境后面全是坑YOLOv8训练在PyTorch环境下运行我建议先创建独立的虚拟环境避免依赖冲突。Python版本3.9或3.10都可以PyTorch 2.x版本配合CUDA 11.8使用最稳定。安装ultralytics包一行命令就能解决大部分依赖pip install ultralytics如果你想在PyCharm里操作流程也很简单新建项目时选择已存在的虚拟环境或者直接在Terminal面板里执行上述命令。我见过不少人卡在environment error上基本都是PyTorch和CUDA版本不匹配导致的先跑这行命令确认python -c import torch; print(torch.__version__, torch.cuda.is_available())如果输出True说明GPU可用如果False优先检查NVIDIA驱动和CUDA版本而不是无脑重装。4.2 训练参数的选择逻辑不是随便填的用这个数据集训练YOLOv8我最常用的参数组合是yolo detect train \ datasidewalk.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ patience20 \ lr00.01 \ projectsidewalk_experiments \ namebaseline为什么模型选yolov8s而不是yolov8m或yolov8n因为人行道场景目标密集yolov8n为了追求速度特征提取能力偏弱小目标检测明显吃亏yolov8m训练更慢、显存占用更大但精度提升有限。yolov8s是速度和精度的平衡点在一张RTX 3060 12G上batch16可以稳定运行。imgsz选640是标准值但如果你发现场景里大量目标是中小尺寸可以试试imgsz960。代价是训练时间增加约一倍但如果项目是离线分析场景、对实时性要求不高我倾向于用960收一波精度提升。之前在一个客户项目里imgsz从640提到960行人mAP50从0.78涨到0.84提升非常明显。patience20是早停参数。如果连续20个epoch验证集loss没改善就自动停止实际训练中一般在epoch 60到80就收敛了不用硬跑完100个epoch。4.3 训练过程监控别只看loss曲线训练启动后每过一个epoch会输出一长串指标重点看这几个box_loss边界框回归损失、cls_loss分类损失、dfl_loss分布焦点损失以及验证集的mAP50和mAP50-95。看loss曲线有个很实用的经验如果训练集的loss在下降但验证集loss出现反弹上升说明过拟合了马上调低epoch数或者增加数据增强。如果两个loss一直下不去先别急着调模型参数检查数据——八成是标签有问题。训练结束后的验证指标我的经验参考值大概是这个数据集上yolov8s训练100个epochmAP50能达到0.80以上mAP50-95能到0.55左右。如果你跑出来的数值明显偏低先跑一下自检脚本大概率是标签出了隐蔽问题。如果还想确认模型对遮挡目标的真实表现建议额外准备一小批难例图被严重遮挡的行人、夜间低照度画面单独作为手工测试集去测别只依赖val指标。val指标是整体平均单个困难类别的表现很容易被大量简单样本稀释。5. 从模型到落地——人行道检测的智慧城市应用扩展5.1 三个高价值应用场景数据集的价值最终要落到业务上。以这套人行道数据集为基础的模型在智慧城市项目里有三个典型的落地姿势。第一个是盲道占用检测。盲道被车辆、摊位、杂物占用是很多城市治理的痛点。用检测模型定位盲道区域内的障碍物再结合区域判断逻辑就能自动生成占用事件推送。注意这个场景的误报率门槛很高一个月误报几百条会让管理人员麻木。所以我通常会加一道帧间确认逻辑同一目标连续5帧以上出现在盲道区域才触发告警误报率能显著下降。第二个是重点路口的安全预警。检测人行道区域的行人与骑行者当骑行者速度过快冲入人行道时模型结合目标跟踪判定速度及时预警。这里要重点做骑行人类别的精度优化因为它是最容易和行人混检的类别。第三个是商圈与地铁站周边的人流统计。通过检测行人密度判断是否过度拥挤给管理方提供疏导依据。这个场景不需要太细的类别对行人类召回率要求极高宁可误报也不要漏报。调阈值时要把conf_thres降到0.15靠降低阈值换召回依赖模型本身的精度兜底。5.2 边缘端部署先把模型瘦下来智慧城市项目很多要求在前端摄像头上跑推理或者至少在边缘盒子如Jetson Orin、RK3588上跑不能全依赖GPU服务器。这时候模型压缩就是必须走的流程。第一步是导出ONNX。用YOLOv8导出很简单yolo export modelbest.pt formatonnx dynamicFalse导出ONNX前后一定要对比推理结果我遇到过导出后检测框全部偏移的情况原因是某些算子在ONNX Runtime下和PyTorch下的实现有差异必须逐张图对比验证。第二步是量化或剪枝。如果边缘设备算力有限INT8量化是最直接的手段。量化后模型体积能缩到原来的四分之一推理速度提升一倍左右但mAP可能掉2到3个点。要不要做量化取决于你的业务场景对误检漏检的容忍度。如果客户要求漏报率极低那我建议保留FP16精度模型优先优化推理框架而不是激进量化。5.3 数据迭代数据集不是终局任何数据集都只是起点。模型在某个城市部署后收集到的新数据、暴露出来的新误检才是最有价值的资产。我通常会搭一个简单闭环前端摄像头每天回传误检和漏检截图每周筛一遍挑出代表性样本补充标注增量训练一次模型。一个月后模型针对这个具体街道的检测精度会再上一个台阶。增量训练的时候有个细节新数据不要单独训练要和原始数据集合并后一起训练否则模型会灾难性遗忘旧知识。合并后建议把学习率调低到原来的十分之一让模型在旧知识基础上微调而不是重新学一遍。6. 实际使用中的坑与经验总结6.1 数据清洗时发现的隐藏问题整理数据集的过程中我做过一轮数据清洗结果发现了很多一眼看不出来的问题。有几十张图片是同一场景的连续视频帧虽然时间不同但背景高度重叠如果不做处理划分到训练集和测试集两侧验证结果会虚高还有少量图片本身是网络图带有水印和边框这些对模型泛化有负作用我全部剔除了另外发现个别标签框坐标明显偏离目标中心人工复审时纠正掉了。清洗比对不可靠的样本这步骤不要省略。6.2 类别不平衡骑行人总是被认成行人我在实际训练中遇到最顽固的问题是骑行人类别被大量误判为行人。原因很直接数据集中行人样本远多于骑行人模型为了降低整体loss倾向于把所有人形目标都预测成数量最多的类别。解决思路有两条路。第一条是调数据配比对骑行人做过采样让训练集中该类别的占比达到一个更合理的水平。第二条是调损失函数权重YOLOv8的class_weight参数可以对不同类别设置不同权重给少数类更高的惩罚迫使模型重视它。我最常用的做法是两条路组合先把骑行人的样本通过复制加轻微数据增强扩充30%再把它的损失权重设为1.2到1.5。调整后骑行人的召回率能提升8个百分点左右行人的精度基本不受影响。6.3 与公共数据集混用的正确姿势很多人拿到这个数据集后第一反应是想再加点BDD100K或者COCO数据进来。想法没问题但要小心三个坑。类别映射要统一。COCO里的person、bicycle、motorcycle等类别和这里的类别定义不完全重合。骑行人这个概念在COCO里是没有的直接混用会制造标签冲突。我的建议公共数据只用于预训练或训练早期阶段结合DeepLayer这类工具时也要先做类别映射在后期直接用本项目数据集主导训练。图片尺度要统一。公共数据集图片分辨率五花八门直接混用会导致训练时batch内图片尺寸差异过大影响稳定性。先把所有图片统一缩放到1920×1080或640×640再做划分。去重很关键。公共数据集可能包含和你场景图重复或近似的图片不做去重的话测试集的新样本其实并不新评估结果失真。混用公共数据的目的只是让模型见到更多背景变化而不是替代场景数据本身。人行道检测这种强场景关联的任务场景专有数据的质量永远是最重要的。最后分享一个我这轮的实操体会数据集的整理和清洗花的时间往往不比写模型代码少但它带来的回报是实打实的。一份贴到场景痛点的数据配上一个不折腾的训练流程比反复调参带来的提升大得多。如果你也正在做人行道相关的智慧城市项目不妨从这个数据集开始跑通一次完整训练再针对具体街道做一轮迭代你会发现检测效果比你想象中来得快。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑