资讯动态

基于语义分割的盲道与障碍物识别:从数据集构建到模型部署实战

发布时间:2026/8/27 6:19:46 来源:尧图企业网站定制
简介计算机视觉的四大基础任务——图像分类、目标检测、语义分割、实例分割各有其适用边界。在辅助出行与智慧城市场景中盲道识别不仅需要定位目标更要求像素级的空间理解这正是语义分割技术的核心价值。通过为每个像素分配类别标签模型能精细还原盲道走向与障碍物占位为视障人群提供实时、可靠的导航指引。本文从数据集策略公开数据预训练与自建数据微调结合、标注规范、类别不平衡处理、模型选型DeepLabV3等到边缘设备部署TensorRT/ONNX进行系统梳理并分享训练调参、后处理优化及泛化性提升的实战经验帮助开发者快速构建可落地的盲道识别系统。1. 项目概述与核心需求拆解做这个盲道、障碍物识别项目最开始是因为一个很实际的场景我身边有位视力障碍的朋友平时出行主要靠盲杖和手机上的读屏软件但盲杖只能探测到地面附近的情况空中伸出来的树枝、停得乱七八糟的自行车、突然冒出来的石墩这些都没法提前感知。他跟我抱怨了好几次说现在城市里盲道修得越来越密但实际走起来反而更慌因为盲道本身可能被占用、破损甚至突然断头。当时我就想能不能拿计算机视觉那套东西做一个能实时告诉他“前面是什么、该不该走”的辅助系统。这个项目的核心任务可以拆成两块第一识别出盲道区域在哪里而且必须精细到像素级因为视障用户需要知道“盲道延伸到了哪个方向”、中间哪里断了第二识别出行道上的障碍物包括静态的栏杆、石墩、乱停的电动车和动态的行人、自行车。这两件事如果靠目标检测的矩形框来做效果会很差——你框一个“盲道”出来框里全是旁边的人行道砖用户根本不知道哪些能踩。所以方案最终落在语义分割上也就是给图像里的每个像素都打上一个类别标签盲道、人行道、马路、障碍物、天空、建筑等等。这个项目适合谁来参考如果你在做计算机视觉方向的学习或毕设想搞明白真实项目里数据集是怎么从零搭起来的、语义分割模型怎么训练和落地或者你在做自动驾驶、辅助出行、智慧城市相关的场景想看看避坑经验再或者你是公益开发者想给视障人群做点实际能用的东西这篇文章都会有用。我会把方案选型、数据集构建、训练细节、部署优化、还有我踩过的坑全部展开讲清楚。2. 整体方案设计思路为什么语义分割是这道题的必然答案2.1 从计算机视觉的四大任务说起计算机视觉的基础任务通常归纳为四大类图像分类、目标检测、语义分割、实例分割。分类只回答“这张图里有没有盲道”检测能回答“盲道在哪一块矩形区域”语义分割则回答“每个像素属于哪一类”。如果要做“盲道障碍物识别”这种真实导航需求分类和检测都不够用因为盲道是细长条状结构用矩形框去框它框内必然混入大量背景框外的盲道又会被截断坐标框信息对“沿着盲道走”来说毫无指导意义。障碍物的形状千奇百怪一个倒地的共享单车、一截伸出来的水管矩形框会把很多空白区域也标为目标给后续避障规划带来噪声。视障辅助场景里用户需要的不是“前方3米有一辆电动车”而是“电动车占用了盲道的哪一段我还能不能继续直走”。这要求盲道区域和障碍物区域在像素级上做空间关系判断只有语义分割能提供这种几何信息。所以方案设计上我直接把语义分割作为主任务把目标检测降级为辅助参考比如快速产生候选障碍物再精修分割。整体思路就是摄像头采集画面 → 语义分割模型输出像素级类别图 → 后端算法从分割图中提取盲道中心线、掉落点、障碍物占位信息 → 转成语音引导。2.2 技术路线选型自训练分割模型为主SAM大模型作为辅助这两年大模型很火SAMSegment Anything Model在语义分割圈子里几乎成了标配话题。但在实际做盲道识别时我不能直接在线调用SAM原因有三实时性要求高盲人走路时摄像头帧率至少15帧每秒以上SAM的交互式分割在边缘设备上跑不动哪怕是轻量版也有困难。SAM是通用分割模型它能把图像里的物体边界切得很干净但它不认“盲道”这种语义类别。除非配合文本提示比如SAM-CLIP那套但工程链路会变得很复杂。移动端/嵌入式设备上跑多模型不现实而且项目预算有限云端推理又存在网络延迟和隐私问题。所以我的技术路线是训练一个轻量化的语义分割模型作为核心推理引擎SAM只在离线阶段用来辅助标注。具体来说先用SAM对采集到的街景图做自动抠图人工从SAM生成的分割候选里快速挑出“盲道、障碍物、人行道”等类别再手动修正边界整体标注效率能提升三四倍。这波属于是拿大模型当打工仔而不是让大模型上前线。2.3 数据集策略公开数据集兜底自建数据定胜负语义分割是数据饥渴型任务没有足够多样的标注数据模型再先进也白搭。盲道识别有个天然难题公开数据集里几乎没有专门标过“盲道”这一类别。我最初的想法是找自动驾驶街景数据集来凑比如Cityscapes、BDD100K它们有丰富的城市道路场景但类别列表里只有“道路、人行道、建筑、车辆、行人”这些没有盲道标签。后来我翻了很多数据集Aeroscapes是无人机航拍视角CLCD是车道线检测MMRotate那些是旋转目标检测跟盲道场景都有偏差。最后只能走“公开数据集预训练 自建盲道数据集微调”的组合路线。公开数据集承担的任务是让模型学到通用的图像特征、街道场景的纹理规律、各种光照天气下的鲁棒性自建数据则负责把模型的语义理解锚定到“盲道”这个具体类别上。这个思路后来被证明是性价比最高的因为如果完全从零开始标盲道数据不考虑预训练模型收敛速度会慢很多而且边缘场景泛化差。3. 数据集构建全流程采集、标注、增强的硬核细节3.1 公开数据集怎么选、怎么用我实操下来比较值得用的公开数据集有这几个我整理了一张对照表数据集场景类型分辨率标注类别适合用途Cityscapes德国城市街景2048x102427类道路、人行道、建筑等通用街景语义分割预训练BDD100K美国多城市街景1280x72019类含可行驶区域多天气、多时段鲁棒性Mapillary Vistas全球多城市街景不等66类细分非常多细分类迁移学习Aeroscapes无人机俯视1920x108011类俯视视角的盲道走向判断我实际用Cityscapes和BDD100K做了预训练输入尺寸统一缩放到512x512backbone用ResNet50。这里有个小经验公开数据集预训练时不要只拿Cityscapes因为它的街景风格偏欧洲老城路面砖块纹理跟国内很多城市不太一样加一个BDD100K能明显提升泛化能力因为BDD100K里有晴天、雨天、夜晚、雪天各种天气对盲道识别的光照鲁棒性贡献很大。另外如果你想快速验证流程不一定要马上下载几十GB的完整数据集可以先跑通小样本。比如Cityscapes的mini版或者KITTI的语义分割子集足够用来调试训练代码和评估管线。不过真正上线还是需要完整体量。3.2 自建盲道数据集的采集策略采集是整个项目里最容易被低估的环节。很多初学者直接拿手机在路上随便拍结果模型训练出来一到新城市就崩。我总结了一套采集规范设备视角要模拟真实使用场景。视障用户要么手持手机摄像头大约在胸前高度要么把手机挂在脖子上要么用导盲杖上的摄像头大约离地20-30厘米。不同视角下盲道的透视形变差别巨大。我最后采用双视角采集胸挂视角和低视角各占一半数据。覆盖不同盲道类型。国内盲道主要有三类预制混凝土盲道砖最常见、花岗岩盲道砖、不锈钢/陶瓷盲道砖。颜色有黄色、灰色、红色。还有行进盲道和提示盲道两种砖型。标注时我把它们统一成“盲道”一类但在采集时要求每种类型至少拍2000张避免模型只认得黄色砖。覆盖不同环境状态。盲道被树叶覆盖、被积水淹没、被共享单车压住、磨损严重、断头路、施工改道这些情况都要大量采集。因为视障用户最危险的情况不是“识别不出盲道”而是“以为前方有盲道结果走过去发现断了”。光照条件要多样。清晨逆光、正午强光、黄昏阴影、夜晚路灯、雨天反光每种至少拍500张。模型在光照变化下特别容易崩预训练模型帮不了大忙只能靠数据堆。采集工具我用的是手机原相机和三轴稳定器手机固定好后沿着盲道慢走拍摄视频然后抽帧成图片。视频抽帧的好处是连续帧之间有大量相似场景可以后期做数据清洗去重。我抽帧频率是每秒1-2帧一小时的素材大约能出3000-6000张有效图片。3.3 标注工具与标注规范标注工具我推荐Labelme理由很实在免费开源、支持多边形标注、输出JSON格式方便转成各种训练格式。不建议新手一上来就用那些商业标注平台除非你的数据量特别大否则自己标完全够用。标注类别我设置成这样background背景blind_sidewalk盲道sidewalk普通人行道road机动车道obstacle障碍物包括石墩、栏杆、停放的车辆、施工物品等person行人cyclist骑行者vegetation绿化带可能有人会问障碍物为什么要单独分一类而不是把电动车、石墩、共享单车各分一类原因有两个第一视障辅助的核心需求是“前方有没有东西挡路”而不是“挡路的具体是什么”第二类别越多标注成本越高类别不平衡问题越严重。后面如果要做增强版本可以把“obstacle”细分但第一版务必保持简洁。标注时的几个坑盲道被遮挡时比如树叶盖住了一半我统一按“盲道”标还是按“障碍物”标我的规范是盲道砖仍可见的部分标盲道遮挡物如果面积占比30%以上遮挡区域标对应类别比如树叶就标vegetation这样模型能学到“盲道被占”的空间关系推理时后端算法再判断“盲道被遮挡比例是否大于阈值”触发提醒。多人标注时不同人画的多边形边界差异很大。我的做法是准备一份标注规范文档规定“盲道砖边界以砖面外沿为准不包含砖缝”、“障碍物边界以物体外轮廓为准不包含阴影”然后每100张图抽查一次一致性。Labelme标注完生成JSON需要转成训练格式。我写了个自动转换脚本把JSON转成8位PNG灰度标签图每种类别对应一个像素值然后统一转成COCO或VOC格式。这一步看起来很基础但很多坑都出在这里——类别编号错位、JSON坐标超出图像边界、多边形自相交都会让模型训练时loss爆炸。3.4 数据增强与类别不平衡处理盲道识别中类别不平衡问题非常突出。我统计过自己采集的数据集盲道像素占比大约只有3%-6%而背景能占到40%以上。如果直接用交叉熵损失训练模型会倾向于把所有像素都预测成背景盲道区域直接消失。这边我有几个处理手段每个都实测有效第一加权损失函数。给每个类别设置权重权重跟像素占比成反比。公式就是class_weight 1 / log(1.02 pixel_ratio)这里的1.02是平滑项防止占比太小的类别权重过大导致训练震荡。盲道类权重大约在8-12之间障碍物在5-8之间。第二Dice Loss混合。交叉熵和Dice Loss按1:1混合能直接优化分割区域的IoU。Dice Loss对小目标比较友好但对类别极度不平衡时可能出现梯度不稳定所以混合起来用最稳。第三针对性数据增强。除了常规的随机翻转、旋转、颜色抖动、高斯噪声外我加了两种盲道场景专用的增强方法随机擦除。模拟盲道被树叶或积水覆盖的情况在图上随机擦除小块区域并用随机纹理填充。色彩空间扰动。盲道砖的颜色在不同城市差异很大黄色、灰色、红色我在HSV空间里对H通道做大幅度随机扰动让模型不被颜色绑架更关注砖块纹理和几何排列。第四Crop采样。训练时我不用整张512x512图直接输入而是先下采样到1024x1024再从包含盲道的区域做随机crop保证每张训练图里盲道至少占5%-10%的像素。这个策略能变相增加盲道样本的权重。经过这套组合拳模型在盲道类别上的IoU从初始的0.5左右提升到0.78以上效果非常明显。4. 语义分割模型选型与训练实录4.1 主流语义分割模型怎么选现在语义分割模型一抓一大把U-Net、PSPNet、DeepLabV3、SegFormer、Mask2Former……选型不能只盯着论文精度要结合部署场景看。我的约束条件是在边缘设备上实时推理。也就是说模型参数量不能太大最好50MB以内、计算量要低在Jetson Nano上至少15FPS、精度要足够用盲道和障碍物mIoU达到0.7以上。我做了几个候选方案的实测模型Backbone参数量512x512推理耗时Jetson NanomIoUU-NetResNet5032.5M38ms0.72DeepLabV3ResNet5039.7M48ms0.75DeepLabV3MobileNetV3-Large19.6M22ms0.68SegFormer-B0MiT-B03.7M18ms0.65PSPNetResNet5046.7M52ms0.71这里插一句我实测SegFormer-B0虽然参数量小但在这个任务上精度偏低瓶颈在于盲道需要比较精细的边缘纹理信息小模型的特征表达能力不够。DeepLabV3配ResNet50综合性能最好但38ms耗时在导航场景里有点紧张DeepLabV3配MobileNetV3-Large速度够快精度也能用。最后我选择DeepLabV3 ResNet50作为离线高精度版本MobileNetV3版本作为移动端实时版本两个版本共用同一套训练数据只是backbone不同。如果你用PyTorch强烈推荐直接上segmentation-models-pytorch这个库写起来非常简洁import segmentation_models_pytorch as smp model smp.DeepLabV3Plus( encoder_nameresnet50, encoder_weightsimagenet, in_channels3, classes8, activationsoftmax2d, )这个库的好处是encoderbackbone和decoder是解耦的你可以任意换backbone比如把resnet50换成timm里的efficientnet-b3或者timm的convnext_tiny只用改一个参数。4.2 训练细节与超参数设置训练配置我按照下面的设置最后收敛效果稳定输入尺寸512x512batch size 16单卡V100优化器AdamW初始学习率5e-4配合Poly学习率衰减power0.9训练轮数100 epochs前10个epoch冻结backbone只训练decoder之后解冻全部参数lossCrossEntropyLoss带类别权重 DiceLoss权重比1:1数据加载使用albumentations做在线增强我特别想强调冻结backbone这个操作。因为自建盲道数据量有限如果一开始就端到端训练ImageNet预训练的特征会被很快破坏掉。先冻结encoder训10轮让decoder先学会怎样从预训练特征中解码出语义类别再解冻做整体微调收敛速度更快最终精度也更高。对比实验显示这个策略让最终mIoU高了大约3个百分点。训练过程中的监控指标除了mIoU我强烈建议单独看每个类别的IoU。盲道类、障碍物类的IoU比整体mIoU更重要——因为背景类别占比大会拉高整体mIoU让人误以为模型很好了实际盲道识别很差。我在训练日志里专门写了个回调每个epoch结束后打印每个类别的IoU。4.3 从PyTorch到部署格式的转换训练好的PyTorch模型不能直接部署到边缘设备一般流程是PyTorch模型转ONNXtorch.onnx.export(model, dummy_input, model.onnx, opset_version11, input_names[input], output_names[output], dynamic_axes{input: {0: batch}, output: {0: batch}})ONNX转TensorRT引擎在Jetson上trtexec --onnxmodel.onnx --saveEnginemodel.engine --fp16FP16精度下DeepLabV3 ResNet50在Jetson Nano上从48ms降到28ms精度几乎无损。MobileNetV3版本能从22ms降到13ms基本能满足实时性。如果再激进一点做INT8量化帧率还能再提但盲道边缘会变粗糙我测试下来不建议在盲道这种对边界敏感的任务里用INT8。5. 模型推理后的逻辑处理从分割图到语音引导模型输出的是一张512x512的像素分类图但用户不可能看这张图得把它转成指导性的语音信息。这部分我做了几个关键算法全都是基于分割图的几何分析盲道中心线提取。从分割图中提取盲道掩膜用形态学细化skeletonization算法提取中心骨架然后对骨架做分段线性拟合得到盲道的大致走向。当用户偏离盲道中心线时后端算法会生成“向右偏了”的提示。盲道断头检测。沿中心线方向扫描盲道掩膜如果发现盲道在连续50帧里都中断超过50厘米按深度估计换算成像素判定为盲道断头语音提示“盲道在前方约X米处中断”。障碍物占位判断。把障碍物掩膜和盲道掩膜做交并比计算如果障碍物遮挡盲道面积超过30%触发“盲道上有障碍物”的提醒。这里有个很重要的经验不要直接对单帧分割结果做决策一定要做时序平滑。因为单帧分割偶尔会有闪烁一个像素级的误判会直接导致语音提醒连续乱报。我用的是滑动窗口投票过去15帧里超过10帧判断为同一类事件才触发提醒。这个简单的策略让误报率降低了70%以上。语音部分我用了TTS文本转语音方案把预定义的提示文本比如“前方约2米处盲道被障碍物占用请注意绕行”转成语音播放。为了避免连续重复播放导致用户烦躁同一事件在60秒内只播一次。6. 常见问题与排查技巧实录6.1 训练不收敛或者loss震荡这个问题我遇到过好几次排查顺序如下先看数据标注有没有问题。类别编号和RGB值对应关系错了没有我踩过最大的坑是Labelme导出的JSON里polygon的坐标是浮点数转PNG标签图时需要取整但取整方式不对会有一圈蚂蚁线噪声导致loss一直降不下来。看类别权重是否得当。权重差太大超过50倍会让训练梯度不稳定loss曲线震荡。解决办法是把类别权重上界限制在20以内。看学习率是不是太大。我用AdamW时初始学习率5e-4对512x512输入是合适的但如果你把batch size降到8以下学习率最好也降到3e-4左右否则容易震荡。6.2 盲道边缘锯齿感严重分割图边缘不精细是语义分割的通病。如果只是视觉效果难看还可以忍但在盲道导航场景里边缘锯齿会让盲道宽度估计偏差很大甚至影响断头判断。我的处理办法从512x512的模型输出上采样到720p时不要直接双线性插值而是先对概率图做argmax然后对类别边界用CRF条件随机场做一轮后处理。CRF后处理虽然慢但对边缘平滑效果很显著。训练时加入边界损失Boundary Loss或者用结构相似性损失SSIM Loss让预测图结构更接近GT。我实测结构相似性损失加0.1权重边界锯齿明显减少。6.3 新城市泛化能力差模型在采集数据的城市表现很好但换一个城市盲道类型不同就崩了。这个问题没有银弹只能从数据层面解决跟更多城市的开发者合作采集数据扩大盲道砖类型覆盖。使用域自适应技术Domain Adaptation例如用CycleGAN把高线城市的街景图风格迁移成低线城市作为额外训练数据。这个方向有效果但训练成本较高对工程团队来说优先级可以放低。最简单有效的方法是在训练数据里加入多城市的公开街景数据做预训练让backbone提取到更通用的纹理特征再在自建数据上微调。6.4 模型在夜间和雨天掉点严重我最初的模型在白天晴天mIoU有0.75一到夜间直接跌到0.45。原因是训练数据里夜间和雨天占比不够。解决办法说起来简单做起来烧钱采集更多夜间、雨天数据然后配合图像增强比如随机亮度对比度扰动让模型对光照更鲁棒。但我之前的夜间数据往往没有完全标注因为人在夜间看清盲道边界都费劲。后来我改用弱监督方法用白天训练好的模型去预测夜间图像生成伪标签再人工修正明显的错误区域用这些修正后的伪标签做额外的训练集。这样可以把人力标注成本降低一大半。7. 项目后续可以怎么做这个项目的框架搭好之后可以扩展的方向很多。比如结合深度估计语义分割只告诉你“前方是什么”再接一个单目深度估计模型就能告诉你“障碍物到底离我多远”对视障用户的避障决策帮助很大。再比如接入多传感器融合某些高档导盲设备上会有广角相机加ToF深度传感器融合之后盲道识别和障碍物测距会更稳。另外我在自己用这个系统的时候发现很多户外环境下的干扰物盲道旁的摊位、临时电线等最难识别需要不断补充边缘场景数据来迭代。如果你准备跑这个项目先不要追求模型参数上的完美而是先拉通一条流水线然后围绕“盲道类型覆盖、天气覆盖、遮挡覆盖”三个维度持续补数据效果会越来越好。本文还有配套的精品资源点击获取

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

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

免费获取报价