基于YOLOv9的水稻害虫小目标检测系统实践与边缘部署全解析
褐飞虱brown planthopper这类害虫农业上习惯叫它“稻虱”体长不过几毫米一旦暴发就是成片枯死的“虱烧”景象。以前我们巡田主要靠人工拿白瓷盘在稻丛中一拍数虫口数量水稻面积一大人根本数不过来等肉眼能明显看到枯黄基本已经晚了。所以去年我们尝试用YOLOv9搭建了一套水稻害虫定点识别系统类别列表里第一个就是brown-planthopper之后陆续加上白背飞虱、稻纵卷叶螟、二化螟等。这篇内容就是把这套系统的完整落地过程记录下来包括数据集怎么建、为什么选YOLOv9、训练调参时踩到的坑、模型怎么评估、最后怎么部署到田间的边缘设备。想用YOLOv9做小目标检测的朋友或者正在做农业信息化项目的开发者可以直接参考。1. 认清目标水稻害虫检测到底难在哪1.1 检测对象本身就反人类褐飞虱不是那种体型很大的虫子成虫体长也就三四毫米在图片上经常只有二十几个像素。它喜欢聚集在稻株基部被叶片挡住颜色又和水稻茎秆接近。更麻烦的是它的密度暴发期一丛稻上可以有几十上百头个体之间互相重叠人眼都很难数清。我们最初列出的检测类别就四个类别常见体型危害特点检测难度brown-planthopper褐飞虱3~5mm刺吸汁液成片枯死小目标、高密度、拟色white-backed planthopper白背飞虱2~4mm苗期危害明显小目标、高密度rice leaf roller稻纵卷叶螟蛾类翅展约15mm幼虫卷叶取食成虫翅面纹理易与背景混淆striped stem borer二化螟成虫约12mm蛀茎造成白穗样本少、活动隐蔽表格里最让人头疼的其实就是褐飞虱。它既小又多检测系统稍有漏检统计出来的虫量变化趋势就会失真。1.2 我们要的是“早期预警”不是简单分类这套系统不是做一个学术Demo而是要回答几个实际问题某个田块现在有没有害虫数量大概是多少比昨天是增还是减所以模型不能只输出“这张图里有飞虱”得给出位置框、类别和置信度让后端可以按时间维度去累计和预警。这也是为什么传统图像处理方法在这里走不通。我们用颜色阈值、边缘检测、HOG加SVM都试过一到自然光下全部失效害虫颜色和水稻茎叶太接近阴影、水珠、泥土都会变成误检来源。深度学习目标检测尤其是YOLO这类实时模型成为实际可用的突破口。2. 为什么是YOLOv9PGI和GELAN不是噱头2.1 从YOLOv8s换到YOLOv9c的动机最早我们用YOLOv8s做了一版跑起来很快褐飞虱的漏检率却不理想。后来对比了YOLOv9的开源实现在同样输入分辨率下YOLOv9c对小目标的召回有明显改善。注意这不是说YOLOv9全面碾压YOLOv8而是对我们这类“目标小、背景杂、密度高”的场景它的两个核心设计刚好打在痛点上。2.2 PGI可编程梯度信息通俗理解就是“备用输油管”YOLOv9论文里提出的PGIProgrammable Gradient Information核心解决的是深层网络训练时的信息丢失问题。神经网络反向传播时梯度要一层一层往回传网络越深浅层特征能拿到的有效梯度就越少。小目标的信息本来就弱传到浅层时可能已经没剩多少模型自然学不好。PGI的做法是引入一个辅助的可逆分支把完整的梯度信息保留下来再补给主分支。辅助分支只在训练时用推理时不参与所以不增加线上计算量。用大白话讲主分支是个上课记笔记经常记不全的学生PGI是那个用录音笔把老师所有话都录下来、课后再把重点讲给主分支听的同学。这个机制对水稻害虫特别重要。因为褐飞虱出现在画面里的特征大多集中在浅层细节上比如虫体轮廓、触角、翅膀纹理这些细节能不能在训练时被强化直接决定最终检测效果。2.3 GELAN结构把参数花在刀刃上GELAN是YOLOv9里采用的网络结构本质上是把跨层连接和高效计算模块组合起来在增加网络表达能力的同时控制计算量。相比之前常见的CSP结构GELAN在相同参数量下能拿到更好的精度对部署也友好。我们当时的选型对比如下模型相对体量特点我们的选择YOLOv9t轻量适合低算力设备备用方案YOLOv9c中等精度和速度折中最好主力模型YOLOv9e大模型精度上限高但部署成本大仅作对比最后训练主力放在YOLOv9c上原因很简单在边缘设备上要跑到实时帧率不能只盯着精度。YOLOv9e在测试集上AP高一些但换到低功耗板卡后速度掉得厉害现场用不起来。3. 数据集的命脉采集、清洗和标注决定模型上限3.1 田间图像怎么采集直接决定系统能不能用很多项目输在第一步拿公开数据集或者网上图片凑数训练出来一到田里就废。我们的做法是在试验田里定点采集覆盖三个关键维度角度、距离、光照。角度上要有俯拍、斜拍和贴近稻丛的特写。距离上至少包含两个尺度一种是监控摄像头视角的远景害虫只占几十像素一种是用长焦镜头贴近后的近景害虫占上百像素。光照上则分五个时间段清晨露水期、上午、正午、傍晚、夜间补光。实测下来正午高温时害虫会往稻丛底部躲图片里露头的很少傍晚和夜间才是活动高峰所以夜间数据反而要重点采集。如果你只是拿手机去田里随手拍大概率会得到一堆模糊、过曝、角度单一的照片。我们的建议是固定好采集设备比如把相机架在三脚架上对准稻丛基部每天定时拍一段视频再从视频中抽帧。这样获得的图片背景多样性足够害虫姿态也更真实。3.2 数据清洗别让脏数据浪费训练时间采集完原始素材后不能直接送去标注。我们先用脚本做了两轮筛选拉普拉斯方差低于阈值的模糊帧直接丢弃画面中明显没有稻株或田块的空镜头丢掉连续视频里几乎一样的相邻帧按时间间隔抽帧避免重复样本过多。这些处理虽然简单但能避免模型在重复的背景上过拟合。最后我们保留了大约三万多张有效图像其中大约六成含有目标。3.3 标注规则对密集小目标要提前定好规矩标注这一步是整个项目里最花时间、也最决定上限的部分。我们用的是开源标注工具类别名严格按配置文件来names: 0: brown-planthopper 1: white-backed-planthopper 2: rice-leaf-roller 3: striped-stem-borer对普通目标标注原则是框紧贴虫体边缘不为了迁就图像分辨率而故意放大。对褐飞虱这类密集目标我们定了几条硬性规定遮挡超过一半、人眼无法判断边界的个体不标高密度重叠时能拆分的尽量拆分实在分不清的整簇只标一个框并在后续检查中去掉这类样本宁可漏标也不要标一个包含“半只虫加半片叶子”的框。有人会问漏标不会影响训练吗实际上模棱两可的标注对模型的干扰远大于漏标。让模型学到一个边界混乱的正样本它会在推理时给出大量置信度虚高的错误框。3.4 数据增强针对小目标做“定向喂养”YOLO训练管线里本来就有马赛克增强、HSV扰动、随机翻转这些都要开。但对褐飞虱这种小目标常规增强作用有限最有效的是小目标复制粘贴从近景图里把虫体切出来经过随机缩放和旋转贴到其他稻田背景图上。这样等于变相增加了小目标在训练中的出现次数。一个小提醒复制粘贴时要注意尺度。把一只三毫米的虫放大成三十毫米再贴上去模型学到的还是错误的尺度概念。我们严格控制粘贴后的虫体尺寸和原图匹配宁可贴小一点。4. 训练复盘参数、观测和试错记录4.1 环境与训练命令训练用的机器就是一块24G显存的GPUPyTorch 2.xCUDA 11.8YOLOv9开源代码 clone 下来后按说明装依赖。数据集的配置长这样# rice_pest.yaml path: ./rice_pest_dataset train: images/train val: images/val names: 0: brown-planthopper 1: white-backed-planthopper 2: rice-leaf-roller 3: striped-stem-borer训练命令大致是python train.py \ --data rice_pest.yaml \ --cfg models/detect/yolov9-c.yaml \ --weights yolov9-c.pt \ --batch-size 16 \ --img-size 640 \ --epochs 300 \ --device 0注意尽可能用在COCO上预训练过的yolov9-c.pt作为起点。随机初始化在小目标数据集上训练前期收敛会慢很多。4.2 输入分辨率的取舍我们一开始图省事训练时用--img-size 512速度快了但褐飞虱的AP直接崩了。原因很清楚原本只有二三十像素的虫体再缩放到512分辨率连人眼都难辨认。后来老老实实改回640训练验证时用1280再测一遍小目标召回明显上涨。如果你显存不够优先减batch不要减分辨率。褐飞虱检测这种任务输入分辨率是比batch size更敏感的因素。4.3 训练过程中的观察点整个训练大约跑了300轮有几个值得记录的观察前30轮mAP涨得很慢尤其褐飞虱类别一直趴着不动不要慌预热阶段还没结束到150轮以后其他类别的AP基本稳定褐飞虱还在缓慢上升说明小目标类别需要更长的训练周期我们一度在200轮后出现验证AP震荡训练loss却一直降的典型过拟合信号。针对过拟合做法是增强里加上了随机擦除并把余弦退火调度打开收敛稳定了很多。4.4 类别不均衡的补救数据集里褐飞虱实例最多占七成以上二化螟最少可能只有几百个实例。最初的模型在二化螟上AP不到0.5。我们做了两件事一是给少样本类别的损失加权让模型“更在意”这些稀有类二是对二化螟的样本做适度重复采样。这里要克制不要无限制复制少样本图片否则模型会把那几张图背下来验证集上看不出来到实际场景就露馅。我们最终每个少样本类别只做三倍以内的重复。5. 评估指标拆开看mAP漂亮不等于现场好用5.1 别迷信单一mAP要盯住召回mAP50算是行业惯例但我们自己评估时更关注两个指标褐飞虱类别的AP50以及置信度调低后的召回率。原因前面说过这套系统用于早期预警漏一头迁入的褐飞虱可能比误报十次更严重。宁可让模型多报再由后端按“连续多帧报警”来过滤。我们用验证集跑了F1曲线按F1最大值选的置信度阈值实际部署时又调低了一点。这个细节很多人忽略训练代码里默认的置信度阈值通常是为了刷漂亮指标不是为你现场业务设计的。5.2 我们测试集上的实测数据以下数据仅代表我们的测试集不同场地、不同数据集会有明显差异但可以大致感受一下类别AP50主要错检/漏检原因brown-planthopper0.84若虫颜色浅贴在稻茎上难以辨认white-backed planthopper0.81体型小远景下特征不足rice leaf roller0.76翅面花纹被压缩后与叶片纹理混淆striped stem borer0.71样本少夜间活动数据不够总体mAP50在0.85上下。说实话单看这个数字还行但在真实视频里依然会见到漏检这正是为什么不能只看汇总指标。5.3 坏例分析带来的调整我们把错检和漏检图像分批拉出来看发现两个规律褐飞虱漏检集中在中午强光下稻叶反光导致虫体轮廓消失误检集中在背景里有水珠、稻粒和蜘蛛网上。针对反光增强时加重了亮度扰动和曝光扰动针对误检部署时在后端加了ROI区域排除稻田画面里只有稻丛区域参与检测田埂和天空直接屏蔽。这一改动让每小时误报数下降了一个数量级。6. 部署到田间的最后一步模型压缩与边缘端推理6.1 边缘设备选型模型最终要放在田间不可能拖一台服务器过去。我们的硬件方案是一块低功耗的Orin架构边缘板卡整体功耗控制在25W以内配普通监控摄像头和防水箱。摄像头装在稻丛上方约半米处斜向下45度对准稻株基部这样既能拍到褐飞虱出没的位置又避免直视天空导致过曝。如果你只是做验证树莓派加摄像头也能跑起来但帧率会很难看。褐飞虱检测需要至少15FPS才能实时预警建议还是用带CUDA支持的边缘设备。6.2 从PyTorch到ONNX再到TensorRT导出步骤不复杂命令大致是python export.py --weights best.pt --include onnx --img-size 640导出ONNX后再用TensorRT工具链构建推理引擎。我们对比了几种运行方式的实测参考值运行方式帧率参考相对mAP50损失服务器GPUPyTorch FP32约100基准边缘板卡PyTorch FP32约10几乎为0边缘板卡ONNX FP32约14几乎为0边缘板卡TensorRT FP16约30几乎为0边缘板卡TensorRT INT8约45约1%以内虽然TensorRT INT8帧率最高我们还是选了FP16。原因很简单INT8对褐飞虱这种弱纹理小目标的精度损失不稳定省出来的算力换来的收益抵不过误检漏检率上升带来的现场投诉。如果你在部署时需要追求极致性能建议先跑一遍自己的数据集对比不要照搬别人的经验。6.3 部署后的运行机制模型只是系统的一部分。我们把推理结果送入一个简单的计数模块按帧累计每个类别框的数量计算单位时间内出现的目标次数超过阈值就推送预警。由于单帧会有抖动误检还加了帧间投票连续三帧同一区域出现目标才确认报警。这个机制非常土但非常有效把模型的独立性误检大幅度滤掉了。后来甚至发现不用改模型光靠这个后端逻辑现场误报率就能从每小时多次降到每天一两次。7. 回看整个项目真正起作用的几个经验7.1 数据比模型更值钱尤其阴雨天数据项目跑通以后我们回头复盘发现最大的一次精度提升不是来自换模型而是来自补充了一批阴天和傍晚光照的数据。当时只加了大约三千张图褐飞虱类别AP直接涨了约4个点。原因是傍晚正是褐飞虱取食活动高峰期而原始数据这部分严重不足。7.2 输出虫情指数别让模型直接下防治结论检测系统的职责是“看到什么”不是“该怎么办”。我们把模型输出汇总成中长期的虫情指数再交给植保人员结合气象、作物生育期做判断。千万不要在界面上写“建议立即用药”这种结论模型没有能力理解田间综合因素贸然给结论只会让系统失去信任。7.3 建立误检漏检回流机制模型要持续迭代部署不是终点。我们每周抽一段现场视频把模型预测结果和人工复核结果做比对挑出错例补充到训练集里重训。三个版本迭代下来褐飞虱和稻纵卷叶螟的稳定性明显提升。这个“数据回流”过程比调任何超参数都重要。7.4 警惕物理极限画面里只有几个像素时什么模型都救不了最后说一个很直白的体会有很多用户以为把模型换大、把分辨率调高就能把所有虫都检测出来。但褐飞虱远景下只有六到八个像素时它已经不再是机器学习能解决的问题而是物理成像问题。现场要保证检测效果要么摄像头离稻丛更近要么用特写镜头要么配置灯光诱集装置把虫子引到固定区域再拍。设备机位设计到位后面所有环节都会轻松很多。如果让我重做一遍我会先把采集设备的机位想清楚而不是先把模型跑到50FPS。画面里的虫子只有八个像素时任何算法都救不回来把这个问题想透了YOLOv9也好其他模型也好才能真正在稻田里稳定工作。

