去年在苏北万亩水稻种植基地落地无人机智能巡检项目,目标是替代人工下田巡查,实现稻飞虱、纹枯病、稻瘟病三类主要病虫害的早期预警。初期图省事,直接拿公开农业数据集训好的YOLOv26-s上线,结果飞了两个架次就被农技员打了回来:早期病斑几乎全漏检,杂草、泥斑、水渍被当成病害报了一堆,准确率还不如人工巡田。
前后磨了两个半月,从数据集采集标注、模型小目标改造,到推理端切片优化、业务端统计输出,全链路挨个踩坑调整,最终落地时,100米飞行高度下早期病斑检出率稳定在89%,单日单架次覆盖3000亩,虫情预警比人工提前3-5天,全基地农药用量整体下降了16%。
今天把整套落地方案完整拆开,从核心痛点、数据集构建、模型改造到工程落地,讲透无人机航拍场景下病虫害检测的所有关键节点。
一、先搞懂:无人机航拍病虫害检测,到底难在哪?
农业航拍和通用目标检测完全不是一回事,预训练模型直接搬过来一定会水土不服。核心难点集中在四个方面,每一个都能直接决定项目能不能用。
1.1 目标极小:早期病害特征几乎被背景淹没
病虫害预警的核心价值在“早期”,等到整片发黄、大面积枯死才发现,已经错过了最佳防治期。但100米常规巡检高度下,早期纹枯病的病斑只有5-15像素,稻飞虱虫体甚至只有3-8像素,占整张4000×3000航拍图的比例不到0.01%。
经过YOLO五次下采样后,这类极小目标在深层特征图上连一个完整像素都占不到,特征完全被背景淹没。模型学不到有效特征,自然漏检率居高不下。
1.2 视角特殊:预训练模型迁移效果极差
通用COCO数据集几乎全是平视、侧视视角的物体,而无人机航拍是完全垂直俯拍,没有立体阴影、没有侧视纹理,目标的外观特征和预训练数据分布差异极大。
比如水稻纹枯病,侧视看是茎秆上的云纹状病斑,俯拍只能看到叶鞘上的黄褐色小点,特征完全不同。直接用预训练权重迁移,相当于让模型从头学新特征,效果自然好不了。
1.3 类间相似、类内差异大,分类难度高
- 类间相似度高:早期多种病害都是黄褐色小点,人眼凑近了都容易认错,更别说模型;杂草枯叶、泥点、水渍、化肥残留,外观和小病斑高度相似,很容易误检。
- 类内差异大:同一种病害,在分蘖期、拔节期、抽穗期外观完全不同;晴天强光、阴天漫射光、清晨露水条件下,颜色、纹理差异也极大。模型很容易只学会特定时期的特征,换个场景就失效。
1.4 背景干扰复杂,负样本覆盖不全
航拍图里的干扰源太多:田埂、农机车辙、积水反光、枯叶、杂草、鸟粪、地膜碎片,都可能被误判成病害。如果训练集里没有覆盖足够的负样本,上线后误报率会高到完全没法用。
二、第一步:数据集做扎实,决定模型的真实上限
农业检测项目,数据的权重远大于模型结构。把数据做对了,基础模型就能涨30个点;数据有问题,再复杂的模型也救不回来。
2.1 全场景采集,避免分布偏移
采集阶段就要覆盖所有真实业务场景,不能只挑好拍的晴天正午,否则训练集和落地场景分布不一致,精度再高也是纸上谈兵。
- 多高度覆盖:采集50m、80m、100m、120m四个常用巡检高度的数据,对应不同尺度的目标。不要只训单一高度,否则飞高一点漏检,飞低一点误检。
- 全时段覆盖:清晨露水期、正午强光、傍晚弱光、阴天漫射光,四个时段全覆盖。很多病害在露水干前后外观差异极大,只采正午数据,早上飞就全崩。
- 全生育期覆盖:从分蘖期到成熟期持续采集,每个生育期至少保证2000张有效标注图。水稻不同生长阶段的叶片形态、病害表现完全不同,缺了哪个阶段,到了那个月模型就失灵。
- 足量负样本:专门采集健康田块、杂草田、积水田、秸秆还田田块,整理八大类高频误检负样本,每类至少500张。负样本不用精细标注,整图作为背景即可,但一定要全。
2.2 标准化标注,统一判断口径
农业标注最容易出的问题是标准不统一。三个标注员标同一批图,对早期病斑的判断差异能达到35%,标出来的数据本身就是错的,模型不可能学好。
我们的做法是:
2.3 定制化数据增强,针对性补强
普通的翻转、缩放不够,要针对俯视角和小目标场景做定制化增强:
- 几何增强:0-360°随机旋转(俯视角旋转不改变语义)、随机重叠裁剪、马赛克增强,强制模型适应任意角度、任意尺度的病斑。
- 光照增强:随机亮度、对比度、饱和度扰动,加薄雾、高斯噪声,模拟不同天气和不同画质的航拍效果。
- 小目标重采样:提高包含小目标图片的采样权重,避免模型被大面积健康背景和大病害主导,学不到小目标特征。
- 背景融合增强:把标注好的小病斑随机粘贴到不同健康背景中,快速扩充小目标样本量,缓解小目标样本不足的问题。
三、模型侧优化:四点改造,精准命中航拍小目标
基础选型我们选了YOLOv26-s,核心原因是体积小、速度快,后续能方便地部署到机载边缘盒或者地面站。原生模型在我们的数据集上小目标AP只有27.4%,经过四点针对性改造后,涨到了76.8%,而且全部兼容INT8量化,不影响落地部署。
3.1 零成本优化:锚框重新聚类
这是第一步必做的优化,零代码改动成本,就能带来5-8个点的小目标提升。
默认锚框是基于COCO数据集统计的,最小的锚框也有十几像素,而我们的数据里大量5-10像素的极小病斑,根本匹配不到正样本。模型学不到足够的正样本,自然召回率上不去。
用k-means基于自有数据集的标注框宽高重新聚类,生成适配的9组锚框。我们聚类后最小锚框从12×9降到了4×6,正样本匹配率直接提升了一倍多。
核心实现逻辑:
import numpy as np
def kmeans_anchors(boxes, k=9):
"""基于标注框宽高聚类生成适配锚框"""
box_wh = boxes[:, 2:4] – boxes[:, 0:2]
n = len(box_wh)
centroids = box_wh[np.random.choice(n, k, replace=False)]
for _ in range(100):
# 以IoU为距离度量
distances = []
for wh in box_wh:
inter = np.minimum(wh[0], centroids[:, 0]) * np.minimum(wh[1], centroids[:, 1])
union = wh[0]*wh[1] + centroids[:,0]*centroids[:,1] – inter
distances.append(1 – inter / union)
distances = np.array(distances)
# 分配最近簇
assign = np.argmin(distances, axis=1)
# 更新簇中心
new_centroids = np.array([box_wh[assign==i].mean(axis=0) for i in range(k)])
if (centroids == new_centroids).all():
break
centroids = new_centroids
# 按面积从小到大排序
return centroids[np.argsort(centroids[:,0] * centroids[:,1])]
3.2 新增P2检测头,守住极小目标底线
原生YOLO只有P3/P4/P5三个检测头,最小的P3层下采样8倍。对应4000像素的航拍图,每个格子对应8×8像素,小于8像素的病斑连一个格子都占不满,特征提取非常弱。
我们在下采样4倍的位置新增P2检测头,专门负责32像素以下的极小病斑。改动量很小,只需要在Neck增加一层上采样融合,Head增加一个检测输出层,兼容原生训练逻辑。
代价是计算量增加约15%,但小目标AP直接涨了18个点,对于早期预警这个核心需求来说,完全值得。
3.3 浅层插入轻量注意力,过滤背景噪声
小目标检测最大的敌人是背景噪声。深层特征语义强但细节少,不适合小目标;浅层保留了丰富的纹理和边缘信息,但背景干扰也多。
我们在C2、C3两个浅层特征层插入DPSE动态金字塔注意力,用多尺度池化生成通道权重,强化病害的特征响应,抑制杂草、泥斑这类背景噪声。参数量仅增加0.3M,几乎不影响推理速度,小目标AP再涨4个点。
3.4 损失函数适配,让模型更关注小目标
原生损失函数对所有目标一视同仁,但小目标的定位容错率远低于大目标——偏移1个像素,对大目标不算事,对10像素的病斑就是10%的误差。
两个调整方向:
四、推理端工程优化:不重训模型,再提一档效果
很多人训完模型就完事了,其实推理端的工程优化,往往能带来比模型改造更明显的收益,而且完全不需要重新训练。
4.1 SAHI切片推理:解决大图缩放丢细节的死穴
无人机原图普遍在4000×3000像素以上,直接缩放到640×640送入模型,小病斑直接就缩没了;用原图推理,速度慢到完全没法批量处理。
最优解是SAHI切片推理:把大图切成带重叠的小切片(我们用640×640,重叠率设为20%),逐个切片送入模型检测,最后把所有检测结果合并,还原回大图坐标。
这个方法纯推理端优化,不需要改模型,小目标召回率能再涨12%以上。配合批量推理,处理一张4K航拍图只需要1.5秒左右,完全满足批量处理需求。
4.2 ROI作物区域过滤,从源头降误报
航拍图里有大量不可能发病的区域:田埂、道路、沟渠、防护林、水塘。把这些区域提前裁掉,只在作物区域做检测,一举两得:
- 减少无效计算,推理速度提升20%-30%;
- 剔除了大量背景干扰,田埂杂草、水面反光这类误报直接清零。
每个田块预先配置ROI多边形区域,推理时先裁剪再检测,最后坐标映射回原图。不同区域还可以配置不同的检测阈值,比如长势弱的区域灵敏度调高一点,正常区域调低一点,进一步平衡召回率和误报率。
4.3 分级检测策略,平衡速度与精度
不是所有图片都需要用最高精度的模型跑。我们采用两级检测策略:
整体处理效率能提升2-3倍,而且绝大多数正常图片用轻量模型就能筛掉,高精度模型只处理少量异常图,兼顾了速度和精度。
4.4 后处理优化:让结果符合业务需求
模型输出的原始检测框,不能直接给业务端用,还要做一层业务化的后处理:
- 重叠去重:切片拼接的重叠区域会出现重复检测框,用NMS+距离阈值做二次去重。
- 面积分级:根据病斑面积和密度,分成轻度、中度、重度三个等级,对应不同的防治建议。
- 连片合并:相邻的同类别病斑自动合并统计,输出整片发病区域,方便生成热力图和防治处方。
五、完整落地系统:从航线规划到病害报告的全闭环
模型只是整个系统的一部分,真正落地要打通从数据采集到业务输出的全流程,形成可用的闭环。
5.1 采集端:自主航线+自动回传
- 提前在平台里标注田块边界,系统自动生成巡检航线,设置飞行高度、重叠率、拍照间隔。
- 无人机按航线自主飞行,拍摄的照片实时回传地面站,不需要人工导数据。
- 每一张照片自动记录GPS坐标、飞行高度、拍摄时间,为后续结果定位和热力图生成做支撑。
5.2 边缘端:就近推理,实时输出
地面站搭载RK3588算力盒,模型做INT8量化,落地后单张4K图处理时间1.2秒。一个架次飞20分钟,落地后5分钟就能出初步检测结果,农技员当天就能安排针对性巡查。
5.3 平台端:可视化+统计分析
- 病害热力图:把所有检测结果映射到卫星底图上,生成全田块病害热力图,一眼就能看出重点发病区域。
- 统计报表:自动统计每个田块的发病率、虫害密度、病害类型占比,生成标准化巡检报告,直接导出给种植团队。
- 防治建议:结合病害等级和作物生育期,给出对应的农药用量和防治方案,精准施药,减少农药浪费。
5.4 迭代闭环:越用越准
建立样本回流机制:
- 农技员在平台上可以一键标记误检和漏检,自动进入待标注库。
- 每季度做一次增量训练,更新模型版本。
- 新作物、新区域先小范围试点,补充数据后再全量推广。
六、实测效果与消融数据
我们在苏北基地的独立测试集上做了完整的消融实验,所有测试均为100米飞行高度的真实航拍图,核心指标如下:
| 原生YOLOv26-s + 公开数据集 | 52.1% | 27.4% | 1.0s |
| +自研数据集+锚框重聚类 | 70.3% | 48.6% | 1.0s |
| +P2检测头+注意力+损失优化 | 82.7% | 76.8% | 1.2s |
| +SAHI切片+ROI过滤+后处理 | 89.1% | 83.5% | 1.5s |
业务端落地效果:
- 单架次单日覆盖面积:3000亩,是人工巡查的15倍
- 早期病害预警提前量:3-5天
- 农药用量下降:全基地平均16%
- 巡田人力成本:降低72%
七、落地踩坑实录:六个最容易栽跟头的地方
坑1:只采晴天正午数据,阴雨天全崩
初期图省事,只在晴天中午采集数据,结果第一次阴天试飞,漏检率直接冲到50%。阴天漫射光下,病斑的颜色对比度大幅下降,模型完全认不出来。补全了全时段、全天气的数据后才恢复正常。
坑2:杂草与病斑混淆,误检率居高不下
阔叶杂草的黄叶、枯苗,和早期病斑外观高度相似,上线初期误报里一半都是杂草。专门补充了几千张各类杂草的负样本,针对性训练后,误检率下降了65%。
坑3:连片病斑统计不准,业务端没法用
严重发病区域病斑连成片,模型输出一堆零散的小框,没法统计发病面积和严重程度。后来调整了标注规则,增加连片区域标注,后处理加了合并逻辑,输出的统计数据才真正能用。
坑4:单一高度训练,换飞行高度就失效
一开始只按100米高度采集训练,后来为了提高效率飞到120米,检测效果直接跳水。补了多高度数据后,模型在80-120米区间都能稳定检出。
坑5:大图直接缩放推理,小目标全漏
最开始图省事,把4K图直接缩到640推理,结果早期小病斑几乎全漏。换成切片推理后,小目标召回率直接涨了一倍多。农业航拍场景,这一步绝对不能省。
坑6:一劳永逸不迭代,换季就掉点
水稻不同生育期的外观差异极大,分蘖期训的模型,到抽穗期精度会掉十几个点。必须建立持续迭代机制,每个生育期补充新数据,定期增量更新模型,才能全年保持稳定。
总结
无人机+YOLO做农业病虫害检测,从来不是拿个预训练模型跑一跑就能落地的事。它的核心难点不在模型本身,而在对农业场景的深度适配。
数据要覆盖全场景全周期,模型要针对小目标和俯视角做定制优化,工程端要用切片、分级这些策略补全性能和体验,最后还要有持续迭代的闭环机制。少了任何一环,都只能是实验室里的演示项目,没法真正用到田里。
农业AI落地,永远是场景优先,数据为王,工程补位。把基础的事情做扎实,哪怕用最基础的模型,也能做出真正有价值的落地效果。



