ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

无人机露天矿巡检:轻量化检测跟踪一体化模型的设计与部署

无人机露天矿巡检:轻量化检测跟踪一体化模型的设计与部署

这几个数字是我自己后来反复盯了很久的:4.39M 参数,整机功耗压到 8.3W,检测和跟踪放在同一个模型里,跑在无人机机载设备上,对着露天矿的粉尘、陡坡、卡车和移动设备做实时巡检。“检测+跟踪一体化”这个思路,听着像把两个任务硬塞进一个网络里省事,但把参数和功耗压到这个量级以后,真正要解决的问题反而不是“模型能不能收敛”,而是“无人机在矿山上那点算力和电量,到底能撑住多复杂的逻辑”。

这篇文章就把我自己的完整设计过程拆给大家。从为什么一定要做检测+跟踪一体化,到轻量化骨干选型、量化部署、露天矿场景的特殊优化,再到一次实地飞行测试的复盘和排查记录,尽量把能抄作业的部分都写清楚。

1. 项目背景与设计思路拆解

1.1 露天矿巡检场景到底难在哪

露天矿环境和普通城市园区巡检完全不同。先说几个我拿到项目需求后第一反应就绷紧的点:

第一,目标类型非常杂。固定设备、移动车辆、人员、边坡裂缝、运输道路上的异物,每一类目标的大小、运动规律、出现频率都不一样。卡车在主干道跑起来速度很快,而边坡上的小石块可能几十秒都不动。想用一个统一框架去处理,不能靠单一检测头硬扛。

第二,矿区的光照和天气变化很极端。清晨和黄昏的逆光会把目标压成剪影,中午地面的热浪会造成强烈的空气抖动,扬尘起来以后目标被大面积遮挡。这些干扰对单帧检测的影响极大,但如果模型能利用前后帧的时序关系,很多误检和漏检是可以被纠回来的。

第三,无人机的飞行姿态本身也在干扰感知。飞机转弯时机身倾斜,云台虽然做了补偿,但画面里的目标仍会有明显的尺度突变和位姿变化。如果模型只依赖单帧特征,很容易出现“前几帧跟住了,一转向就丢掉”的情况。

所以在设计一开始,我就没有把“检测”和“跟踪”当成两个独立模块来处理。项目标题里写的是“检测+跟踪一体化”,我的理解是:用跟踪的时序信息去辅助检测,再用检测的置信度去校正跟踪结果,两者共享一套特征。这不是为了方便模型跑得快,而是露天矿这种场景,单靠任何一边都撑不住。

1.2 为什么必须把检测和跟踪揉成一个模型

最常见的目标跟踪方案是先跑一个检测器,再把检测框交给跟踪算法做数据关联。这个两段式方案理论上很稳,但在机载边缘设备上有几个绕不过去的问题:

  • 两段式方案需要分别维护检测器和跟踪器的状态,内存开销翻倍。
  • 跟踪算法通常是单独优化的,部署时要同时编写两套推理逻辑。
  • 在算力受限平台上,每多一次额外的特征提取或后处理循环,都是实打实的帧率损耗。

我选择的是单模型同时输出检测框和多维运动特征,把检测与跟踪作为同一个网络的孪生输出。具体来说,模型在每一个关键帧上不只输出框的位置和置信度,还会输出一个高维的实例嵌入向量。下一帧到来时,网络可以用上一帧的嵌入向量与当前帧的候选目标做相似度匹配,完成跨帧数据关联。这样,跟踪不是外挂,而是融入在特征提取的同一个前向过程里。

这个做法的好处很明显:全流程只有一个前向推理,参数和访存开销都被摊薄了。更重要的是,时序信息能参与到检测中来。当某条特征在连续几帧里持续追踪同一目标时,即使当前帧目标部分被扬尘遮挡,模型也能根据时序预测框的位置,而不是直接丢掉目标。

1.3 4.39M 参数和 8.3W 功耗意味着什么

这个数字大家可能没什么概念,我换算一下。4.39M 权重参数,按 FP32 精度存储大概是 17.6MB,换成 INT8 就只剩 4.4MB 左右。配合三五百兆的运行时缓存,已经完全可以在机载小算力设备上跑起来。