相关新闻

FastAPI+PyTorch 实时推理 API 性能优化实战指南

FastAPI+PyTorch 实时推理 API 性能优化实战指南

把训练好的 PyTorch 模型塞进 HTTP API,是绝大多数算法工程师迟早要面对的事。我最早干这事的时候踩了无数坑:模型是能跑,但并发一上来延迟就飙到几秒,或者第一个请求直接把服务打挂。后来我把整套东西梳理成一条清晰的链路——Ce…

2026/10/19 12:30:18 阅读更多 →
DiskANN:大规模向量检索的磁盘索引方案解析与实践

DiskANN:大规模向量检索的磁盘索引方案解析与实践

1. 项目概述先说结论:DiskANN是一个专门解决“大规模向量检索内存放不下”问题的索引方案。这几年做向量检索的朋友应该都有同感——数据量一小,方案随便选,FAISS、HNSW、Milvus都能跑得挺好。但数据一旦到千万级、亿级,内存立刻变…

2026/10/19 12:30:18 阅读更多 →
嵌入式LCD/OLED取模工具原理与实战指南

嵌入式LCD/OLED取模工具原理与实战指南

简介:这是一款专为嵌入式开发人员设计的LCD/OLED字符与图像取模工具,面向单片机、STM32、Arduino等硬件开发者,解决在资源受限显示屏上高效生成可直接调用的点阵数据这一核心问题。工具支持ASCII字符自定义取模、BMP位图转单色/灰度数组&…

