做河道巡检项目的人应该都有同感:河道很长,人工巡检一趟下来,几十公里的岸线和水面要靠人眼盯屏幕,一段无人机航拍视频看下来眼睛酸胀不说,漂浮垃圾往往就漏过去了。这几年智慧水利、数字孪生流域的项目越来越多,“无人机河道垃圾图像识别”这个词几乎成了一个标配需求,但真正把它从demo做成能稳定跑业务的系统,涉及的不只是训练一个目标检测模型那么简单。
这个项目标题看着直白,拆开看其实是三层东西:第一是无人机飞行平台和图像采集,第二是目标识别算法和模型优化,第三是边缘端推理与业务平台集成。只做其中任何一环都不算落地,能把三层串起来,并在真实河道环境里稳定运行,才算真正交付。这篇文章我打算从技术架构的拆解开始,把硬件选型、数据采集、模型训练、TensorRT部署、以及我在实际项目中踩过的坑全部梳理一遍,适合正在做智慧水利、智慧环保巡检系统的开发者和项目经理参考。
1. 项目概述:河道垃圾识别到底在解决什么问题
1.1 河道巡检的真实痛点
先说说场景本身。河道漂浮垃圾、岸坡堆放物、入河排污口附近的异常漂浮物,这些都是河湖监管的核心对象。传统人工巡检有几个很难绕开的痛点:一是效率低,一条几十公里的河道,靠人开车到桥头、岸边看,半天只能覆盖几个点位;二是时效性差,漂浮垃圾是移动的,一场雨之后上游冲下来一堆树枝、泡沫、塑料瓶,如果当天发现不了,可能就漂到下游去了;三是记录追溯难,靠手机拍照、纸质台账,数据零散,没法形成统一的 GIS 图层。
无人机航拍天然适合这个场景。一架多旋翼无人机,挂载可见光相机,沿着河道飞行二十分钟,能采集上千张高分辨率图像。但这又带来另一个问题:数据量太大,人工看图根本看不过来。我见过一些项目,前期用无人机飞了几天,存了几万张图,最后靠人工慢慢翻,效果比纯人工巡检好不了多少。这时候图像识别技术的价值就体现出来了,先用算法把疑似垃圾的目标筛出来,人工只需要复核算法标出的候选框,效率完全不一样。
1.2 技术架构的整体设计思路
从系统层面看,一个可落地的河道垃圾识别项目,技术架构可以分三层:
端侧是无人机平台和机载影像采集系统,负责飞行动作、拍照、图像缓存,以及可选的机载轻量化识别;边缘侧是部署在地面工作站或机载算力板卡上的推理服务,接收图像流,运行目标检测模型,输出检测结果和置信度;云端是业务平台,负责汇总识别结果、叠加地理坐标、生成工单、推送告警,并沉淀历史数据用于模型迭代。
我见过不少项目一上来就追求“机载实时识别”,把模型直接跑在无人机上。这个方向没有错,但要看成本和功耗约束。实际落地中,更稳妥的做法是“机载采集 + 边缘推理 + 云端管理”三层并行:无人机负责拍,地面站或便携算力盒子负责跑模型,云端负责业务流程。原因很简单,机载算力再强也有限,而河道巡检往往要连续飞几十公里,功耗、散热、飞行安全都要权衡。
1.3 为什么最终选择“AI识别 + 人工复核”的混合链路
这里要泼一盆冷水:任何目标检测模型在河道这种开放环境里,都不可能做到100%准确。水面反光、岸边植被阴影、桥梁墩柱、水鸟、甚至是漂浮的枯木,都可能造成误检;反过来,小尺寸的塑料瓶、半沉在水下的编织袋,又容易漏检。
所以在架构设计上,我强烈建议不要把AI识别作为唯一判定环节,而是做成“AI自动检出 + 置信度分桶 + 人工复核”的混合链路。具体来说,模型输出所有检测框后,按置信度分桶:高置信度结果直接进入告警流程,低置信度结果进入待复核队列,由平台人员在终端上快速确认。这样既保证了效率,又能把误报拦截在业务层之外。这个思路看起来笨,但落到真实项目里非常管用,客户满意度和数据积累速度都比纯自动判读好得多。
2. 硬件选型与数据采集
2.1 无人机平台、相机与算力板卡怎么选
无人机平台的选择取决于项目预算和载荷需求。我做过两种方案:一种是使用大疆经纬M300级别的小型行业无人机,载重大,可以同时挂载可见光相机和RTK模块,适合正式的河道巡检项目;另一种是自组方案,基于开源飞控(比如PX4或ArduPilot)搭配机身和云台,灵活性高,但需要团队有飞控调试能力,适合预算有限或需要深度定制的场景。开源无人机生态里经常提到的 SpaceDrone 之类的项目,本质上是给了你一个软硬件参考,真要用来干活,还是要自己调相机触发和数传链路。
相机选型上,我更看重动态范围和低光表现,而不是一味堆像素。1英寸CMOS、2000万像素级别的相机,配合等效焦距24mm到35mm的镜头,在30到50米高度飞行时,已经能拍清塑料瓶和编织袋这类目标。注意一点,无人机航拍常用的广角镜头边缘畸变比较明显,如果接的是正射影像拼接流程,要先用相机标定参数做畸变校正;如果只是做检测框标定,畸变影响相对小,但也要保证标定时使用的图片和推理时使用的图片来自同一套相机参数。
机载算力板卡的选择,我实际测试过几款。如果只在无人机上做轻量的预览检测,Jetson Orin NX级别的板卡(20 TOPS以上算力)够用,配合TensorRT跑一个YOLOv8n模型,能做到十几毫秒一帧。预算更紧的话,Jetson Nano也能跑,但帧率会掉到10帧以下,只能做抽帧检测。一定不要对ESP32-S3-CAM这类单片机级别的图像识别方案抱有太高期望,它适合做玩具验证或教学demo,不适合河道巡检这种对检测精度和稳定性有要求的场景。
2.2 飞行策略与图像采集参数
有了硬件,接下来是采集策略,这一步决定了你的训练数据和最终识别效果的天花板。
飞行高度直接影响地面采样距离(GSD),也就是每个像素代表的实际尺寸。以2000万像素相机、35mm等效焦距为例,在40米高度飞行,GSD大约在1.5厘米到2厘米左右,一个30厘米长的塑料瓶在画面里大约占15到20个像素,检测的难度不算太大;如果飞到80米以上,目标在画面里只剩几个像素,再强的模型也容易漏。
我常用的参数是飞行高度30到50米,航线沿河道走向布设,航向重叠率在70%以上,旁向重叠率在60%以上。重叠率的意义不只是为了拼接正射影像,也保证了同一个目标在多帧画面中出现,后续可以利用多帧投票机制来降低单帧误检率。拍摄角度推荐尽量正射或接近正射,俯拍状态下垃圾的几何形态最稳定,斜拍会带来透视形变,增加标注和检测的难度。
快门速度这块很容易被忽视。无人机飞行时,机身在前进和悬停之间会有持续的振动,快门太慢就会出现运动模糊。我要求拍摄参数里快门不低于1/1000秒,光圈适当收缩到f/5.6左右,ISO越低越好。如果光线太强,水面耀斑严重,可以加装偏振镜,实测对压反光效果非常明显。
| 飞行高度 | 大致GSD | 可稳定识别目标尺寸 | 推荐场景 |
|---|---|---|---|
| 30米 | 约1~1.5cm/px | 20cm以上目标 | 重点河段巡查 |
| 50米 | 约2~2.5cm/px | 30cm以上目标 | 常规巡河 |
| 80米以上 | 约4cm/px以上 | 50cm以上目标 | 快速大范围扫描 |
2.3 数据标注与数据集构建
模型训练的数据无外乎三个来源:自采航拍图、公开数据集、合成数据。公开数据集里能找到一些垃圾漂浮物、编织袋相关的标注数据,但要注意目标尺寸分布和拍摄角度跟我们真实航拍场景差别很大,直接用往往效果不好。我的经验是以自采航拍图为主,公开数据作为补充预训练语料。
类别设置不要设计得太细。有的项目一上来就分“塑料瓶、易拉罐、泡沫箱、塑料袋、编织袋”,模型很难学得过来。我习惯先设置为五类:塑料瓶、泡沫类、编织袋类、水草团、其他漂浮物。这里面最难的是“其他漂浮物”,它本质上是一个兜底类别,如果样本不够,建议先砍掉,只保留前四类,避免模型把噪声都学进去。
标注格式用YOLO的txt格式最方便,标注工具用LabelImg或者X-AnyLabeling都行。河道场景的目标普遍偏小,标注的时候必须严格按照目标的最小外接矩形框,不能随意扩大边框。如果目标模糊到连人都无法判断,就直接跳过不标,不要硬标,硬标只会给模型加噪声。数据集规模上,我建议至少要有3000到5000张图,每个类别样本量不低于500,小目标占比较低的类别,可以通过复制粘贴增强、MixUp等方式补充,这一点后面会细说。
3. 目标检测模型的训练与优化
3.1 模型选型:为什么从YOLO系入手
河道垃圾识别本质上是小目标检测问题,对实时性和部署友好度都有要求。目前工业界用得最多的就是YOLO系列,我以YOLOv8n和YOLOv8s作为主力基线。原因很简单:一是训练成本低,一张消费级显卡就能跑;二是导出ONNX转TensorRT非常成熟,边缘端推理效率高;三是YOLO系的anchor-free结构对小目标相对友好,配合高分辨率输入效果不错。
我也对比过RT-DETR这类基于Transformer的检测器,精度上有些场景确实更高,但对边缘端的工程适配、自定义NMS后处理这些环节,明显不如YOLO系省心。如果团队刚起步,建议直接选YOLOv8系列,尽快跑通全链路,再来讨论更高精度的替代方案。
| 模型 | 输入尺寸 | TensorRT FP16推理耗时 | mAP50(自测河道数据) | 适用平台 |
|---|---|---|---|---|
| YOLOv8n | 640 | 约6~8ms | 0.62 | Jetson Nano/Orin NX |
| YOLOv8s | 640 | 约10~12ms | 0.71 | Jetson Orin NX/工控机 |
| YOLOv8n | 1280 | 约16~20ms | 0.74 | Jetson Orin NX |
| YOLOv8s | 1280 | 约24~30ms | 0.79 | 高性能工控机 |
3.2 训练细节:参数、增强与调优
训练阶段的几个关键点,直接影响最终效果。
第一,输入分辨率。河道垃圾尺寸偏小,用640分辨率训练,很多目标在降采样到特征图时只剩几个像素,检测头根本学不到有效特征。我实践下来,训练时用1280或1536分辨率,推理时如果算力紧张可以降到960或1280,效果比直接用640好得多。代价是训练显存占用和推理耗时都上升,需要在硬件上做权衡。
第二,数据增强策略。我关注几个增强的组合:Mosaic和MixUp对提升小目标检测效果明显;HSV颜色扰动帮助模型应对不同光照条件;随机翻转要慎用,水面目标虽然上下翻转不影响认知,但河岸的遮挡关系会变,造成负样本错乱。另外,针对水面反光,可以在增强管线里加入随机亮度扰动和随机高斯噪声,让模型见过更多“脏图”。
第三,训练参数参考。我常用的配置:batch size 16,初始学习率0.01(配合SGD动量)或1e-4(配合AdamW),训练200到300个epoch,使用余弦退火学习率调度。损失函数直接用YOLOv8自带的CIoU损失,不用额外改。真正值得调的是后处理阈值,在验证集上网格搜索confidence阈值和NMS IoU阈值,我常用的起点组合是confidence=0.25、IoU=0.45,然后在业务数据上微调。
3.3 模型压缩:剪枝、量化与蒸馏
模型训练完只是第一步,要跑到Jetson或工控机上实时推理,还得做压缩优化。
最常规的是半精度FP16量化,这个在TensorRT里几乎无损,mAP掉0.5个百分点以内,速度提升20%到40%。如果想更进一步,可以尝试INT8量化,但需要用校准集做量化校准,校准集最好覆盖不同光照和水况的典型图像,否则某些场景下精度会掉得厉害。我在一个项目里用INT8量化YOLOv8n,mAP掉了大约1.8个百分点,但推理速度几乎翻倍,对于河道巡检这种任务,换取实时性很值得。
剪枝(结构化剪枝)可以减小模型体积,但手工剪枝容易破坏网络结构,导致精度崩掉。更稳妥的做法是蒸馏:用一个精度更高的YOLOv8m或者YOLOv8s作为教师模型,去蒸馏YOLOv8n,让小模型学习大模型的特征表征,精度提升通常比单纯剪枝更明显。这里有个心得:蒸馏时不仅要对齐分类和回归输出,还可以对齐中间层的特征图,尤其是C3/C4层,对小目标召回率的提升很有帮助。
4. 边缘端推理与系统集成
4.1 推理引擎选型与TensorRT加速
训练好的PyTorch模型不能直接上边缘端,常规流程是:PyTorch导出ONNX,再用TensorRT把ONNX转成engine文件。这个过程有几个容易踩的坑。
导出ONNX时要注意固定输出节点。YOLOv8的输出包含多个尺度的特征图,导出时要把concat操作放在模型内部完成,最好使用torch.onnx.export时设置动态轴,但建议先固定batch=1,避免后续TensorRT构建时出现不必要的动态shape分支。转TensorRT时的常用命令大致是:
trtexec --onnx=model.onnx --saveEngine=model_fp16.engine --fp16 --workspace=4096如果用到INT8,还需要指定校准数据集目录:
trtexec --onnx=model.onnx --saveEngine=model_int8.engine --int8 --calib=/path/to/calib_images转完之后要验证一下输出与原始模型的差异,特别是坐标解码方式。YOLOv8的检测头在ONNX导出后输出的是原始预测值,需要自己写解码逻辑做坐标换算和NMS,也可以把EfficientNMS插件直接集成到engine里,省去在Python端做繁琐后处理。但集成插件后灵活性会降低,比如后续想改confidence阈值就得重新构建engine,所以我的习惯是阈值参数单独配置,后处理放在推理服务代码里。
4.2 端-边-云协同架构
推理服务跑起来之后,就要设计数据链路了。河道巡检的场景里,无人机一般通过RTSP或RTMP把视频流推到地面站,地面站的推理服务按固定帧间隔抽帧检测,也可以接收机载端传来的关键帧。检测结果需要包含几样东西:目标类别、置信度、检测框坐标、时间戳、对应的飞行位置。
位置信息至关重要。我的做法是:无人机端把GNSS坐标和IMU姿态记录到每帧图像的EXIF或同步日志里,推理服务检测出目标后,根据图像中心点GSD和飞行姿态,把像素坐标换算成经纬度偏移,最终得到目标的近似地理坐标。这个换算不需要特别精确,能定位到河道的一个断面就够用了,但一定要做,否则后台告警连位置都没有,客户根本没法用。
云端业务平台通过MQTT或者HTTP接收边缘端推送的检测结果,存入空间数据库,叠加到底图上,生成告警工单。工单流程里,要预留一个“人工确认”的状态,这就是前面提到的混合链路。这样既保证了自动化的效率,又不会让误报直接打扰到河道管理人员。
4.3 性能瓶颈定位与稳定性保障
边缘端部署最头疼的不是模型精度,而是稳定性。河道巡检经常在野外长时间运行,设备散热、供电、通信中断都是常态。
Jetson板卡在长时间高负载推理时,温度会迅速上升,触发降频后推理帧率掉一半都有可能。我的解决方案是:在系统层面限制GPU和CPU的最高频率,牺牲一点峰值性能,换取稳定的平均推理速度;同时给算力盒子加散热风扇或被动散热片,放在阴凉处。实测下来,Orin NX限制到70%的性能后,连续跑6小时,帧率稳定在预期值没有明显波动。
通信链路方面,无人机和图传设备的信号在河道峡谷、桥下区域容易丢。不要指望单独一条链路打天下,建议同时使用无线电图传、4G/5G数据通道和本地缓存三重保障。边缘端所有检测结果和原始图片先落本地缓存,再异步上传云端,一旦网络恢复自动补传,这样即使现场通信断了,数据也不会丢。
5. 常见问题与排查技巧实录
5.1 误检漏检痛点速查表
这里整理一张我根据多个河道项目排查经验做的问题速查表,遇到问题可以直接对着查:
| 现象 | 常见原因 | 解决手段 |
|---|---|---|
| 岸边浅色石头被识别成白色垃圾 | 训练样本中白色垃圾过多,石头类难负样本缺失 | 收集大量河岸石头负样本,加入训练集 |
| 水面反光区域频繁误检 | 图像高光区域纹理类似垃圾边缘 | 使用偏振镜采集,训练时加入亮度扰动增强 |
| 半沉水编织袋漏检 | 目标与水体背景对比度低 | 提高输入分辨率,增加半沉水样本,使用多帧融合 |
| 快速移动垃圾漏检 | 运动模糊导致目标轮廓模糊 | 提高快门速度,或采用机械快门相机 |
| 桥墩、岸边阴影误检 | 几何形状和大小的上下文信息不足 | 引入更大感受野的模型,或增加带桥墩阴影的负样本 |
| 同一目标连续多帧重复告警 | 多帧检测结果未做去重 | 根据位置和时间做目标关联,合并重合度过高的告警 |
5.2 水面环境下的图像干扰处理
水面环境是河道垃圾识别跟普通目标检测最大的不同点。反光、倒影、波纹都会干扰模型,其中最难处理的是倒影。岸边的树、桥、广告牌倒映在水面上,形状拉长变形,跟垃圾的视觉特征有一定相似性,模型很容易误判。
我验证过几种处理办法。第一是采集端处理:加偏振镜,这在前面提过,实测最有效;第二是推理端预处理:对输入图像做限制对比度自适应直方图均衡化(CLAHE),能稍微提升低对比度目标的可分性,但对反光严重的区域帮助有限;第三是利用时序信息:连续多帧画面里,真实垃圾会随水流移动,而倒影的形状和位置会随着视角变化发生明显跳跃,通过多帧跟踪和置信度投票,可以过滤掉大量单帧误检。
具体实现上,不用做太复杂的跟踪算法。简单一点的做法是:取目标在连续三帧检测框的重叠度,如果三帧中至少两帧检测到且位置变化符合水流方向的速度约束,就认为是有效目标;否则就丢弃。这个规则简单,但效果出奇地好,能砍掉至少一半的倒影误报。
5.3 长期维护与模型迭代建议
模型上线不是终点,而是另一个循环的起点。河道场景随季节变化很大:汛期水浑,漂浮物以树枝杂物为主;秋季落叶多,水面黄褐色物体增加;冬季光线弱,图像噪声严重。一个只在夏季数据上训练的模型,到秋冬季精度大概率会掉。
所以我在项目里一定会做数据回流闭环:所有误检、漏检、人工复核结果都回传到样本库,按周或按月增量训练。增量训练不推荐把新旧数据混合后从头训,因为成本高;更推荐的方法是保留旧模型,加载其权重作为预训练,再混入新增数据做微调。这样既能控制训练耗时,也能防止灾难性遗忘。
版本管理也要提前想好。我给每个模型都维护一个版本号、训练数据统计、验证集指标、部署时间、运行设备对应关系。模型文件用哈希值做标识,部署时记录灰度范围和回滚方案。别小看这一步,我见过不少项目,模型更新后误报率暴增,却因为找不到旧版本而回滚不了,最后只能紧急重训,非常被动。
最后再分享一点实际体会
做了几个河道垃圾识别项目之后,我最大的感受是:算法模型只占整个落地工作的三分之一,剩下三分之二是数据工程和系统工程的体力活。识别精度从70%提升到85%,靠模型调参还能勉强实现;从85%提升到90%,几乎全靠高质量样本和合理的业务链路设计。
另外一个小技巧,我每次去河道现场采集数据,都会刻意把飞行时间安排在晴天的上午和下午各飞一次,这样数据里自然覆盖了不同光照角度。事实证明,这种看似随意的数据多样性,对模型应对真实环境的贡献,比任何高级网络结构都大。如果你正准备启动这类项目,我的建议是第一周不要碰模型,先把飞行采集和标注流程跑顺,你会感谢这个决定。