8.3W 是实测量到的整机功耗,包含主控、NPU、摄像头、图传和传感器模组。这个功耗水平最直接的价值是散热压力非常小。巡检无人机通常没有主动风冷,靠机身外壳被动散热。之前用一块高性能工控板跑检测,整机功耗冲到 25W,机身热到不敢用手碰,电池续航直接从 40 分钟跌到 25 分钟。现在整机功耗只有 8W 级,机载电池的压力小了很多,留出了足够的飞行余量。

在算法侧,8.3W 的推理功耗对应的是很宽裕的能效比。大部分轻量化模型只要不刻意堆分组卷积和动态结构,在这个功耗档位上都能跑到中等帧率。实测下来,单路 1080p 视频流可以稳定跑到 15~20 FPS,对于慢速盘旋的矿山巡检任务完全够用。

2. 轻量化模型的关键技术选型

2.1 骨干网络怎么选才不拖后腿

骨干网络决定了模型的基础容量和速度上限。我从头到尾对比过三类方案:

骨干方案参数体量单帧推理耗时适合程度问题点
通用残差网络较沉慢不推荐机载端访存压力大
移动端轻量网络轻很快推荐语义信息稍弱
自蒸馏结构可调中等可选训练门槛高

我最后选择了移动端轻量网络作为骨干,没有用更花哨的结构。原因很朴素:轻量化骨干在特征提取效率上经过了大量场景验证,工程化资料齐全,各种部署工具都默认支持。对于巡检这种要长期维护的项目,成熟方案的稳定性比单点精度更值钱。

在骨干尾部,我没有用最宽的最高层特征,而是保留了三层不同分辨率的特征图做跨层融合。露天矿里的目标尺度差异实在太大,摄像头在 100 米高度看一辆卡车可能只有十几个像素,但飞低到 20 米时同一辆卡车能占满半边屏幕。单一尺度的特征不可能同时照顾好这两种情况。

2.2 检测分支和跟踪分支怎么做到“一体化”

一体化的关键不只是共享骨干,而是让检测分支和跟踪分支彼此帮忙。

我的做法是这样:网络在输出检测框的同时,为每个检测框生成一条 64 维的实例嵌入向量。这些向量不是随便学出来的,训练时我会构造大量“跨帧配对样本”,让同一个目标在不同帧、不同角度下的向量尽可能接近,同时让不同目标之间的向量尽可能区分。这样推理时只需要计算当前帧所有候选框的向量与上一帧轨迹向量之间的距离,用简单的最近邻匹配就能完成跟踪。

这个设计和普通两段式跟踪最大的区别在于:两段式是被动关联,先检测再匹配;一体化是两者共享同一个特征空间,检测分支的错误特征会反馈到跟踪,跟踪的时序信息又会反过来修正检测置信度。比如某个目标在上一帧置信度很高,但这一帧因为扬尘导致检测分数骤降,模型不会直接把它判为“消失”,而是结合时序预测把位置保留下来,等待下一帧重新确认。这就是露天矿场景里比“纯检测+外挂跟踪”更稳的地方。

2.3 功耗和算力的平衡策略

我遇到过不少同学一上来就压缩输入分辨率,图像从 1080p 直接降到 480p,算力是省了,但小目标直接丢了。这是典型的“捡芝麻丢西瓜”。

我的策略是保持推理输入 320×320 的不变,但把视频流分为两条通路:一条原始高清流用来回传地面站和人工判读,另一条降采样到模型输入尺寸做实时推理。这样既保证了算法侧的帧率,又保留了原始画面的细节证据。毕竟无人机巡检不只是跑算法,还要拍视频留给后台复盘,两者缺一不可。

另一个功耗大头是模型推理框架的效率。同样一个 INT8 模型,放在不同的推理引擎里差距可以到 20% 以上。我会在量化后做一次逐层耗时分析,找出耗时占比最高的几个算子,尽量把图结构中多余的内存拷贝和格式转换剪掉。这一步能在不动模型结构的前提下挤出 10% 左右的帧率收益。

3. 训练与部署的实操细节

3.1 矿区数据的准备与增强

真实矿区的标注数据非常难拿。露天矿场地大,车辆设备移动频繁,人工标注一个小时的航拍视频可能要三个人干两天。所以我采用了一套“真实数据打底 + 合成数据扩量”的混合策略。