2026/10/19 12:25:43 阅读更多 →

最新新闻

两参数威布尔分布风速建模:MATLAB参数估计与拟合优度检验实战

两参数威布尔分布风速建模:MATLAB参数估计与拟合优度检验实战

简介:这份MATLAB小程序面向风能行业工程师、风电项目研究者及学习风速统计建模的学生,用于对风电场实测风速数据进行两参数威布尔分布拟合与参数估计。压缩包内共1个文件,为weibull1.m脚本,体积约436B,属于轻量级可直接…

2026/10/19 13:14:38 阅读更多 →
遥感影像与矢量点配准后像素坐标提取:从GeoTransform到GDAL实战

遥感影像与矢量点配准后像素坐标提取:从GeoTransform到GDAL实战

做遥感的人应该都遇到过这种事:手里有一幅影像,上面还有一批矢量点,可能是外业踏勘的采样点、精度验证用的检查点、或者深度学习样本里要用的目标中心点。现在要把这些点对应的像素行列号提出来,也就是“像素坐标”。很多人第一反…

2026/10/19 13:14:38 阅读更多 →
open-code-review:可审计、可编程的LLM代码审查CLI工具

open-code-review:可审计、可编程的LLM代码审查CLI工具

1. 这不是又一个“AI写代码”工具:open-code-review 的真实定位与设计哲学你搜“open-code-review”,大概率会撞上一堆带“CLI”“LLM”“Git”标签的零散讨论,甚至夹杂着“Codex CLI”“ZCode CLI”“Trae CLI”这类名字相似但目标迥异的项目…

