铁路障碍物检测数据集构建与YOLO训练实战:5400张图像的完整流程

发布时间:2026/10/19 3:16:28
铁路障碍物检测数据集构建与YOLO训练实战:5400张图像的完整流程
前阵子接了一个铁路周界安防的小型验证项目需要检测轨道上的障碍物。模型训练本身不难真正难的是数据。翻遍各种公开资源要么是通用场景的行人车辆要么是无人机视角的高速公路几乎没有带铁轨、道砟、接触网这些典型铁路元素的图像。后来我自己梳理了一个包含5400张图片、全部按照YOLO格式标注的铁路障碍物检测数据集才把整条流程跑通。这篇文章就围绕这个数据集展开聊聊铁路障碍物检测到底需要什么样的数据、如何把数据整理成YOLO能用的格式以及训练和落地过程中那些容易踩的坑。如果你正在做铁路安全相关的视觉检测或者打算用目标检测算法识别轨道入侵物、落石、动物、施工设备等异物体这篇文章应该能给你省下不少时间。我会按数据采集、标注格式、划分增强、训练调参、评估部署这个顺序讲最后专门整理一份常见问题排查清单。整个思路不限于某个具体算法框架只要你的模型输入是标准YOLO格式这套方法都适用。1. 数据集定位为什么铁路障碍物检测需要专属数据集1.1 铁路场景的特殊性铁路障碍物检测和通用目标检测最大的区别在于场景高度结构化但目标高度非结构化。轨道、道砟、枕木、接触网、信号机这些是固定的背景而障碍物则五花八门可能是闯入轨道的行人、野生动物可能是边坡滚落的石块、断落的树枝也可能是施工遗留的工具、包装物甚至是大风刮来的轻飘物。这类目标没有统一尺寸也没有固定的外观用COCO或者VOC那种通用模型直接硬套效果通常很惨。另一个痛点是目标相对尺寸极小。铁路场景的相机视角普遍较远一个站在轨道上的行人在1080p图像里可能只占二三十个像素高度。小目标检测本来就是难点再加上铁轨周围纹理复杂背景和目标的对比度有时候还不如人和铁轨的颜色对比明显。这就是为什么做铁路障碍物检测必须有一个专门针对轨道场景的数据集来帮助模型理解背景与目标的边界。1.2 5400张数据集的定位5400张图片听起来不算海量但对于一个垂直场景的数据集来说这个规模已经够做很多事了。我见过不少项目用一千多张图就开始训练效果不稳定泛化也差。而五千张级别的数据配合合理的增强策略足以让一个中等规模的检测模型达到不错的基线水平。这个数据集更适合用来做三件事验证算法方案、微调预训练模型、搭建仿真测试环境。如果是方案验证你不需要追求极致的精度只需要证明“这个场景下用YOLO能不能检测出来”5400张足够跑通完整流程结论也有说服力。如果是微调预训练模型比如用ImageNet或COCO预训练权重做迁移学习这个规模正好不会因为数据太少而过拟合也不会因为数据太多而需要太长训练时间。至于仿真测试环境那更是合适你可以从这套数据里抽出不同的子集模拟白天、夜间、隧道口、边坡等不同条件测试算法的鲁棒性。当然如果你要做的是一条覆盖几十公里的真实线路每天几十路视频接入那5400张只是起点。后续需要针对具体点位收集更多场景数据做持续迭代。数据集的价值在于它给了你一个可复用的起点而不是终点。2. 数据采集与合规性图像从哪里来2.1 采集渠道的规划很多没接触过铁路项目的人第一反应是“去铁路边拍”这个想法必须立刻打住。进入封闭线路区域拍摄不仅危险而且涉及违规绝对不能做。合规的做法主要有三种采用公开来源的铁路图像资源、使用模拟环境构建合成数据、与有资质的单位合作在试验线或专用线拍摄。公开来源是最方便的方式可以找铁路相关的开源图片、遥感影像、铁路维护记录中的影像资料等。这类数据通常比较零散需要花时间去筛选清洗。合成数据是现在很常用的手段可以用三维仿真引擎搭建轨道场景手动放置障碍物模型批量渲染生成带标注的图片。优势是能自由控制光照、天气、视角类别和位置完全可控缺点是渲染图像和真实照片之间存在域差异后期需要用真实图像做微调来弥补。与铁路运营单位或试验基地合作的实拍是最有说服力的数据但协调周期长、成本高通常是在项目已经立项、有正式合作框架后才能拿到。我在整理数据集时采用的方式是“公开图像筛选 模拟环境补充 少量合作实拍验证”的组合。三种来源按大约6:3:1的比例混合这样既有足够的背景多样性又有干净的标注可控性还能保留真实图像的纹理细节。2.2 采集质量要求图像采集不是按几下快门就行以下几个维度直接决定数据集能不能用。分辨率要统一。建议至少保持1280x720以上因为铁路障碍物很多是小目标分辨率太低会直接丢失细节。如果来源图片分辨率不统一训练前要做归一化处理统一到相同尺寸但要注意缩放后小物体会更小所以原始分辨率越高越好。光照覆盖要广。白天、黄昏、夜间、逆光、阴天这些条件都要有体现。如果你的应用场景有夜间检测需求那夜间图像至少要占到一半以上。不过夜间图像的目标可见度很低标注的时候很容易漏标建议使用图像增强工具先提亮再标注同时保留原始图像用于训练。天气和季节也不能忽视。雨、雪、雾、霜冻天气下镜头视野会受到影响轨道表面反光也会干扰检测。不同季节的植被状态不同比如夏天茂密的树枝遮挡轨道冬天枯枝裸露背景纹理差异很大。如果目标场景是全年运行数据里至少要覆盖到主要的季节和天气组合。拍摄视角要有变化。固定机位拍摄会让模型过拟合到特定角度导致新点位泛化失败。建议同一目标至少包含水平视角、略微俯视、轨道端头视角等几种构图。实际铁路监控大多采用轨旁立杆安装视角偏高但训练数据里如果只有这一种视角模型在平视相机上的表现会很差。3. 标注体系与YOLO格式转换3.1 标注类别的设定铁路障碍物检测需要定义哪些类别是整个数据集的灵魂。类别的粒度太粗比如只有一个“障碍物”模型虽然容易学但无法区分“人闯入”和“石头滚落”这两种情况的风险等级完全不同。类别粒度太细比如把“施工锤子”和“施工扳手”分成两类数据量会被严重稀释模型反而学不好。我在这套数据集中采用的类别方案是行人、动物、车辆、落石、施工设备、其他异物。共6类。行人和动物是高频入侵主体需要单独区分车辆包括轨道工程车、公路车辆等出现在轨道附近的情况落石属于地质灾害相关目标施工设备包括工具、机械设备等其他异物用来兜底比如垃圾袋、树枝、风筝之类。类别数量控制在6类是为了在“可分辨性”和“泛化能力”之间找平衡。实际项目里你可以根据线路环境调整比如矿区线路可能更需要关注大块落石山区线路可能需要增加“树枝倒伏”类别。但无论如何每个类别至少要有300到500个实例否则模型难以收敛。3.2 从边界框到YOLO坐标的转换YOLO格式的标注文件是txt文本每行代表一个目标五个值分别是类别ID从0开始、目标中心x坐标、目标中心y坐标、目标宽度、目标高度。后四个值都是相对于图片宽高的归一化值范围在0到1之间。如果你从标注软件导出的是Pascal VOC格式也就是左上角坐标和右下角坐标需要转换成YOLO格式。转换公式如下x_center ((xmin xmax) / 2) / image_width y_center ((ymin ymax) / 2) / image_height width (xmax - xmin) / image_width height (ymax - ymin) / image_height举个例子一张1920x1080的图片里有一个目标框左上角坐标是(480, 270)右下角坐标是(960, 540)那么转换结果就是0 0.375 0.375 0.25 0.25第一位的0表示类别ID是人中心x是(480960)/2/19200.375中心y是(270540)/2/10800.375宽度是(960-480)/19200.25高度是(540-270)/10800.25。这个转换过程看起来简单但很容易出错。最常见的问题是在归一化时使用了原图尺寸以外的缩放尺寸导致坐标偏离。另一个问题是边界框穿出图像边缘导致宽度或高度大于1或者中心坐标不在0到1之间。写一个校验脚本过滤掉这些异常标注非常有必要。3.3 标注质量检查方法标注做完不等于能直接训练。我习惯用一段Python脚本把标注框可视化叠加到原图上随机抽样检查。可视化能同时发现三类问题漏标、错位、类别标错。漏标在遮挡严重的场景里经常出现错位表现为框没有紧贴目标轮廓有的偏大有的偏小类别标错则多见于行人和施工设备外观相似时。import cv2 def visualize_label(image_path, label_path, class_names): img cv2.imread(image_path) h, w img.shape[:2] with open(label_path, r) as f: lines f.readlines() for line in lines: cls, xc, yc, bw, bh map(float, line.split()) x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, class_names[int(cls)], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imshow(check, img) cv2.waitKey(0)这段代码会逐张显示图片和标注框一帧一帧看过去虽然枯燥但比直接看txt文件高效得多。我在整理数据集时用这个脚本扫了两遍第一遍查粗错第二遍查小目标漏标前后修掉了几百处问题。你要是处理的数据量大可以每20张随机抽1张先粗看一轮拿不准的情况再密集复查。4. 数据划分与增强策略4.1 训练/验证/测试集划分原则数据集划分不是随手按比例切分有个很容易犯的错误是忽略数据来源。如果原始图像是从同一段视频里按帧截取的那么相邻帧之间非常相似如果这些帧同时出现在训练集和测试集里测试指标会虚高实际部署时马上打回原形。划分时要按照“视频片段”或“拍摄批次”为最小单位而不是单张图片。也就是说一个视频片段里的所有帧要么全在训练集要么全在验证集要么全在测试集不允许交叉。这样能最大程度模拟真实场景的分布。我采用的划分比例是训练集4200张验证集600张测试集600张大约7:1:2。验证集用来做模型选择和调整超参数测试集只有在最终评估时才碰一次防止过拟合验证集。划分完数据集后目录结构要符合主流检测框架的要求。常见的组织方式如下dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/图片和标签的文件名需要一一对应图片为image_001.jpg标签就应该是image_001.txt。这个对应关系一旦错位训练时会出现“标签和图像不匹配”的问题且这种问题极隐蔽loss表面看正常mAP却一直上不去。4.2 离线增强与在线增强的选择数据增强是扩充有效样本的重要手段但不能盲目堆量。离线增强是在训练前把图像复制增强直接增加硬盘上的样本数适合原始数据明显不足的情况。在线增强是在训练过程中实时对每批次图像做变换不增加额外存储且每轮epoch看到的变换都不同效果通常更好。我推荐以在线增强为主离线增强为辅。像随机旋转、水平翻转、缩放、亮度抖动、对比度调整、加入高斯噪声这些都可以在线做。像模拟雨雾、遮挡复制粘贴这类复杂的增强因为计算代价高最好离线做好后单独作为一个数据子集加入训练。有一点要特别提醒目标检测的增强不能破坏标注的有效性。比如随机裁剪时必须重新计算标注框如果裁剪后目标面积小于某个阈值要丢弃该样本。水平翻转能够自然适用但垂直翻转不适合铁路场景因为轨道、地面和天空的语义关系是固定的垂直翻转会让模型学到错误的空间关系。颜色抖动幅度也不能太大否则铁轨和背景的颜色混在一起反而增加了学习难度。5. 基于YOLO的训练配置与踩坑记录5.1 网络模型选择数据准备好了接下来是选模型。YOLO系列有很多版本从v5到v8再到v9、v10迭代很快。对铁路障碍物检测这种垂直场景我的建议是不要盲目追求最新版本而是选择生态成熟、部署资料多的模型。以YOLOv5和YOLOv8为例两者都有完善的官方代码和预训练权重支持导出多种部署格式。YOLOv8的检测头设计更简洁训练收敛速度略快但YOLOv5在嵌入式设备上的推理优化案例更多。如果你的项目要部署到边缘盒子建议先确认目标平台对哪个版本的算子支持更好。模型尺寸方面铁路障碍物检测对算力要求不高多数场景只需要单路或几路视频。我建议从nano或small这种轻量级模型开始先把训练流程跑通再根据实际精度和速度需求决定是否换大模型。不要一上来就选large训练时间长不说在实际设备上推理帧率往往不达标。5.2 关键训练参数训练参数直接影响最终效果。我整理了几个最关键的配置方便你对照检查。输入分辨率img_size建议设为1280。虽然416或640能跑得更快但铁路障碍物属于小目标场景分辨率越低小目标特征越弱。640分辨率下一个30像素的行人会被压缩到十几个像素基本只剩一个点。1280分辨率能保留更多细节检测能力明显提升。批大小batch要根据显存定通常设置为16或32。学习率一般默认0.01配合warmup策略能稳定训练。训练轮数建议从100轮起步配合早停机制如果验证集mAP连续20轮不涨就提前结束。锚框anchor参数在YOLOv5里会自动从标注数据中重新聚类计算YOLOv8已经内置了自适应锚框机制这省了很多麻烦。即便如此如果你的标注框尺寸分布极其特殊比如都是横向长条形可能对应远处山体落石可以检查一下anchor匹配情况必要时手动设置。5.3 一个典型训练过程以YOLOv8官方库为例准备一个dataset.yaml文件内容大致如下path: ./dataset train: images/train val: images/val test: images/test nc: 6 names: [person, animal, vehicle, rockfall, construction, foreign]然后执行训练命令yolo train datadataset.yaml modelyolov8n.pt imgsz1280 batch16 epochs100训练过程中要盯着两个曲线一个是训练集loss另一个是验证集mAP。loss平稳下降表示模型在收敛如果loss在前期骤降后一直震荡可能是学习率过大如果loss完全不降甚至变大先检查数据和标注有没有问题。mAP曲线会在某个节点后趋于饱和如果继续训练提升很小说明数据量所能提供的信息已基本被模型学完了。我这次训练在30轮左右mAP就开始有明显提升到70轮后趋于稳定。最终验证集mAP0.5达到91.2mAP0.5:0.95达到68.7。在没有特别优化的情况下这个数值已经能支撑基础应用。如果你的模型精度比这个低很多先回头检查数据而不是急着换大模型。6. 评估与落地模型好坏的判断标准6.1 指标解读模型训练完不能只看一个mAP数字。mAP0.5表示IoU阈值0.5下的平均精度比较宽容适合快速筛选mAP0.5:0.95表示从0.5到0.95多个IoU阈值的平均对定位精度要求更严格是衡量检测框精度的硬指标。铁路场景里召回率往往比精确率重要。漏检的危险极大误报至少可以被人工复核或业务逻辑过滤。所以我在评估时更关注每个类别的召回率。拿行人类别来说验证集里如果有500个行人实例模型至少要检出480个以上也就是召回率96%以上才能认为基本合格。如果在某些困难样本上召回率特别低比如夜间远距离行人需要针对性补充这类数据。6.2 从测试集到真实场景的gap训练和测试都在图片上做实际部署是连续视频流两者之间有一个很现实的gap。第一图片测试是单帧判断视频流中目标会连续出现。单帧漏检在视频里可能表现为目标闪烁可以被后处理算法通过多帧投票、目标跟踪等方式修正。所以如果你的部署场景有明显运动规律比如行人跨过轨道可以叠加一个简单的跟踪器来稳定输出这比单纯提高模型精度更有效。第二测试集里的场景有限真实铁路线路可能有很多测试集没覆盖的工况例如逆光强烈、轨道表面结冰、列车高速通过时带起的粉尘遮挡。这时候需要额外的图像预处理模块比如自动白平衡、去雾算法、夜间增强等将输入图像调整到模型容易识别的状态。第三相机安装角度和机位高度的影响非常大。训练数据里的视角如果偏平视实际立杆安装的俯视角可能就会漏检。最好在实际安装后采集一批真实图像用这些图像做模型微调这是缩短差距最有效的方式。6.3 部署建议铁路障碍物检测的部署环境通常比较恶劣算力受限。我的建议是先做模型压缩再看帧率。将训练好的模型导出为边端推理格式然后用半精度推理或模型量化能显著提升速度。在边缘设备上YOLO模型可以做到几十毫秒级别的单帧推理。但要达到实时视频流处理除了模型推理时间还要考虑视频解码、图像预处理、后处理耗时。一张1080p图像预处理加解码可能比推理还要慢所以要从全链路去优化而不是死磕模型本身。如果检测到障碍物系统需要联动告警建议预留至少200毫秒的告警输出延迟。这个时间可以留给跟踪确认、消抖等逻辑避免因为单帧误检导致频繁报警。7. 常见问题与排查技巧实录7.1 标注文件错误导致训练loss异常我训练时遇到过一种情况loss前期下降但到第10轮左右突然变成nan。排查半天发现是有一个标注框中心坐标超出了图像范围归一化后出现了负数。原因是标注时不小心把边界框拖到了画布外转换格式时没有做越界检查。后来我在校验脚本里加入坐标边界判断凡是坐标小于0或大于1的标注直接标记为异常人工复查后剔除问题样本。这个问题非常隐蔽因为训练框架一般不会校验标签是否越界只会读取数值。如果你也遇到loss突然为nan优先检查标签文件里是否存在负数或大于1的坐标值。7.2 类别不平衡导致漏检样本地图里“行人”占了50%“落石”只占5%模型经过训练后落石类别的召回率可能会惨不忍睹。解决思路有三个一是对少数类做过采样在训练集里重复包含少数类样本二是对多数类做降采样但这会损失数据多样性一般不推荐三是在损失函数里调整各类别的权重让模型更关注少数类。我采用的组合是过采样加损失权重。将落石、施工设备等少数类复制成变体样本比如水平翻转、小角度旋转然后把类别权重设置为样本量反比的平方根这样既不会让模型过拟合到某几张重复图片又能平衡各类别贡献。调整后落石类别的召回率提升了11个百分点。7.3 小目标检测困难的处理铁路障碍物里很多都是小目标。推荐分辨率提到1280是一个办法但还不够。另一个有效手段是切图训练把1080p或更高分辨率的图像切成几个有重叠的patch再分别检测最后将结果映射回原图坐标。切图会成倍增加计算量但能显著提升小目标检测精度。如果不想增加推理计算量可以在训练阶段使用多尺度训练让模型学会应对不同尺度的目标。训练时每隔几个epoch随机选择一种尺度尺寸比如从640到1280之间变化。这样模型对小目标的响应更稳定推理时依然使用固定分辨率不增加额外开销。7.4 数据集中包含重复帧怎么办从视频抽帧得到图像时相邻帧之间经常存在大量相似内容。如果这些重复帧大量进入训练集模型会对这些特定帧产生记忆泛化性能下降。我建议在抽帧时设置间隔不要每帧都抽比如每秒抽1到2帧。同时可以对全量图片做感知哈希去重将相似度超过阈值的图片只保留一张。刚开始整理数据集时我没注意这一点训练出来的模型在验证集上mAP很高但换一小段新视频测试精度掉得很厉害。后来重新整理数据去掉了重复帧并用视频片段划分训练集测试集整体性能才恢复正常。最后再分享一个实用小技巧数据集的版本管理和数据本身一样重要。我习惯给每次整理都打上版本号记录类别定义、来源组成、图片数量、划分比例。后续模型效果出现波动只需要回退到对应的数据版本排查成本会低很多。铁路障碍物检测是一个持续迭代的过程数据集永远有优化空间关键是要建立一套可追溯、可复用的流程。