真实数据主要覆盖了三个典型飞行高度:30 米、60 米和 100 米。每次飞行固定带 RTK 记录飞行坐标,这样我可以反向算出图像中每个像素对应的实际地面尺寸,做精确的目标尺度标注。

合成数据的思路是用矿区三维模型配合灾害场景技术渲染生成训练样本。虽然没有真实照片那样丰富的纹理细节,但用来训练检测网络的几何特征和尺度敏感性非常有效。合成样本里我会故意设置大量遮挡、扬尘和逆光条件,把模型在恶劣环境下的适应性提前拉起来。

数据增强方面,除了常规的翻转、裁剪、色彩抖动,我重点加了两种:一种是动态模糊模拟无人机悬停抖动,另一种是随机插入模拟粉尘的噪声块。这两种增强直接对应露天矿最常见的画面退化。

3.2 训练策略与量化过程

轻量化模型对训练策略的敏感度比大模型高很多。大模型容错性强,随便什么学习率和优化器都能收敛;小模型一个学习率设置不对,可能直接训飞。

我用的方式是:先在合成数据上用较大的初始学习率做预训练,再切到真实数据上用较小的学习率微调。预训练阶段让模型学会基本的几何结构和尺度关系,微调阶段专门适应真实矿区的纹理分布和拍摄角度。两个阶段的损失函数略有不同:预训练偏重检测损失,微调时加入跟踪嵌入损失。

量化是这里最需要耐心的一步。虽然 INT8 模型体积和功耗都更友好,但直接全量化容易掉点。我采用逐通道量化和混合精度策略:对大部分卷积层做 INT8,但对最后的检测头和嵌入头保留 FP16。因为这个部分对数值精度最敏感,稍微扰动几个百分点的精度损失都能看到匹配错位。

校准数据集一定要用真实矿区的图像,不能用合成图。合成图的数值分布和真实图有偏差,用它做校准集,量化后的模型在真实场景里会出现预测分数普遍偏高的情况,非常坑。

部署时把训练好的权重导出成 ONNX,再转换到边缘推理框架。整个过程里我踩得最多的坑是算子兼容性。轻量化网络里经常用到的某些激活函数在部分推理框架里没有高效实现,需要手工替换成等价的组合算子。每替换一个算子,都要在边缘设备上重新实测精度和速度,不能光看误差对比,因为不同硬件对不同算子的加速效果差别很大。

3.3 机载部署的帧率与延迟压榨

机载设备运行推理时要同时承担摄像头采集、飞控通讯、图传编码和模型推理的任务。单纯盯着模型的推理耗时没用,整条链路里任何一环都会拖垮实时性。

我做了一个简单的流水线优化:摄像头采集和模型推理用双缓冲机制处理。摄像头采完一帧后不需要等模型跑完,而是立刻开始采集下一帧。这样采集和推理并行执行,整条链路的有效帧率从串行的 12FPS 提升到了 18FPS。

后处理也做了裁剪。模型输出原始检测框之后,NMS 按目标类别分组执行,而不是全图统一做一次大 NMS。露天矿的目标分布有明确区域特征:车辆集中在运输道路,人员集中在设备周围。按区域划分后再做 NMS,计算量能再降 20% 左右。

4. 露天矿场景的针对性优化

4.1 扬尘与误检的时序抑制

露天矿的扬尘问题比想象中严重得多。采场爆破后的灰尘能持续十几分钟不散,卡车经过干燥路面时扬起的尘土会直接把目标淹没。单帧检测在这种条件下会频繁出现“漏检-复检-再漏检”的抖动。

我的优化方案是在跟踪模块里增加一个延迟确认机制。一个新的检测目标不会立刻被当成跟踪目标,而是先进入一个候选队列,只有连续三帧都被检测到,才会正式创建跟踪轨迹。一旦轨迹建立,即使后续几帧的检测置信度很低,只要嵌入向量的匹配分数够高,轨迹仍然保留。这个机制对扬尘造成的间歇性遮挡非常有效,代价是新建轨迹的响应时间多了半秒左右。但对于巡检场景,稳定性比响应速度更重要。

针对爆破产生的粉尘云,我在分类标签里单独加了一个“粉尘”类别。把它当成一个目标类型来训练,模型学习到的特征背景就更准确,不会再像之前那样把粉尘误判成烟雾或者人员。

4.2 大尺度差别的多尺度策略

露天矿目标的尺度跨度大到离谱。同一颗摄像头对着不同高度的地面,工人在 100 米高度下可能只有 5×5 像素,但无人机下降后,同一工人可能变成 100×100 像素。

我不建议靠单一多尺度测试技巧硬撑。真正有效的是在训练阶段刻意做尺度扰动,让模型学会跨尺度识别同一目标。具体做法是:训练时对同一批图,随机缩放到 0.8 倍到 1.5 倍之间,同时传入多尺度特征融合层,强制模型从不同尺度特征中找到一致的目标语义。经过这种训练后,模型在真实飞行中面对尺度突变时不会出现明显的定位漂移。

还有一种情况是在高海拔飞行时目标过小,常规检测头压根找不到。我增加了一个专门的低层特征输出分支来处理小目标。这个分支结构简单、计算量小,但能明显提升远端小目标的召回率。代价是模型参数量多了大约 0.3M 左右,在 4.39M 这个体量下完全可接受。

4.3 光照突变和天气干扰的应对

露天矿一天之内的光照变化很猛。上午十点的直射强光会把卡车玻璃照成高光白斑,傍晚的阴影会把目标拉成长条。我吸取了一个教训:不要在模型输入侧做过于激进的像素归一化。有些套件默认把图像线性拉伸到 0~1 范围,这在矿区反而会把本来有价值的光照信息压平。

更好的做法是在训练数据里刻意保留光线变化。标注数据时把清晨、正午、黄昏分成三个时段分别做统计,每个时段单独配一组亮度校准参数。推理时根据无人机当前时间自动切换对应的校准配置。这个操作简单但很管用,不同时段的漏检率差别肉眼可见地缩小了。

雨水和雾气的影响我也有过实测。雨天镜头上的水珠会形成局部圆形光斑,这种干扰只靠算法很难完全消除。我现在一般建议雨天增加飞行高度,让镜头视场角覆盖更大范围,水珠的干扰面积相对变小。模型侧则增加了模拟雨线纹理的增强样本,让检测头学会忽略这种周期性纹理。

5. 一次实地飞行测试的完整复盘

5.1 测试环境与评估指标

项目验收前,我们在某矿区做了一轮完整的实地测试。天气是多云,风速 3 级左右,没有降雨但局部有扬尘。无人机按预设航线在 40 米和 80 米两个高度各飞两圈,重点覆盖运输道路、排土场和采掘工作面三个典型区域。

评估指标用了三套:检测侧用 mAP 和召回率,跟踪侧用多目标跟踪精确度和 ID 切换次数,整机侧用帧率和整机功耗。做到了优先保证跟踪不丢,再尽量提升检测精度。

由于目标尺寸跨度大,按 COCO 的固定 IoU 区间没法准确反映小目标表现,我改用自适应匹配阈值。测试集中的目标框按照像素面积分成大、中、小三档,每一档单独计算 AP 和召回率。这项改动让评估结果更贴近真实作业需求。

5.2 主要性能数据

高度检测 mAP大目标召回小目标召回跟踪精确度帧率整机功耗
40 米86.3%93.1%71.2%82.5%18.6 FPS8.3W
80 米81.7%87.4%58.9%77.9%18.2 FPS8.1W

整体来看,常用作业高度下的检测精度是够用的,但 80 米高度的小目标召回明显下滑。这不是模型容量不够,而是小目标特征在高空采集时本身信息量不足。后来我在航线规划里加入了一个策略:常规巡航飞 80 米快速扫全貌,重点区域自动下降到 40 米做精细巡检。这样既保住了效率,又解决了小目标召回问题。

5.3 测试中暴露的三个问题

第一个问题是运动模糊。飞机在转弯时云台补偿会有大约 50ms 的延迟,画面里快速移动的卡车会出现明显拖影。检测头的模糊增强样本虽然降低了漏检,但跟踪嵌入向量的匹配精度受到拖累。后来我在前处理里加了一个轻量的去模糊算子,只是对跟踪分支的特征单独做,对计算量影响不大。