2026/10/19 13:14:38 阅读更多 →
Java加密与SSL/TLS快速参考:核心原理与HTTPS实战指南

Java加密与SSL/TLS快速参考:核心原理与HTTPS实战指南

1. 内容整体设计与思路拆解 1.1 为什么需要一份“快速参考指南” 先聊点实际的。搞Java开发这几年,我见过太多同事在加密和SSL这块踩坑了——不是不会写代码,而是每次都要现查文档、翻博客、试半天才能凑出一段能跑的代码。尤其是碰到对接第三方系统、上…

2026/10/19 13:14:38 阅读更多 →
基于LLM的智能客服系统架构设计与排障实践

基于LLM的智能客服系统架构设计与排障实践

去年我主导了一个智能客服平台从零到一的设计与落地,整套系统基于LLM(大语言模型)搭建,上线后稳定运行了三个多月,扛住了一年中最大的活动流量,也把各种诡异问题从日志里一个个捞出来解决掉。这篇文章不是泛…

2026/10/19 13:14:38 阅读更多 →
开源SECS/GEM协议栈实战:从HSMS状态机到S6F11事件上报

开源SECS/GEM协议栈实战:从HSMS状态机到S6F11事件上报

简介:SECS(半导体设备通信标准)开源实现库,面向半导体设备自动化领域的开发者与研究人员,用于简化设备控制器与生产线工具之间的数据交换与通信开发。资源包共11个文件,约39KB,以test测试脚本、…

2026/10/19 13:13:37 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →