农业害虫图像识别数据集构建实战:从田间采集到模型训练
植保站的老专家在田里一蹲一上午拿白瓷盘拍打稻丛数飞虱的日子正在被慢慢替换掉。现在做植物保护信息化绕不开一个基础问题算法能不能认得田里的虫子。市面上公开的通用目标检测数据集一大把但真正针对水稻、小麦、玉米、大豆这些主粮作物的农业害虫计算机视觉数据集却很零散要么类名乱要么只有单一视角的标本图落到真实田块里根本不好用。所以我一直觉得整理一套覆盖黏虫、豆芫菁、红蜘蛛、稻瘿蚊、稻纵卷叶螟、稻飞虱、稻水象甲、小麦皮蓟马、白背飞虱、二化螟这10类常见害虫的图像识别数据集是智慧农业落地里性价比最高的一件事。这篇就把我们团队从数据规划、田间采集、标注质检到模型训练的完整经验捋一遍给准备自己搞害虫数据集的朋友做个参考。1. 项目整体设计与数据集定位1.1 为什么选水稻、小麦、玉米、大豆这四类作物先聊一个很现实的问题害虫数据集为什么难做。不是没有数据而是公开数据大多来自标本馆或者实验室饲养的种群拍出来背景干净、姿态单一真到了田间背景是泥水、叶片、杂草、蜘蛛网混在一起的虫体还常常只有几个像素。我们当时定项目范围就直接锁定水稻、小麦、玉米、大豆这四类大宗作物。原因是这四类作物种植面积大、害虫种类多、监测需求最迫切而且田间场景差异明显水稻田有水层反光旱地作物有土壤背景干扰正好能逼着模型学到更鲁棒的特征。10种害虫的选型也有讲究。清单里的二化螟、稻飞虱、白背飞虱、稻纵卷叶螟、稻瘿蚊、稻水象甲几乎覆盖了水稻从苗期到穗期的核心虫害小麦皮蓟马对应麦类穗部害虫黏虫是典型的杂食性暴食害虫小麦、玉米、水稻都能造灾豆芫菁和红蜘蛛则把大豆、玉米常发的食叶类、刺吸类害虫补上了。从分类学角度看这批害虫横跨鳞翅目、同翅目、双翅目、鞘翅目、缨翅目、蜱螨目形态差异梯度拉得很大很适合用来验证一个模型在不同体型尺度、不同颜色纹理、不同环境光照下的泛化能力。1.2 数据集的双重任务定位做图像识别数据集第一步要明确模型将来怎么用。是只想判断“这片田有没有稻飞虱”还是想明确“图里每一只稻飞虱在哪里、有多少头”这两种需求对应完全不同的标注策略。我们最终把数据集按目标检测格式为主来组织同时保留分类标签。原因很直接田间的实际监测场景几乎不会给你单目标特写更多是拍到一丛稻株上混着稻飞虱、蜘蛛、叶蝉模型如果能输出每个目标的位置和类别后端不管是接计数统计、诱虫灯自动识别还是无人机巡田的告警都能直接衔接。分类标签则作为辅助用来做粗筛或训练分类backbone。目标检测主干格式选的是YOLO系列通用的txt标注同时导出一份COCO格式方便切到Faster R-CNN、RT-DETR这类两阶段模型时直接加载。一开始不要只锁一种格式后面换模型、换框架都会后悔。1.3 数据规模和类间平衡的预期设计数据规模不是拍脑袋定的。我们按每类害虫至少2000张有效图像、每张图目标数1到20个来规划像红蜘蛛这类体型极小的单张图目标数可能到几十上百标注策略还要单独设计。类间平衡上预期设计是常见且容易采集的稻飞虱、二化螟、稻纵卷叶螟尽量做到2500张以上像稻瘿蚊这种区域性强、田间暴发需要特定条件的前期可能只有几百张那就通过灯诱、人工饲养补充标准姿态图再用生成式增强补样本。真实数据的量级不用追求完美均衡但至少要保证每个类别的轮廓、龄期、姿态有足够变化否则模型只是记住了某几张图。2. 十种虫害识别特征与标注要点2.1 先把10类害虫的关键特征装进表格做标注规则时我给标注员发过一张速查表这比让他们自己翻图鉴有效率得多。这里直接放整理版标签名对应害虫主要作物危害部位图像识别关键特征Mythimna_separata黏虫小麦、玉米、水稻叶片、穗部老熟幼虫体色黑褐或绿褐头部有“八”字形黑纹背线、亚背线明显成虫前翅有黑褐斑纹Epicauta_gorhami豆芫菁大豆、花生等豆科叶片成虫鞘翅黑色带金属光泽头部红褐色体长约11到18毫米取食时群集性明显Tetranychus_sp红蜘蛛玉米、大豆、棉花等叶片背面成螨砖红色或锈红色体型仅0.3到0.5毫米叶片背面有细丝网受害叶面失绿发白Orseolia_oryzae稻瘿蚊水稻心叶、茎秆幼虫蛆状、乳白色侵蛀后形成“标葱”状卷缩心叶成虫似小型蚊体长3到5毫米Cnaphalocrocis_medinalis稻纵卷叶螟水稻叶片幼虫会将叶片纵卷成苞3龄前啃食叶肉留下白色条斑成虫前翅有3条黑褐色横纹Nilaparvata_lugens稻飞虱水稻稻株基部长翅型与短翅型并存体色黄褐至黑褐后足胫节末端有显著扁距常聚集在稻丛基部Lissorhoptrus_oryzophilus稻水象甲水稻根部、叶片成虫体长约3毫米喙长且向下弯前胸背板和鞘翅密布鳞片形成不规则白斑幼虫无足型蛆状Haplothrips_tritici小麦皮蓟马小麦穗部成虫黑褐色体长仅1.3到1.8毫米翅缘有长缨毛多在麦穗颖壳内为害Sogatella_furcifera白背飞虱水稻稻株中上部体色淡白黄褐中胸背板有“v”字形黑褐色斑翅斑不如褐飞虱明显后足胫节有距Chilo_suppressalis二化螟水稻茎秆、心叶幼虫淡褐色体背有5条紫褐色纵线蛀茎造成枯心、白穗成虫前翅黄褐有黑斑后翅白色这张表是标注的“最小公共知识库”。重点在于虫害识别不能只靠虫体本身危害状是重要的辅助特征。比如稻瘿蚊的“标葱”比成虫更容易在田间被拍到稻纵卷叶螟的卷苞和白条斑在图像里非常显眼。我建议数据采集时不要只拍虫体特写要把危害状一起拍进去同一图像里双标签关联模型学到的不只是虫子长什么样还有它造成的损失长什么样。2.2 水稻害虫组的易混类型水稻上这6类害虫最容易被搞混的是稻飞虱和白背飞虱。分类学上它们是近缘种体型接近田间经常混发低龄若虫几乎是同一个配色。实际操作时我们强制要求标注员在框选这类目标时至少能看到后足胫节末端的小距或中胸背板的斑纹如果清晰度不够看清楚关键特征宁可标记为“飞虱类”统一类也不要硬标到种一级否则训练集内部标签噪声比模型算法误差还要致命。稻纵卷叶螟和二化螟虽然都是鳞翅目幼虫但一个在叶片表面活动、一个蛀茎所以采集到的图像场景差异很大。不过要注意的是老熟二化螟幼虫从茎秆里钻出来准备化蛹时也会爬到叶片上此时它和黏虫的低龄幼虫容易混淆。区分关键看体背纵线数量二化螟是5条紫褐色纵线黏虫则是有背线、亚背线、气门线的复杂层次。标注规则里写清楚“看纵线不看体色”因为体色受寄主和龄期影响太大完全不可靠。稻水象甲最显著的特征是喙和鞘翅上的鳞片斑。它的卵和幼虫都在水稻根部田间拍不到能拍到的几乎都是成虫。这提醒我们数据集的类目定义最好按“图像可识别阶段”来裁剪如果一个物种的可识别形态只有成虫那就老老实实只收成虫图像不要硬凑若虫或卵的图来充数。2.3 旱地害虫组的特殊处理旱地组里红蜘蛛和小麦皮蓟马是小目标中的小目标。红蜘蛛成螨不到0.5毫米普通手机镜头根本拍不清个体但它在叶片背面吐丝结网形成的群落一眼就能看出来。所以红蜘蛛这类目标我们的标注单位从“单个个体”改成“为害群落”框选的是螨虫聚集区域类别语义是“红蜘蛛为害区”。这样做工程上是合理的因为植保上的防治决策关注的是“有没有发生、发生面积多大”而不是精确统计螨虫头数。不过还是要单独保留一小批单螨微距图用于模型学习精细特征。小麦皮蓟马比红蜘蛛稍大但成虫也只有1.5毫米左右而且躲在麦穗颖壳里。实际采集时与其拍活的田间个体不如用白瓷盘拍打麦穗让蓟马掉落在白色背景上拍特写。这一类图像作为模型的特征学习很重要但田间部署时大概率拍不到清晰个体所以还要补充一批“麦穗受害状”图像也就是麦粒灌浆不良、颖壳发黑的近景照片作为辅助类目。豆芫菁属于最好认的一类成虫体型大、鞘翅漆黑带金属光泽、头部红褐色和大豆叶片形成强烈反差模型几乎不会认错。难点在于它只在大豆开花结荚期大量出现其他季节采不到。黏虫也是同样的季节性问题暴食期幼虫数量大但发蛾期只能在灯下拍到成虫。对这类时令性害虫不能只依赖自然采集需要配合人工饲养补充不同龄期的图像。3. 数据采集与标注实操方法论3.1 田间采集设备和拍摄规范采集设备没有标准答案取决于你准备投入多少人力。我们实际用了三种方案混采第一种是手机微距方案用于日常巡田和早期发现。拍摄时把手机相机切到微距模式距离目标控制在5到10厘米自然光条件下拍稻飞虱、蚜虫这类中小型害虫效果不错。缺点是景深太浅焦平面稍微偏一点虫体就糊了所以拍摄时要尽量找叶片平面的角度拍避免斜对焦。第二种是单反加微距镜头方案用100mm微距镜头配合环形闪光灯专门拍红蜘蛛、蓟马这种微小个体。环形闪光灯能均匀照亮目标减少手持抖动但要注意压低闪光强度否则叶片反光会把虫体细节吃掉。第三种是体视显微镜加相机转接方案主要用来拍饲养个体和标本图像最清晰但背景单一只能作为补充。拍摄规范方面我总结了几条硬性要求。一是一张图尽量只保留一个生态位比如拍稻丛基部飞虱时不要在同一张图里把上部卷叶螟也框进来除非目标确实重叠否则会让模型学到的上下文特征互相干扰。二是背景要多样化至少包含叶片正面、背面、茎秆、水面、泥土、白色背景板、黄色粘虫板七类背景。三是拍摄时优先选多云天或早晨傍晚避免正午强光造成的高光过曝和阴影死黑。四是每片田块连续拍摄不要超过一定数量同一株作物不同角度拍的图像要在后处理时去重。3.2 灯诱、黄盘和人工摆拍的补充路径只靠田间肉眼寻找很多害虫根本凑不齐数量尤其夜蛾科和小型缨翅目。所以采集计划里必须包含诱集手段。灯诱是最常用的方式在田边架起诱虫灯一晚上能收到几十上百头黏虫成虫、二化螟成虫、稻飞虱长翅型。灯诱样本的问题是姿态偏“展翅标本”和田间活体姿态有差异需要把部分个体转移到透明饲养盒里拍侧视和背视活体图。黄盘和水盘主要诱集蓟马、飞虱、叶蝉盘里加一点表面活性剂破坏水的表面张力否则虫体浮在水面会变形图像真实度差。人工摆拍也是补姿态多样性最直接的办法。抓到的虫子放在干净的培养皿、白卡板或湿润的叶片上摆拍每头从背视、侧视、前视三个角度各拍几张。如果是低龄幼虫移动速度快可以先放进冰箱冷藏室低温处理几分钟让它活动减缓再拿出来拍。这套方法比野外随缘拍摄的效率高很多但拍出来的背景偏人工所以比例要控制在全数据集的30%以内避免模型过度依赖简单背景。3.3 图像清洗与版权隐私处理收图回来不是直接进标注流程的。我让实习生先过一轮清洗规则很简单模糊图、过曝图、目标占比小于图像面积1%的图、同一场景连拍超过3张的图、以及目标被遮挡超过一半的图全部进回收站。清洗完的照片统一重命名命名规则建议是“作物_害虫名_采集日期_地块编号_序号”例如rice_nilaparvata_20250712_p03_001.jpg。这套命名在下游能帮你自动生成数据集配置文件调试时定位坏图也方便。如果数据来源包含他人拍摄的图片合规问题必须提前处理。我们在项目里全部使用自有采集和授权数据不采用任何爬虫批量抓来的图片避免版权和肖像权风险。图像涉及的农户地块、地理坐标信息在发布前要脱敏只保留到产区等级。这不是保守是数据集能公开复用的前提。3.4 标注工具、标注规则与质检流程标注工具首轮我们用CVAT标注导出YOLO格式再用Roboflow做辅助预标注和增强。个人项目也可以用开源的labelImg但多人协作时最好还是上CVAT这类在线工具任务分配和审核记录都清晰。标注规则要白纸黑字写清楚否则每个标注员对“框多大算一个完整目标”的理解都不一样。我们定的规则是完整可见的虫体框紧贴目标最小外接矩形群体目标如飞虱若虫密集分布时每个独立个体只要边缘可分辨就必须单独框无法分辨的聚集块按“簇”标注并加类别后缀_cluster被遮挡超过一半但类别确定的目标不标注成虫和幼虫形态差异大的类别像黏虫、二化螟、稻纵卷叶螟用类别后缀_adult、_larva区分还是合并成一个大类要提前决定。我们内部最终决定合并为大类不做龄期细分。原因是幼苗期和低龄幼虫的类间差异远大于类内差异硬切子类会把数据量稀释模型反而学不好。模型先学会“认得出是二化螟”再去解决“这个二化螟几龄”的问题交给下游的尺寸估计算法。质检流程采用双人交叉复核。第一个人标完第二个人抽检20%重点看错框、漏框、边界框是否贴合。抽检合格率低于95%的批次整批打回重标。腰这一环节最容易被压缩但我强调一下脏标注对目标检测模型精度的影响比模型结构选型的影响大得多。宁可用5000张高质量标注也不要两万张粗糙框。3.5 数据划分要考虑“不漏题”划分train/val/test时很多新手直接随机切分结果同一株作物在不同角度拍的几张图一张在训练集一张在测试集模型等于提前见过答案。正确做法是按采集事件划分具体来说是以“田块编号日期”作为分组单位同一个分组内的图像要么全在训练集要么全在验证集/测试集绝不允许跨组混合。跨地块、跨季节的泛化才是真正有效的评测。比例上按7:2:1还是6:2:2看数据量但建议测试集尽量选不同产区、不同光照条件下的图像模拟真实部署环境。4. 模型训练与评估跑通要点4.1 目录组织与配置文件数据集落到磁盘上的组织方式建议采用这种结构dataset/ ├── train/ │ ├── images/ │ └── labels/ ├── val/ │ ├── images/ │ └── labels/ ├── test/ │ ├── images/ │ └── labels/ ├── data.yaml └── stats.txttrain、val、test三层目录是YOLO系列的标准约定。data.yaml内容示例path: /path/to/dataset train: train/images val: val/images test: test/images nc: 10 names: 0: Mythimna_separata 1: Epicauta_gorhami 2: Tetranychus_sp 3: Orseolia_oryzae 4: Cnaphalocrocis_medinalis 5: Nilaparvata_lugens 6: Lissorhoptrus_oryzophilus 7: Haplothrips_tritici 8: Sogatella_furcifera 9: Chilo_suppressalis类名的顺序一旦定了就不要改因为模型输出的索引和权重文件是绑定的。我最开始调试时调整过两次类名顺序结果测试脚本里类别映射全乱了花了一个下午排查纯属低效踩坑。建议在stats.txt里存一份类别统计每类图像数、目标数、平均目标面积占比每次更新数据集后跑一遍统计能避免很多排查成本。4.2 模型选型与训练参数目标检测我们优先跑YOLOv8s和YOLOv8m作为基线分类辅助模型用EfficientNet-B3。为什么不用更重的YOLOv8l/x因为农业监测端侧设备通常是Jetson、树莓派或者低功耗工控机模型权重超过100MB部署帧率很难看。YOLOv8s在640分辨率下参数量适中mAP50在中等规模数据集上往往已经够用先跑通基线再谈优化。如果后续要把航拍图像、大田全景接进来可以尝试RT-DETR或DINO这类端到端检测器对重叠目标和小目标的处理更友好但推理速度会慢一截。训练超参我直接给一组实测可用的起点值yolo train \ datadata.yaml \ modelyolov8s.pt \ imgsz640 \ epochs200 \ batch16 \ lr00.01 \ optimizerSGD \ augmenttrue \ mosaic0.5 \ patience30mosaic增强不要开满农业害虫图像里小目标很多mosaic把目标缩得太小对学习不利0.5的概率是平衡点。输入分辨率方面红蜘蛛和小麦皮蓟马这类小目标建议训练时用960甚至1280推理时再按部署设备取舍。增强策略里HSV扰动要适度因为害虫体色是分类重要特征色相泛化太狠可能把“红蜘蛛”的红色学没。用预训练权重从COCO迁移过来效果会好很多直接从随机初始化训练农业数据集前期收敛极慢且容易过拟合到背景纹理除非你有充足的大规模预训练数据否则别省这一步。4.3 评估指标怎么看不要只盯着一张mAP表就下结论。农业害虫数据集有几个特殊评估视角。第一个是per-class的AP看哪些类拖后腿。我们第一版模型稻瘿蚊AP只有0.42其他类都在0.8以上后来发现是“标葱”受害状图像没进训练集模型只会认成虫不认识危害状。补充标注后AP拉到0.75。第二个是small/medium/large目标分组下的AP红蜘蛛和蓟马基本都是small目标如果map_small明显偏低优先考虑提高输入分辨率或者切图推理。第三个是混淆矩阵重点看稻飞虱和白背飞虱的交叉误判率只要这个交叉率超过10%就要回头检查数据标注质量而不是急着调模型。评估脚本里也建议输出每张测试图的置信度分布。置信度普遍很低但预测正确说明训练域和目标域差异大需要补充更多现场风格数据置信度很高但预测错误说明存在标注错误或特征学习有偏要看热力图分析模型到底在看哪里。4.4 部署前的模型轻量化训练指标达标只算完成一半另一半是能不能在目标硬件上跑起来。我们常用的轻量化操作包括转TensorRT FP16一般能获得2到3倍加速输入分辨率从1280降到960或640类别置信度阈值从默认0.25调到0.35减少低置信噪声用NMS的max_det参数限制单图最大输出目标数避免红蜘蛛密集图上输出几百个框把后端口拖垮。还有一个隐蔽的技巧是给模型加一个后处理过滤规则同一图像区域同时检出害虫和蜘蛛时若面积重叠超过50%保留害虫目标因为捕食性蜘蛛不是防治对象。5. 常见问题与排查实录5.1 类不均衡怎么处理很多团队会在这上面栽跟头。稻飞虱、白背飞虱好采集一晚上灯诱就能收到上千头数据量轻松冲上3000。稻瘿蚊和稻水象甲是区域害虫不是每个产区都有一个季度能收到300张就谢天谢地。直接用原始分布训练模型会把高频类学得极好低频类几乎放弃。我们的处理分三步第一步对少数类过采样复制图像时配合轻度仿射变换不要原样重复否则模型容易死记硬背第二步引入合成数据用少类害虫的纯背景图像做拼贴这属于最朴素的mixup方法效果已经不错第三步如果某类实在凑不够300张看看是否要合并到上一级类目。稻瘿蚊美洲亚种和亚洲亚种在图像上几乎不可分强行区分只会增加标注噪音。5.2 相似种混淆的实战解法稻飞虱和白背飞虱的混淆是这类数据集的标准难题。我们试过三种方案第一种是加细粒度分类头检测框内再过一个分类分支效果提升有限但推理成本高第二种是数据层面专门挑两种飞虱混发的图像让模型见过足够多“同框对比”的例子这个操作是模型学出判别特征的关键第三种是干脆合并把检测任务定义为“飞虱类”下端的密度计数和种类鉴别交给更高倍镜头设备去做。最终选了第二和第三的组合检测阶段输出“飞虱类”同时用分类模型对高分辨率裁切缩略图做种级识别。这样既不损失生态信息又绕开了小目标分类难的问题。5.3 小目标检测失效红蜘蛛、小麦皮蓟马在田间图里的目标尺寸经常只有10到20像素YOLO在这类目标上的召回率惨不忍睹。试过把整图切成重叠块推理吗这是最有效的手段。把1024的图像切成4个640带overlap的图块分别推理再合并小目标漏检明显下降。代价是推理时间变大但对离线分析场景完全可接受。训练阶段也可以给模型更多“小目标参与度”方法之一是把输入分辨率提到1280代价是显存占用变大3090级别显卡才能舒服跑大batch。另一种思路是把红蜘蛛这样的类别标注换成区域标注前面提过的“群落框”就是妥协方案牺牲粒度换可用性。5.4 季节和地域漂移问题夏天拍的稻飞虱图像模型到了秋季低温环境下识别率会下降因为虫体颜色偏深、翅型比例变化、背景秸秆颜色完全不同。农业昆虫的物候变化本来就大同一物种在不同寄主、不同温度下的体色差异可以超过种间差异。应对办法是在数据采集计划里就规定跨三个以上产区、跨两个以上生长季节宁可单季数据量少一点也不要只集中在9月份的晴好天气里猛拍。模型层可以做风格随机化增强但根本解法还是数据多样性和真实部署环境的对齐。5.5 标注不一致和跨员复核问题标注员盯久了屏幕会产生视觉疲劳对“边界框要不要包含触角”“翅稍微张开的目标算不算完整”这类问题的标准会漂移。我们设计了一个最低成本控制方案每天标注任务完成后管理员随机抽20张已标图放在团队共享频道里让大家盲评不讨论具体是谁标的。一旦某类标签的框尺寸分布出现明显双峰基本就是有个人重标了一批不同标准。这种偏差在训练集里形成内噪声模型学出来的框会偏大或偏小部署时再做NMS合并特别容易出错。5.6 负样本和背景类的比例纯害虫目标检测模型很容易把泥土块、水滴反光、白色塑料碎片错认成稻飞虱因为训练集里没有“不是虫”的负样本约束。我们单设了一个no_insect标签专门收集田间的背景干扰物图像每类害虫样本量的10%起步。加了10%到20%的负样本后田间误报率肉眼可见下降。但负样本不要用纯空白图那种图没有任何上下文信息模型学不到真正应该拒绝的目标反而浪费训练容量。要选那种“很像虫但实际不是虫”的干扰场景比如稻飞虱若虫蜕下的皮、水滴反光、枯叶边缘这才是高质量负样本。这套数据集从立项到现在迭代了三轮我最大的感受是农业害虫数据集真正难的不是模型而是对田间生态的理解和把这种理解转译成可靠的标注语义。红蜘蛛到底标单只还是标群落飞虱要不要分到种二化螟幼虫要不要分龄期这些问题没有标准答案全看你的下游任务需要什么粒度。我建议每一个开始做这个方向的人都先从自己的应用场景倒推数据集设计而不是先抄别的数据集的结构。如果想在这个基础上继续扩展下一步比较值得做的是把同株作物的多种虫害共现关系建模进去以及把田间诱虫灯的视频流识别、定时抓拍和气象数据联动起来让数据集从一个静态资源变成一个可持续更新的监测闭环。最后再分享一个小技巧所有标注完的图像记得保留一份未压缩原图任何图像增强、压缩转码都应该发生在副本上。原始图像是数据集最不可再生的资产很多时候模型表现不好回头排查才发现当初为了省空间把图压得太狠高清细节早就没了。这一步放之四海而皆准做农业数据尤其如此。