第二个问题是阴影干扰严重。测试当天是多云,云层移动会让阴影边界不断变化,模型偶尔会把卡车阴影当成新鲜开挖的矿物区域。解决办法很简单:在训练样本里增加了矿区阴影区域与目标本体重叠难分的负样本,强迫模型学习区分目标边缘与阴影纹理。

第三个问题是 GPS 信号在采坑底部会偶尔丢失。没有定位信息时,无人机悬停漂移会让画面出现低频晃动。这时候纯视觉跟踪反而需要承担更多责任。好在一体化模型的时序预测抗住了这个工况,没有出现轨迹整体丢失,说明当初坚持跟踪与检测融合的方向是对的。

6. 实操中遇到的高频问题与排查建议

6.1 缩小模型但没有缩小精度差距

很多人在轻量化过程中一换小骨干网络,mAP 直接掉好几个点,第一反应是回退到原来的大网络。我的建议是先查数据侧,再查训练侧。

我遇到过几次类似的情况,最后定位出问题:小网络对输入的数值分布更敏感,原来的归一化参数是从大网络的数据统计里计算来的,换到小网络上根本不合适。重新统计轻量化模型在目标数据上的均值方差后,精度差距缩小了一半。第二步是调大训练轮数,小模型需要更多 epoch 才能充分收敛,尤其是一体化网络中跟踪分支的嵌入向量更新比较慢。

6.2 推理速度上不去,瓶颈不在模型

帧率不达标的锅,经常不在模型而在数据链路。图像解码、内存拷贝、框架预处理,每一步都可能成为瓶颈。我的排查顺序是:先用空图循环跑模型,测出纯推理耗时;再加上图像解码,测整链路耗时;最后加上画面回传和存储,测端到端耗时。对比这三个数字,就能知道瓶颈在哪一段。

实测最意外的一次是图像解码耗了总耗时的一半,原因是机载摄像头的输出格式需要先转到通用格式才能输入模型,这个转换没有硬件加速。后来换成摄像头直接输出模型需要的格式,整体帧率提升了 35%。有时候一个硬件的原生格式支持,比优化十个算子都管用。

6.3 常见异常对照速查表

现象可能原因优先排查项
检测框频繁闪烁单帧检测置信度过高/过低降低置信度阈值,启用时序确认机制
跟踪 ID 频繁切换嵌入向量区分度不足增大跟踪分支损失权重,延长训练轮数
高光区域大量误检光照归一化参数偏离按时间段分组校准亮度参数
目标在阴影边界丢失训练样本缺少明暗对比补充阴影与目标重叠的负样本
量化后精度骤降校准集分布偏差改用真实矿区图像重建校准集
整机功耗偏高框架存在多余拷贝逐算子耗时分析并剪枝

6.4 我的一些个人实操心得

从项目启动到落地,我最深的一条体会是:轻量化模型项目,工程占比永远比算法占比高。模型结构只占整个系统的一小部分,数据采集、部署适配、功耗优化、链路调优,每一项的工作量都不小。很多人过度关注如何设计一个更精巧的网络,却忽略了真正上线以后卡住你的往往是那些不太“高大上”的环节。

第二点是:合成数据能力远远被低估了。露天矿这样的封闭场景,正适合用三维建模加渲染生成高仿真训练数据。我在这个项目里真正积累下的算法优势,很大一部分来自合成数据策略而不是网络结构创新。场景固定、光照可控、目标类型明确,这些条件意味着合成数据可以在短时间内覆盖大量极端工况。

最后分享一个小经验:拿到项目以后,不要急着做模型选型。先把飞行高度区间、目标尺度分布、天气工况和续航约束全部量化出来。这些参数会直接影响骨干网络、输入分辨率和量化精度的选择。很多项目做到一半才发现机载功耗根本撑不住训练出来的模型,根源就在于需求分析阶段少做了一步测算。

如果后续你也在做无人机边缘巡检,无论是矿山、电厂还是化工园区,我建议把这篇文章里的流程当作一份检查单:先明确尺度区间,再做合成数据,然后选轻量化骨干,联调检测与跟踪,最后用功耗和帧率做验收指标。这个路径不保证每次都最快,但能让你少走大半弯路。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进