ARTICLE DETAIL

资讯详情

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

轨道交通计算机视觉实战:目标检测、缺陷分割与边缘部署

轨道交通计算机视觉实战:目标检测、缺陷分割与边缘部署 简介围绕计算机视觉技术在轨道交通领域的落地应用这份文档系统梳理了信号系统、线路维护、运营管理三大场景的关键技术路径覆盖信号灯自动识别、列车定位与轨迹跟踪、轨道缺陷检测、道岔状态评估、桥梁隧道健康监测以及客流统计等具体问题适合人工智能、交通工程相关专业学生及轨道交通智能化从业者作为综述参考或技术方案蓝本。整份文档以研究报告结构展开先介绍计算机视觉基础与常用算法再分主题论述检测、跟踪、识别等模型在真实轨交环境中的部署思路对目标检测、图像分割等关键环节有一定分析深度。包内为1个docx文件整体约170KB目录完整、章节划分清晰便于按需查阅。已有31人学习适合需要快速建立轨交视觉应用框架认知、撰写调研报告或进行方案预研的读者。1. 从人工巡检到视觉感知轨道交通计算机视觉的落地边界轨道交通场景里的计算机视觉和通用安防有一个明显差异所有模型都跑在强约束环境里。固定机位、隧道低照度、列车过车时的运动模糊、道岔动作的毫秒级时间窗这些约束决定了技术选型不是越新越好而是越对越好。这份资料把视觉应用拆成信号系统、线路维护、运营管理、乘客服务、应急保障五条主线真正能复用的是信号灯识别、轨道缺陷检测、道岔状态确认和客流密度估算四件事。适合继续读的读者有两类做智慧交通方案设计、需要给轨道场景配置视觉模块的系统工程师算法岗想切入工业场景、需要知道参数边界和踩坑位置的从业者。轨道项目难点不在模型结构而在标注一致性、边缘算力预算和安全逻辑衔接。下文按成像约束、目标检测、缺陷分割、边缘部署展开每章都给可复现的命令、参数与排错思路。2. 图像采集与特征提取轨道场景成像约束与 OpenCV 预处理管线2.1 光照、振动与运动模糊轨道成像的三个硬约束轨道成像和普通园区监控最大的区别在光照动态范围。地面段白天强光与阴影交替隧道段只有稀疏照明同一个系统要同时应付两种亮度列车进站时车头灯直射信号机区域会被局部过曝。预处理阶段不能只做一次全局伽马变换要按亮度区间分档处理否则后续检测模型的输入分布完全不可控。第二个约束是振动。列车通过时轨道和桥架会把振动传导到相机轴箱附近的检测相机尤其明显常见的对策是缩短曝光时间、提高帧率但这会引入第三个问题运动模糊。时速 80 公里的列车在画面里每帧移动可达几十像素快门快于 1/1000s 才能压住拖影低照度下又需要增益补偿。这三者相互制约意味着预处理管线必须在去噪、增强、保细节之间取平衡把通用图像算法直接搬来用一定会翻车。2.2 图像增强与去噪一条可复用的 OpenCV 预处理管线我一般会先做一个统一的预处理入口把 CLAHE 对比度增强和去噪放到同一个函数里方便在巡检车和固定相机之间切换参数import cv2 import numpy as np def rail_preprocess(frame, clip_limit2.0, tile_size8, denoise_h10): # 转到 LAB 色彩空间只在亮度通道做直方图均衡 lab cv2.cvtColor(frame, cv2.COLOR_BGR2LAB) l_chan, a_chan, b_chan cv2.split(lab) clahe cv2.createCLAHE(clipLimitclip_limit, tileGridSize(tile_size, tile_size)) l_eq clahe.apply(l_chan) # 合并通道并转回 BGR避免 RGB 三通道分别增强导致色偏 merged cv2.merge([l_eq, a_chan, b_chan]) enhanced cv2.cvtColor(merged, cv2.COLOR_LAB2BGR) # 非局部均值去噪抑制隧道低照度下的传感器噪点 if denoise_h 0: enhanced cv2.fastNlMeansDenoisingColored( enhanced, None, denoise_h, denoise_h, 7, 21 ) return enhancedclip_limit 控制对比度拉伸上限隧道昏暗场景设 2.0 足够地面阳光场景可以提到 3.5过大会出现明显的块状伪影。tile_size 取 8 是局部细节和计算量的折中取 4 时暗部细节更好但速度下降。fastNlMeansDenoisingColored 的 denoise_h 在 5 到 15 之间调但要注意它是非局部均值算法1080p 单帧耗时几百毫秒只能用在低速巡检车或离线复核实时视频流里改成双边滤波耗时能压到 20ms 以内。预处理不是万能的强去噪会抹掉小目标边缘。信号灯这种只有十几个像素的灯位去噪强度过大会让漏检率不降反升。实践上我会把预处理做成两路目标检测链路用小强度增强裂缝分割链路用强去噪互不干扰。2.3 传统算法基线轨道线检测与边缘特征深度学习普及之前轨道几何参数的初筛靠边缘检测加霍夫变换。钢轨顶面反射形成稳定的直线结构用 Canny 提取边缘后做概率霍夫拟合就能得到钢轨边界和轨距参考值import cv2 import numpy as np def track_line_edges(gray, canny_low50, canny_high150, min_len200): # Canny 双阈值low 控制弱边缘保留high 控制强边缘确认 edges cv2.Canny(gray, canny_low, canny_high) lines cv2.HoughLinesP( edges, 1, # 距离分辨率 1 像素 np.pi / 180, # 角度分辨率 1 度 threshold80, # 累加器阈值越小越容易检出短碎片 minLineLengthmin_len, maxLineGap30 # 断点拼接允许的最大间隙 ) return linesCanny 两个阈值一般按 1:3 比例设置轨道阴影复杂时可以改用自适应阈值。threshold 是霍夫累加器门槛取 80 表示至少要 80 个边缘点投票的直线才被接受minLineLength 要跟画面里钢轨的像素长度匹配否则会把枕木的短边缘误检成轨道线。这套传统基线现在仍有价值在巡检车上先跑直线检测框出轨道区域再把区域交给分割模型能省掉接近一半的无效计算。表 2-1 是这一阶段常用的算法对比选型时按这个表做参照算法用途计算量主要限制Canny 概率霍夫钢轨边界、接触网直线检测低弯道与交叉渡线处误检偏高MSER 区域检测隧道裂缝、锈斑粗定位中低对比度与阴影下易失效灰度直方图统计道床脏污、轨面泛白量化极低只能粗筛无法定位这套管线在数据链路里只是入口真正的识别和判定要交给目标检测和分割模型。但把传统算法当作哈希过滤器先用掉七成背景帧后面模型的压力会小很多这是轨道交通视频数据量大、边缘算力有限时最划算的做法。3. 信号灯识别与列车定位YOLO 目标检测的选型、调参与多帧确认3.1 先检测后分类信号灯识别的两级流水线信号机识别是轨道交通里最早一批用上人工智能的落地场景但我不建议用一个端到端模型同时输出红黄绿状态原因有三。第一灯位在画面里往往只有十几个像素颜色分类需要的是灯位区域内部的像素统计而不是全局特征第二信号机灯头是强结构目标检测难度低拆开之后两个模型都可以单独调优第三颜色判定要跟着光照变化调整阈值拆成独立分类器更便于维护。实际项目里两种做法都存在。固定机位、灯位大、视角稳定的场景YOLO 直接输出 red、green、yellow 三个类别也能跑车载视角、光线和背景变化大的场景我倾向两段式先用检测器框出信号机灯位再对灯位区域做颜色分类。第二个模型的输入可以很小32×32 的裁剪块就够。整个链路的关键在帧间一致性单帧判定在轨道安全场景里不可靠。3.2 模型选型YOLOv5s、YOLOv8n 与 RT-DETR 的取舍模型输入尺寸推理耗时边缘盒1080p适合位置特点YOLOv5s640约 25ms车站固定机位生态成熟量化资料多YOLOv8n640约 15ms车载低功耗相机参数少适合电池供电RT-DETR-L640约 60ms离线行为分析无 NMS密集遮挡场景稳选型逻辑很直接固定机位供电充足用生态最成熟的 YOLOv5s部署和排错资料多车载相机对功耗敏感用 YOLOv8n 换取更低延迟RT-DETR 去掉 NMS 之后在多目标密集场景表现好但训练收敛慢一般用在离线分析而不是实时告警。输入尺寸默认 640如果信号灯在画面中占比极小建议做贴图裁剪把灯位区域放大到 320×320 再进模型比盲目加大全图分辨率有效得多。3.3 推理代码与关键参数用 Ultralytics 权重做实时推理很简洁但参数要按场景区分设置from ultralytics import YOLO model YOLO(rail_signal.pt) results model.predict( sourcertsp://192.168.10.20/main, # 站台固定机位视频流 conf0.35, # 置信度阈值车载抖动场景降到 0.25 iou0.5, # NMS 的 IoU 阈值密集灯位降到 0.4 imgsz640, # 与训练尺寸保持一致 classes[0, 1], # 只推理信号灯和道岔标志两个类别 max_det50, streamTrue, # 视频流模式逐帧返回生成器 ) for idx, r in enumerate(results): boxes r.boxes.xyxy.cpu().numpy() scores r.boxes.conf.cpu().numpy() for box, score in zip(boxes, scores): # 业务层做多帧投票连续 3 帧都判红灯才输出告警 print(idx, box.tolist(), round(float(score), 3))conf 是模型输出进入业务逻辑的第一道闸门。固定机位用 0.35 可以过滤远处灯组的误检车载视角因运动模糊导致得分普遍偏低降阈值到 0.25 并配合多帧投票效果比强行维持高阈值好。iou 控制 NMS 去重力度多个灯位在画面里挨得很近时0.5 可能把相邻灯位并掉此时降到 0.4。提示轨道安全场景的告警逻辑一定要放在模型外面。模型只负责输出灯位框、颜色和置信度帧间一致性判断、状态持续时间统计、与联锁信号的交叉校验都由业务层完成否则模型一次误检就会触发误报警。3.4 列车位置估计特征点匹配与卡尔曼平滑列车定位是信号系统之外视觉用得比较多的方向原理是视觉里程计对相邻帧做特征点匹配估计相机位姿变化。轨道场景结构性强轨枕、接触网立柱、信号机都是稳定的特征点来源比城市道路上的车流场景好处理。实际部署时要警惕特征点分布不均这是最大的坑。列车直线行驶时特征点集中在画面中心运动估计在横向分量上退化容易产生漂移。常见做法是用卡尔曼滤波对位置输出做平滑状态量取位置和速度两个维度测量噪声按相机标定残差来设。视觉定位在轨道交通里一般不是唯一信息来源和应答器、轮轴速度传感器融合才是主流纯视觉方案只适合隧道内短距离临时定位。4. 轨道缺陷与道岔状态检测分割后处理与数据增强策略4.1 轨道表面缺陷检测分割模型的输出怎么用轨道表面缺陷检测的目标是裂纹、剥落和锈斑。分类模型只能回答有没有要定位缺陷位置、量化缺陷面积必须上分割。轨检场景的实时性要求不高巡检车低速运行U-Net 变体和 DeepLabV3 都够用不需要刻意追求轻量网络。真正容易出问题的是模型后处理。分割模型输出的概率图转成二值掩码后直接统计会带进大量孤立噪点我一般用连通域分析做清洗import cv2 import numpy as np def defect_filter(mask, min_area50, max_ratio0.3): # mask: 分割模型输出的缺陷概率图取值 0~1 binary (mask 0.5).astype(np.uint8) num_labels, labels, stats, _ cv2.connectedComponentsWithStats(binary, 8) defects [] total_px binary.shape[0] * binary.shape[1] for i in range(1, num_labels): # 跳过索引 0 的背景 area stats[i, cv2.CC_STAT_AREA] if area min_area: continue # 小于最小面积视为噪点 if area / total_px max_ratio: continue # 面积占比异常可能是整轨泛白或遮挡 x stats[i, cv2.CC_STAT_LEFT] y stats[i, cv2.CC_STAT_TOP] w stats[i, cv2.CC_STAT_WIDTH] h stats[i, cv2.CC_STAT_HEIGHT] defects.append((x, y, w, h, area)) return defectsmin_area 的取值要跟相机分辨率绑定。轨检相机通常在 1 到 10mm/pixel 之间设 50 像素意味着只保留最小实体尺寸 5mm 到 5cm 的缺陷更小的裂纹在数据上会被当作噪声。max_ratio 防止异常情况比如相机被油污遮挡时整幅画面都被预测为缺陷面积占比异常偏高直接丢弃这一帧比硬算一个错误结果安全。连通域分析是 OpenCV 里最便宜的后处理手段对 1080p 掩码处理一次不到 5ms放在推理链路上没有压力。4.2 道岔转换状态识别时序确认与部件级检测道岔状态直接决定列车能不能通过岔区是轨道安全的高危点。视觉方案要回答的问题是尖轨和基本轨是否密贴。单帧判定在这里完全不可靠沙尘、油污、晨昏光影都会让同一组道岔看起来截然不同。我一般先检测岔区再判断状态检测模型框出岔区后用直线拟合尖轨和基本轨的边缘计算两条线之间的缝隙宽度。缝隙低于阈值判为密贴超过阈值并持续多帧才判为不密贴。这里必须引入时序确认表 4-1 是常用的视觉特征与判定关系道岔状态视觉特征判定方式密贴尖轨与基本轨之间无明显透光缝隙缝隙宽度低于 2mm 对应像素数转换中轨缝宽度连续变化转辙机动作连续多帧缝隙宽度单调变化不密贴缝隙超过阈值并保持连续 5 帧以上缝隙超限才确认缝隙宽度的像素换算依赖标定。相机距离、俯仰角、镜头焦距都影响每像素对应的实际毫米数标定不准阈值就全偏了。不用追求全局精确标定可以采用局部标定在道岔附近放置已知尺寸的参照物或用轨枕的标准间距反推精度足够支撑密贴判断。4.3 数据增强与不均衡样本处理缺陷样本天然不均衡裂纹和剥落属于小样本类别直接训练会把召回率拉得很低。常用手段是复制粘贴增强从标注好的缺陷图里把裂纹区域抠出来随机旋转、缩放后贴到正常钢轨图上一张缺陷图能扩充几十个训练样本。配合 mosaic 增强让模型在同一个 batch 里看到多种道床背景。损失函数上分割任务用 dice loss 比纯交叉熵稳定对前景占比很小的缺陷样本更友好import torch import torch.nn.functional as F def dice_loss(pred, target, smooth1.0): # 将预测概率和真实掩码展平成一维 pred torch.sigmoid(pred).flatten() target target.flatten() intersection (pred * target).sum() # dice 2 * 交集 / (预测和 真值和)加 smooth 防止除零 return 1 - (2.0 * intersection smooth) / ( pred.sum() target.sum() smooth )smooth 取 1.0 是常见做法。dice loss 对前景像素占比只有千分之几的裂缝图特别有效因为它直接优化交并比而不是逐像素似然。实际训练时我常把 dice loss 和交叉熵按 1:1 加权避免 dice loss 在极端不均衡下收敛不稳定。验证时不要只看 mIoU要单独统计缺陷像素的召回率轨道交通场景漏检的代价远大于误检。5. 客流密度估算与 AFC 边缘部署INT8 量化与回归验证5.1 客流密度估算的两种路径站台客流分析有两条技术路径目标检测计数和密度图回归。检测计数在人群稀疏时精度高但早晚高峰站台遮挡严重漏检率快速上升密度图回归对大规模人群更稳但要人工标注高斯核训练成本高。实际项目里我倾向两者结合头部检测负责稀疏时段密度回归分支负责拥挤时段用多任务模型同时输出。大模型在客流场景的价值目前不在端侧推理而在半自动标注。用大模型对历史监控视频做粗标注再人工校正能把标注成本压到原来的三分之一。端侧推理还是靠轻量模型这一点在 AFC 系统的国产化工控平台上尤其明显。5.2 INT8 量化与国产化边缘平台部署AFC 闸机这类国产化工控平台用的是龙芯 2K3000 这类处理器算力有限外接 GPU 不现实模型必须做瘦身。最常用的手段是把 PyTorch 权重导出为 ONNX再做动态 INT8 量化import onnx from onnxruntime.quantization import quantize_dynamic, QuantType # 先确认 ONNX 模型可以直接跑通 model_in flowdet.onnx model_out flowdet_int8.onnx quantize_dynamic( model_in, model_out, weight_typeQuantType.QInt8 # 权重量化为 8bit激活保留浮点 ) # 部署端用 ONNX Runtime 加载量化模型 import onnxruntime as ort sess ort.InferenceSession(model_out, providers[CPUExecutionProvider])quantize_dynamic 只量化权重激活值仍用浮点计算对 CPU 部署最稳精度损失通常控制在 1 到 2 个点 mAP 以内。如果想进一步压延迟可以换 QOperator 模式的静态量化但需要校准数据集收益未必明显。量化完一定要在目标平台上做延迟压测不要在开发机上测边缘盒子的内存带宽和缓存大小会显著影响 ONNX Runtime 的表现。5.3 回归验证与性能压测量化上线前我做三件事。固定一段 10 分钟的 RTSP 录像回放分别用浮点模型和 INT8 模型跑一遍导出逐帧检测结果对比两类指标mAP0.5 看精度P99 延迟和每秒处理帧数看实时性把量化前后两份逐帧结果按帧号对齐diff 检测框的变化快速定位掉点集中的类别。这个方法能省大量排查时间。量化掉点通常集中在特定类别上比如小目标或纹理复杂的类别而不是均匀分布。逐帧 diff 出来后只用针对这一类别的数据做增强或改用混合精度不必推翻整个量化方案。把量化前后两份逐帧结果并排 diff是最快的定位手段也是我建议每个部署项目都保留的习惯。本文还有配套的精品资源点击获取
返回列表