拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于YOLO11的无人机航拍铁路障碍物检测实战解析

这期来聊一个我前段时间完整跑通的实战项目基于YOLO11的无人机航拍铁路障碍物检测。先说结论这套方案从数据准备、模型训练到系统封装整体链路是通的检测效果在真实航拍场景下能达到可用级别尤其针对铁轨沿线的异物侵入、落石、树木倒伏这类目标识别稳定性和误报率都控制得不错。如果你正在做无人机巡检、基础设施监测或者准备用YOLO11训练自己的垂直场景数据集这篇文章应该能帮你省掉不少弯路。我先把项目背景讲清楚。铁路沿线环境复杂传统人工巡检效率低、盲区多而无人机航拍可以快速覆盖大范围线路但航拍画面里障碍物尺度小、背景杂乱、视角多变靠人去盯视频流同样不现实。所以这个项目的核心就一句话让模型自动从无人机俯拍画面里标出铁轨附近的障碍物并给出类别和位置信息为后续调度、告警和处置提供输入。下面我按完整实操顺序来拆解包括为什么选YOLO11、数据集怎么做、训练怎么调参、系统怎么封装以及我在过程中踩过的坑。1. 项目背景与检测思路拆解1.1 无人机航拍铁路巡检为什么值得做铁路线路是典型的线性长距离基础设施穿越的地形包括山区、隧道口、桥梁、森林边缘等。传统的人工巡检模式工务段人员需要沿线路徒步或者添乘检查一个天窗点能覆盖的范围有限而且很多隐患集中在边坡、排水沟、防护网外侧这些人工难以接近的位置。无人机航拍恰好弥补了这个短板一次起飞可以沿着线路飞行几公里用高清摄像头把线路两侧的情况完整记录下来。但航拍带来的新问题是数据量暴增。一段10公里的线路4K画质飞下来视频素材可能是几十个GB靠人工逐帧翻看一是慢二是漏。所以这里的核心矛盾不是“能不能拍到”而是“拍完之后怎么快速定位异常”。目标检测模型正好解决这个问题——它可以把人工从“看视频找异常”变成“看告警框做确认”。这个项目的落地场景主要有三类第一是异物侵入检测比如落石、倒树、大块垃圾被风吹进限界第二是设施状态异常比如防护网破损、桥墩附近堆载第三是人员车辆违规进入这个涉及到安全红线对检出的实时性要求更高。我这次做的数据集主要覆盖了前两类人员车辆的样本也收了一部分但量不大后面可以单独扩充。1.2 技术选型为什么最终选了YOLO11目标检测模型现在可选的范围其实很大从两阶段的Faster R-CNN系列到单阶段的YOLO系列、SSD再到基于Transformer的DETR、RT-DETR这些。我在选型的时候主要考虑了三个因素检测精度、推理速度、生态成熟度。先说精度和速度的平衡。无人机巡检最终要跑在什么设备上决定了模型不能太臃肿。如果是地面站用GPU离线分析那模型可以大一点如果是机载边缘设备实时处理那模型必须轻量。YOLO11提供了从n、s、m、l到x的完整尺寸梯度我可以先拿大模型验证精度上限再根据部署目标选择蒸馏或直接换小模型这一个理由就足够有吸引力了。再说生态。YOLO11背后的Ultralytics库把数据加载、增强、训练、验证、导出这一套流程封装得非常完整而且对自定义数据集的适配几乎是开箱即用。相比之下DETR这些Transformer类的模型虽然精度上限高但训练技巧多、收敛慢、对数据量要求大在垂直场景里如果没有充足数据和调参经验反而不容易出效果。还有一点是社区活跃度。YOLO系列有大量的预训练权重、改进教程、部署案例可以参考遇到问题搜一下基本都有答案。对于这种偏工程落地的项目生态成熟度直接影响开发效率。所以最终方案定为YOLO11准确说是在Ultralytics框架下训练YOLO11检测模型。2. 数据集构建全流程2.1 数据收集与场景覆盖数据集是这种垂直场景项目的命门。铁路障碍物检测听起来简单但数据收集的难度比通用目标检测大得多——你不可能为了收数据去铁路上摆一堆石头和木头真实场景的获取受到安全和调度限制。所以我的数据来源是组合式的主要包括三部分一部分是自有航拍素材。我这边有一些无人机沿铁路线路拍摄的原始素材包含不同季节、不同时段、不同天气条件下的画面。这部分数据虽然标注成本高但最贴近真实部署场景是整个数据集的基石。另一部分是公开数据集的整合。网上能找到一些铁路场景的目标检测数据集以及通用航拍数据集比如VisDrone、UAVDT这些。VisDrone里虽然主体是行人、车辆、自行车但很多画面里包含道路边缘和基础设施可以通过筛选保留一部分作为背景负样本对提升模型泛化能力很有帮助。还有一部分是网络图片补充。我会搜索一些铁路沿线的新闻图片、行业公开资料里的现场照片特别是落石、滑坡、倒树这些罕见场景。这里要注意版权和合规非商用研究用途的问题不大但如果是商业项目图片版权必须理清楚。数据量方面我最终整理出有效图片约8000张其中有标注的目标约2.1万个。这个量级在垂直场景里不算多但配合合理的数据增强训练出来的模型已经能够满足需求。类别我设计成了6类落石rock、倒树tree、人员person、车辆vehicle、堆载物debris、防护网破损fence_damage。前两类是核心后两类是扩展。2.2 标注规范与格式转换标注是数据构建中最费时的一环。我用的标注工具是X-AnyLabeling它支持YOLO格式直接导出也支持Pascal VOC、COCO等格式互转。实际标注的时候我建议直接用多边形标注而不是矩形框——因为航拍视角下目标姿态随机矩形框往往包含大量背景会干扰模型学习。X-AnyLabeling支持自动标注辅助可以先用一个预训练模型跑一遍粗框人工再修正效率能提高不少。标注过程中的几个原则我踩过坑之后总结如下遮挡目标必须标。航拍画面里目标被树冠、电线杆遮挡很常见只要人眼能判断出类别就要画框标注否则模型学到的就是“只认完整目标”。小目标不要跳过。很多标注人员习惯性忽略画面里小于20×20像素的目标但无人机航拍恰恰小目标占比极高漏标等于告诉模型“这些不算障碍物”。类别边界要统一。比如“落石”和“堆载物”之间的边界如果一部分人把散落碎石标成堆载物另一部分人标成落石模型就会混乱。我这边定了一个简单规则直径超过30厘米、单独存在的岩石算落石成片堆积且来源不明的算堆载物。标注完成后YOLO格式是每张图片对应一个同名txt文件每一行的内容是class_id x_center y_center width height四个坐标值都归一化到0到1之间。如果你的标注工具导出的是COCO格式需要写一个转换脚本。这里贴一段我常用的COCO转YOLO脚本片段import json import os with open(annotations.json, r) as f: coco json.load(f) for img in coco[images]: img_id img[id] img_w, img_h img[width], img[height] lines [] for ann in coco[annotations]: if ann[image_id] ! img_id: continue cat_id ann[category_id] x, y, w, h ann[bbox] x_center (x w / 2) / img_w y_center (y h / 2) / img_h w_norm w / img_w h_norm h / img_h lines.append(f{cat_id} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}) txt_path os.path.join(labels, img[file_name].replace(.jpg, .txt)) with open(txt_path, w) as f: f.write(\n.join(lines))转换完一定要抽查几组图片把框可视化出来确认坐标没有错位这一步省不得。2.3 数据增强策略训练数据只有8000张如果不做增强模型很容易过拟合。YOLO11自带的增强策略在ultralytics配置里默认开启包括Mosaic、随机透视、颜色抖动、翻转等。但针对无人机航拍场景我把增强策略做了两处定制。第一是增加了随机旋转的角度范围。航拍画面中目标的朝向完全随机和地面平视场景不一样所以我把旋转角度从默认的0度放开到正负90度让模型学到目标在不同朝向下的特征。第二是增加了色温偏移和光照变化的强度。不同季节、不同时间航拍的色温差异非常大夏天正午和冬季清晨的画面色调完全不同增强强度调大一些模型对光照变化的鲁棒性会更好。此外我还做了一个针对性处理因为无人机高度变化会导致同一个目标在画面里的尺度差异很大我额外切了一些高分辨率图片的局部区域作为放大样本让模型更多看到“大目标”的形态。这个操作等效于把训练集里大目标样本的比例提高了对提升大目标识别率有帮助。关于增强有一点要提醒Mosaic增强并不是越大越好。Mosaic把四张图片拼成一张确实能大幅增加样本多样性但如果画面里目标本身很小拼图之后目标会更小反而增加了学习难度。我实测下来把Mosaic关闭后模型在小目标类别上的召回率反而提升了。这点在不同数据集上结论可能不同建议你训练时做一组开关对照实验不要盲目默认。3. 模型训练与关键调优3.1 环境配置踩坑记录环境配置这块网上教程一搜一大把但版本匹配问题真的能卡住很多人。我的建议是直接按照Ultralytics官方文档来Python版本3.9到3.11之间PyTorch版本2.0以上CUDA根据显卡驱动版本选对应版本别追新。我这次用的环境是Python 3.10PyTorch 2.1.0CUDA 11.8ultralytics 8.3.x显卡单张RTX 4090 24GB需要注意的一个坑是ultralytics库的版本迭代很快不同版本的默认参数和输出格式可能有差异。网上很多教程是基于旧版本写的参数名对不上很正常。我建议锁定一个版本用到底不要中途升级我这次锁定在8.3.x整个项目跑完没有遇到兼容性问题。另外一个容易忽略的点是数据集的目录结构。YOLO训练对数据目录有固定要求images和labels文件夹必须配对存在而且train、val子文件夹的命名要和data.yaml里的配置一致。我习惯用下面的结构railway_dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml的内容也很简单指向对应的路径声明类别数和类别名path: /path/to/railway_dataset train: images/train val: images/val nc: 6 names: [rock, tree, person, vehicle, debris, fence_damage]这里有个容易踩的坑data.yaml里train和val的值我一开始写成绝对路径换机器之后路径变了又得改。后来我直接用相对path的组合写法整份YAML文件就固定下来了在不同机器间拷贝项目时方便很多。3.2 训练参数与策略选择训练参数直接决定了模型收敛速度和最终效果。我实测下来对这类中等规模数据集以下配置是经过验证的yolo detect train \ --model yolo11s.pt \ --data railway_dataset/data.yaml \ --epochs 300 \ --batch 32 \ --imgsz 1280 \ --optimizer AdamW \ --lr0 0.001 \ --weight_decay 0.0005 \ --device 0几个参数的选择逻辑我说明一下。预训练权重选yolo11s而不是yolo11m或yolo11l。虽然更大的模型精度上限更高但垂直场景数据量有限大模型更容易过拟合。s模型参数适中在精度和泛化之间比较平衡。如果你想追求更高精度我的建议是先训练s模型确定数据没有问题再用m或l模型在同样数据上微调对比而不是一上来就放大模型。输入尺寸imgsz设为1280。这是整个训练配置里我认为最关键的一个参数。YOLO11默认的输入是640×640但航拍画面里大量目标只有二三十个像素640分辨率下这些目标几乎不可辨。把输入分辨率提高到1280小目标的像素数变成原来的4倍检测效果提升非常明显。代价是训练显存和速度24GB显存跑1280分辨率batch 32稍微有点吃紧但4090能扛住。训练轮数300轮同时开启早停。ultralytics自带early stopping机制patience参数默认100轮。也就是说如果连续100个epoch验证集mAP没有提升训练会自动停止。我这次实际跑到240轮左右就停了说明数据量不大时模型在200轮前后就已经收敛没必要死磕满300轮。另一个值得说的是冻结骨干网络训练的技巧。第一次训练从yolo11s.pt预训练权重开始我已经让模型继承了COCO数据集上学到的通用特征。对于这种数据量不大的场景前50轮可以冻结骨干网络只训练检测头这样能避免骨干特征被少量新数据破坏训练也更稳定。ultralytics支持通过参数设置冻结前几层yolo detect train \ --model yolo11s.pt \ --data railway_dataset/data.yaml \ --epochs 50 \ --freeze 10 \ --name rail_freeze我实测下来先冻结训练50轮然后解冻全模型再训练比直接从头训练最终mAP高出约2个百分点而且前期收敛更快。如果你想省事一步到位直接全模型训练也能出效果但精度天花板会低一些。3.3 小目标检测的关键给YOLO11加P2检测头前面提到无人机航拍最大的难点是小目标检测。YOLO11默认的检测头从P3层开始对应输入图像下采样8倍后的特征图。以1280分辨率输入为例P3特征图的每个格子对应原图8×8像素区域小于24×24像素的目标在P3特征图上可能一个格子都占不满检测难度非常大。很多做航拍检测的人会考虑给YOLO11加一个P2检测头。P2对应下采样4倍的特征图分辨率比P3高一倍小目标在P2特征图上能占据更多格子特征表达更充分。这个改进方向是可行的也确实能提升小目标召回率。但这里我要多说一句加P2检测头不是银弹代价是显存和速度。P2特征图尺寸大增加一个检测头意味着多出一大块计算量训练显存开销明显上升。在1280分辨率下加P2后显存占用提升约40%推理速度降低约25%。所以如果当前模型的小目标漏检问题还能通过数据增强或提高输入分辨率来缓解不建议一上来就动网络结构。如果你确实需要加P2思路是在yolo11的yaml模型配置文件里把检测头的分支从P3扩展到P2。具体做法是把backbone输出P2特征图的层加入检测头的输入列表。网上有不少关于YOLO系列加P2的教程YOLOv8、YOLO11结构类似可以参照修改。改配置文件之后还要同步调整训练时的anchor分配策略否则新增的P2检测头分配不到足够的正样本效果会打折扣。这个改进我实际做过对比实验结果是P2检测头让小目标面积小于32×32像素的召回率提升了约7个百分点但中等以上目标的精度略有下降整体mAP50只提升了1.2个百分点。所以它是“用小目标的提升换大目标的微小损失”具体值不值得要看你的业务更关注哪类目标。3.4 评估指标怎么看训练结束后ultralytics会在run目录下生成一系列评估结果包括PR曲线、混淆矩阵、F1曲线以及各类别的精度指标。很多人只看一个mAP值就下结论但对这种垂直场景项目我建议重点关注以下几点。第一是每个类别的AP值要分别看。6个类别里落石和倒树的AP50如果能达到85%以上基本满足实用要求人员、车辆这类类别数据相对少AP低一些是正常的但要看漏检是普遍性的还是集中在某些困难样本上。第二是混淆矩阵里的混淆模式。如果落石经常被误检成堆载物说明这两个类别的特征区分度不够要么补充边界样本要么考虑合并类别。第三是precision和recall要结合业务场景权衡。铁路障碍物检测这个场景漏检的代价远高于误报。一个真实的障碍物如果没检出来可能导致安全事故误报只是让人去复核一下成本很低。所以我在最终模型选择上不是选mAP最高的那个权重而是选recall召回率更高的那个权重哪怕precision稍微低一些。这个取舍思路在落地场景中很重要。训练完成后可以用下面的命令在验证集上评估指定权重的指标yolo detect val \ --model runs/detect/rail_freeze/weights/best.pt \ --data railway_dataset/data.yaml \ --imgsz 1280ultralytics会自动输出mAP50、mAP50-95、precision、recall等指标。另外val命令生成的混淆矩阵图特别有用我每次训练完第一件事就是看混淆矩阵能快速发现类别之间的混淆模式。4. 系统实现与部署4.1 检测流程与后处理模型训练好之后接下来要做的是把模型封装成一个能用的系统。我先说一下整体流程读取视频帧或图片缩放至模型输入尺寸送入模型推理得到检测框、类别、置信度然后做后处理过滤最后在画面上绘制结果并输出告警信息。YOLO11推理本身很简单ultralytics一行代码就能跑from ultralytics import YOLO model YOLO(runs/detect/rail_freeze/weights/best.pt) results model.predict(input.jpg, imgsz1280, conf0.25, iou0.45)但实际工程中有几个后处理细节对最终体验影响很大。置信度阈值要分开设置。默认conf0.25对通用场景合适但在铁路检测里我对落石和倒树这两个核心类别会更激进一些阈值降到0.15因为漏掉它们代价太大而对人员、车辆这些类别阈值可以维持在0.3以上减少误报。ultralytics支持按类别过滤我写了一个简单的后处理函数来实现这个逻辑。帧间稳定性处理。无人机视频连续帧之间同一个目标偶尔会出现“检出-漏检-检出”的闪烁。解决这个问题最简单有效的办法是做一个轻量的跟踪机制比如用ByteTrack或者简单的IoU匹配当前帧检测到一个目标时和历史帧的检测结果做匹配如果在连续几帧里稳定出现才判定为真实目标如果只是偶尔闪现一帧判定为误检直接丢弃。这个机制对降低误报非常有效尤其是在背景复杂、目标容易被树木短暂遮挡的场景里。ROI区域裁剪。如果无人机是沿线飞行我们可以预先定义铁轨两侧一定范围内的区域为关注区域ROI只对ROI内的检测结果做告警。这样路过的行人、远处的车辆这些在铁轨范围外移动的目标就不会触发误报。我实现的方式是标注一个多边形ROI检测结果的目标中心点落入ROI才保留实测可以把误报率降低一半以上。4.2 快速搭建可视化检测系统为了让模型效果直观可见我封装了一个基于Streamlit的简易可视化系统。它能实现三个功能上传单张图片进行检测并展示结果、上传视频流进行逐帧检测并输出带检测框的视频、展示实时检测统计信息。Streamlit的开发效率很高整个交互界面几百行代码就搞定了。核心逻辑如下import streamlit as st from ultralytics import YOLO from PIL import Image st.set_page_config(page_title铁路障碍物检测系统) st.title(无人机航拍铁路障碍物检测) model YOLO(best.pt) uploaded_file st.file_uploader(上传航拍图片, type[jpg, png, jpeg]) if uploaded_file is not None: image Image.open(uploaded_file) results model.predict(image, imgsz1280, conf0.25, iou0.45) annotated results[0].plot() st.image(annotated, caption检测结果, use_column_widthTrue)运行方式也简单streamlit run app.py如果你是做C端演示或者给业务方看效果这个方案基本够了。但如果是生产环境的实时检测Streamlit就不合适了建议直接调用模型接口配合FastAPI提供HTTP服务或者导出ONNX模型用TensorRT/OpenVINO做推理加速。4.3 模型加速与导出的实践验证效果好之后我通常会导出一份ONNX格式的模型用于跨平台部署。ultralytics提供了非常简洁的导出命令yolo export modelbest.pt formatonnx opset12导出后可以用onnxruntime进行推理推理速度比PyTorch原生快不少。如果部署在英伟达平台上可以进一步导出为TensorRT引擎FP16精度下推理速度能再提升一倍。这里有一个优化技巧导出ONNX时可以把输入尺寸固定下来。比如训练用的是1280×1280导出时指定--imgsz 1280生成的ONNX模型输入张量就是固定的onnxruntime在推理时不需要动态分配内存延迟会更稳定。缺点是输入尺寸不能随意改但对于固定部署场景完全没问题。另外如果不需要检测头里的一些训练专用分支比如回归分支的分布输出可以同时开启简化模型参数让导出的文件更小。这块是部署细节网上都有说明真正做上线部署时值得花时间优化。5. 常见问题与排查技巧实录5.1 小目标漏检严重怎么办航拍检测最典型的问题就是小目标漏检。遇到这个情况我建议按照下面的顺序排查和处理第一先确认标注数据里小目标样本是不是太少了。如果标注的小目标框占比很低模型天然学不到小目标特征。这种情况优先回补数据不要急着改模型结构。第二把训练输入尺寸从640提高到1280这一步通常能带来显著提升是最容易实施的优化。第三上面提到过的数据增强特别是关闭Mosaic再看小目标指标是否有变化。第四最后考虑加P2检测头或者用SAHI这类切片推理工具。SAHI的做法是把大图切分成小块分别送入模型检测再把结果拼回去对超大分辨率航拍图特别有效缺点就是推理时间成倍增加。我实际组合下来的最优方案是1280输入尺寸 关闭Mosaic 微调置信度阈值就解决了大部分小目标漏检问题没有动用P2检测头。5.2 误报频发怎么定位和消除误报是另一个普遍问题。在我这个场景里误报主要来源于三类一是把铁轨上的扣件、枕木误检成落石或堆载物二是把电线杆、信号机的阴影误检成人员或车辆三是把植被边缘的纹理误检成倒树。定位误报来源我的经验是把模型在验证集上的误检框导出成图片人工翻看一遍基本就能归纳出几类典型的误报模式然后针对性地处理。如果误报集中在背景类别可以考虑增加负样本如果集中在某些特定形状可以用ROI区域过滤掉非关注区的目标如果误报是普遍性的说明模型置信度校准有问题适当提高阈值或者调整类别权重。我这里有一个很有效的办法在验证集评估时专门统计一下误检框的位置分布看看是不是集中在某个区域或某种背景下然后用人工规则去过滤。5.3 训练loss不收敛或过拟合怎么办如果你训练时发现loss曲线震荡剧烈或者验证集指标一直不涨先别急着调参检查三件事数据标注是否有明显错误、data.yaml路径是否正确、类别数是否和标注的类别id对应。这三个问题占了训练异常原因的一大半。如果确认数据没问题模型还是不收敛优先调整学习率。AdamW优化器的初始学习率我一般设置在0.0005到0.001之间太高容易震荡太低收敛过慢。过拟合的典型表现是训练集loss持续下降但验证集mAP停滞这时优先考虑降低模型大小从m降到s、增加数据增强强度、添加weight decay或者直接用早停机制。还有一个容易被忽略的点验证集和训练集的数据分布要保持一致。我一开始按时间顺序划分数据集某一批光照条件特殊的数据全部进了验证集导致模型评估结果虚低。后来改为随机划分评估结果才恢复正常。这个细节在数据量小的时候尤其重要。5.4 推理速度不达标怎么优化如果你的部署环境对推理速度有硬性要求优化方向按收益从高到低排列固定输入尺寸转TensorRT/ONNX、降低输入分辨率从1280降到960或640但要注意小目标精度损失、换更小的模型从s降到n、开启FP16推理。实测下来YOLO11s在TensorRT FP16下1280×1280输入的单帧推理延迟大约30到40msRTX 4090基本能满足30fps以下的实时分析要求。6. 总结与经验心得这期项目从数据处理到模型部署完整走了一遍有几个心得体会想分享给做类似项目的朋友。第一垂直场景目标检测项目的瓶颈往往不在模型而在数据。模型选型、调参这些都有成熟的方法论但高质量的数据需要自己投入大量时间去采集、筛选、标注和校验。如果项目时间有限优先把精力放在数据质量把控上比反复调参收益高得多。第二评估指标一定要跟业务挂钩。mAP是通用指标但铁路障碍物检测这个场景里漏检和误报的实际代价完全不同不能只看mAP选模型要结合precision和recall的取舍来定。第三部署时不能只关注模型精度还要考虑系统的整体逻辑。ROI过滤、帧间跟踪、按类别置信度阈值这些后处理逻辑对最终系统效果的贡献往往不亚于模型本身。最后说一个我踩过的坑模型在验证集上mAP很高但一跑真实航拍视频就频繁误报。后来排查发现真实视频里的画面抖动和运动模糊是训练集里没有的。解决方案是在训练增强里加入了轻微的模糊和运动伪影同时在推理端对相邻帧做了去重和跟踪。所以做这类项目一定要想尽办法让训练数据模拟真实部署时的数据分布。这期内容就到这里整个过程从数据到系统都有完整的链路如果你也在做无人机巡检或者类似的垂直场景目标检测项目希望这些实操经验能帮到你。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门