资讯动态

柑橘叶片病害识别实战:自建数据集与YOLOv8训练全流程

发布时间:2026/9/11 2:35:47 来源:尧图企业网站定制
说个扎心的事实模型能不能落地九成看数据像不像真实场景。柑橘叶片病害识别这事网上公开数据集一抓一大把但真拿去果园里拍一圈精度立马掉下来。原因很简单——公开数据大多是实验站里拍的“标准病斑”背景干净、光线均匀跟农户手机里那张背光、带泥土、还有露珠反光的图完全是两个世界。所以这次我做了个项目自己从头搞一套柑橘叶片病害数据集锁定5类高发病害——黄龙病、溃疡病、疮痂病、炭疽病、黑斑病从拍摄规范到标注标准全部自己做再基于YOLOv8跑通训练和验证。这篇文章把整个过程中踩过的坑、验证过的参数、以及为什么这样设计数据集的思路全部写出来。想做农业AI、目标检测、或者纯粹好奇数据集怎么“喂”出好模型的朋友这篇能帮你少走很多弯路。1. 项目定位与数据构建思路为什么死磕这5类病害1.1 柑橘叶片病害识别的真实痛点柑橘是全球第一大水果作物叶片病害直接关乎产量和果品质量。但现实是能准确诊断病害的农技专家数量非常有限一个镇可能都摊不上一个更多时候靠的是农资店老板的经验判断。手机拍照识别的需求因此非常刚——农户对着病叶拍一张几秒钟内知道“是什么病、用什么药”这个场景一旦跑通价值是实打实的。但真正做过农业AI的人都知道这个场景比想象中难。难点不在模型结构而在数据本身病害形态在田间受品种、树龄、光照、湿度影响极大病害之间还存在相似症状加上手机拍摄角度、距离、清晰度参差不齐任何一个变量都会让模型崩掉。业界有一句话叫“模型决定上限数据决定下限”在农业图像识别里体现得淋漓尽致。所以这个项目的核心思路不是“跑通一个demo”而是从数据源头开始较真——既然公开数据集无法满足田间复杂场景那就自己建一套标准明确、场景覆盖足够广的柑橘叶片病害数据集再去训练和验证模型看看到底能把识别精度推到什么水平。1.2 5类病害的选型逻辑选哪几类病害决定了这个数据集的实用价值。我最终锁定的5类是柑橘产区最常见、危害最大、防治需求最迫切的叶片病害病害名称病原类型典型叶片症状发生特点柑橘黄龙病细菌韧皮部杆菌斑驳状黄化黄绿相间不对称叶脉黄化叶片硬脆毁灭性病害木虱传播目前无有效治疗手段柑橘溃疡病细菌黄单胞杆菌正反面近圆形病斑周围黄色晕圈木栓化隆起中央凹陷呈火山口状风雨传播高温高湿流行嫩梢嫩叶受害重柑橘疮痂病真菌痂囊腔菌病斑木栓化突起、粗糙叶片扭曲畸形黄褐色较小春雨多时严重主要危害嫩叶、幼果柑橘炭疽病真菌胶孢炭疽菌叶斑型边缘深褐色、中央灰白色有轮纹状小黑点易落叶弱寄生树势弱时爆发全年均可发生柑橘黑斑病真菌柑橘球座菌病斑圆形黑褐色硬质突起表面粗糙周围有黄色晕圈果实和叶片均受害老叶更常见选这5类有几个层面的考虑。一是发病率覆盖这5种病害基本覆盖了从嫩梢期到成熟期、从细菌到真菌的主要类型对农户来说是最常遇到的“疑难杂症”。二是形态差异足够丰富黄龙病的黄化斑驳、溃疡病的火山口状病斑、疮痂病的木栓化凸起、炭疽病的轮纹凹陷、黑斑病的黑色硬质斑点形态差异大类别之间有区分度模型学起来效率高也能避免因为类别过相似导致的混乱。三是防治策略完全不同黄龙病要砍树防木虱溃疡病要铜制剂疮痂病和炭疽病靠杀菌剂识别错误意味着防治方向彻底跑偏。所以这个“5类”是经过调查得出的不是随意拼凑。1.3 数据来源取舍公开数据集、网络图片还是实地拍摄定完类别接下来就是数据来源。我当时调研了几条路各有各的坑。第一优先考虑的是公开数据集毕竟省事。但是搜了一圈发现柑橘叶片病害的公开数据集非常少常见的大多是番茄、苹果、葡萄而且已有的柑橘数据集多来自实验站照片背景干净、拍摄规范一到实际果园就水土不服。直接拿公开数据集训练模型的泛化能力根本扛不住真实场景。第二是网络图片爬取。这个方法的问题是版权不清晰而且网上图片质量参差不齐标注成本极高。同一张图片可能被多个网站转载还容易爬进重复图清理起来非常费劲。我试过一版光去重就花了两天最后质量还是不满意。最终我选的是第三条路——实地拍摄配合专家复核。联系了几家柑橘种植基地在果园里用手机和相机分别拍摄覆盖晴天、阴天、雨后、背光、顺光不同条件。这个方法最笨但最靠谱。数据集的构建本来就没什么捷径采集阶段多花的时间在训练阶段都能省回来。2. 数据采集与质量规范一张好样本胜过十张废片2.1 拍摄规范让模型看到“田间真实”而不是“影棚摆拍”数据采集最核心的原则是让模型看到实际使用时的样子。模型最终吃进去的是农户手机拍的图那训练数据的拍摄方式就必须贴近这个场景。我定了几个基本规范拍摄设备上手机和相机都来手机占比六成以上确保图像分辨率、噪点水平贴合真实用户拍摄距离上从贴近叶面特写病斑特征清晰到整枝远景病斑小但真实都要有这样模型才能在“近看细节远看位置”两个尺度上都学得会角度上要有正面、侧面、斜上方多角度不能只拍正对着的叶片光照上晴天强光、阴天散射光、雨后湿润状态、甚至背光阴影都要覆盖。这里要特别提醒一下湿度场景。果园里真正拍病害时叶片上经常带露水或者刚下过雨水珠反光会明显改变病斑的视觉特征。如果训练数据全是干燥叶片模型在雨后场景下大概率误判。所以采集时我特意安排了一部分“带水珠”的样本这个细节后来在验证集上起到了重要作用。数量规划上每类目标1000张以上5类合计至少5000张原始图。实际采集过程中会有一定比例废片失焦、过曝、运动模糊按15%的损耗预留余量。最终清洗后每类保留900-1000张总量在4800张左右。这个量级对目标检测来说不算大但配合后面的数据增强和预训练权重已经够用了。2.2 图像清洗与去重宁愿少而精不要多而杂图像清洗这个环节很多人不重视但它的重要性不亚于拍摄。我的清洗标准分三层第一层是技术问题排除。模糊、过曝、欠曝、严重反光的照片直接剔除。手机拍的图容易有轻微运动模糊肉眼看不出来但模型会学到错误特征这类图数量一多精度就被拉低了。我当时的做法是把图放大到100%逐张过虽然费眼睛但值得。第二层是重复度控制。同一病叶拍多张很正常但相似度太高的图必须去重。如果训练集和验证集里出现同一片叶子的不同角度照片那验证集就“泄题”了精度虚高部署到真实场景立刻现原形。我用感知哈希算法做了初步去重再把阈值设得比较高宁可少留一些也不能让相似图混进不同集。第三层是内容审核。有些叶片同时有溃疡病和炭疽病这类图不但不清洗掉反而要专门保留因为真实场景中复合感染非常常见。标注时把所有可见病斑全部标出来不回避重叠。2.3 标注方案边界框粒度、工具选型与质量审核标注是数据集构建中最耗时的一环也是决定模型精度的最直接因素。我采用的是“每个独立病斑一个框”的标注策略只要病斑在图像中能被辨认就单独画一个框宁可框小一点把病斑包裹完整也不要留出大量背景。框太大会让模型学到背景特征导致误检率上升框太小则丢失病斑边缘信息影响定位精度。重叠病斑的处理要特别注意。如果两个病斑挨得很近甚至部分重叠我不会把它们合并成一个大框而是各自标注允许框之间有交叠。这样做模型学到的特征分布更接近于真实形态。但这个操作对标注者的要求很高画框的贴合度直接影响训练效果。标注工具我用过好几个最终推荐这三款工具优点不足适用场景LabelImg经典、免费、离线、安装简单界面老旧无自动标注个人小规模数据X-AnyLabeling支持分割模型辅助标注效率高配置稍复杂中大规模框标注CVAT支持多人协作、标签管理完善需要部署服务端团队协作标注我这次用的是X-AnyLabeling理由很简单它的半自动标注功能能大幅提升效率。先手工标注几个典型样本用它内置的模型生成候选框再人工修正水平和位置。实测下来能节省将近一半的时间。质量审核环节我做了“双人复核”机制一个人标注后另一个人不看第一人的标注结果独立再标一遍然后对比两个版本分歧大的图重新讨论确认。这样虽然多花时间但能显著减少边界框偏移、漏标、标签错标这三类问题。农业病害数据集最怕的就是标签错误——黄龙病和缺素症很相似如果错标几张图混进数据集模型就会学到错误规律而且这种错误很难排查。标注完成后的目录组织我按照YOLO通用格式来存后续接入训练框架非常方便。3. 数据集结构设计与模型训练实践3.1 目录结构、命名规范与训练/验证集划分数据集的组织方式直接决定了后续训练的顺畅程度。我当时按YOLO格式组织的目录结构如下citrus_leaf_disease/ # 根目录 ├── images/ │ ├── train/ # 训练集图片 │ │ ├── HLB_001.jpg # 黄龙病样本 │ │ ├── canker_002.jpg # 溃疡病样本 │ │ └── ... │ └── val/ # 验证集图片 │ ├── HLB_010.jpg │ └── ... ├── labels/ │ ├── train/ # 与图片一一对应的txt标注 │ │ ├── HLB_001.txt │ │ ├── canker_002.txt │ │ └── ... │ └── val/ │ ├── HLB_010.txt │ └── ... └── citrus_disease.yaml # YOLO格式的配置文件每个txt文件里的每一行代表一个目标框格式为“class_id x_center y_center width height”坐标经过归一化取值范围0到1。这个格式是YOLO系列的标准输入Ultralytics框架直接读不用额外转换。类别的ID分配很重要我按字母顺序固定下来避免后面改动导致标签错乱# citrus_disease.yaml path: /path/to/citrus_leaf_disease train: images/train val: images/val names: 0: canker # 溃疡病 1: anthracnose # 炭疽病 2: scab # 疮痂病 3: HLB # 黄龙病 4: black_spot # 黑斑病训练集和验证集的划分走的是“按图片分、不按叶片分”的原则。也就是说同一片叶子的多张照片必须全部归入同一个集合绝对不能一半在训练集一半在验证集。否则验证集就等于是“开卷考试”评测出来的精度水分很大。实际划分比例是8:2总共4800张图片训练集约3800张验证集约1000张。3.2 数据增强补足样本多样性但别把病斑增强没了数据增强是数据集不够时的特效药但这里的坑也非常多。YOLOv8内置的增强策略已经相当完善默认开启mosaic、随机翻转、色彩变换等。我在默认基础上做了一些针对性调整。先看默认增强了什么。Mosaic增强会把4张图拼成一张模型在训练时能看到更丰富的背景和上下文对小目标检测帮助很大HSV色彩变换会随机调整色调、饱和度、明度模拟不同光照条件。这些对叶片病害识别都有好处毕竟田间光线变化太大。但有些增强策略要慎用。旋转增强尤其是大角度旋转会让叶片方向混乱。叶片病害的特征并不依赖方向所以90度、180度旋转问题不大。但雾化、雨纹这类天气增强就不建议用了它们的模拟效果和真实露珠、雨滴的反光差异很大反而会引入噪声。针对本数据集小病斑较多的特点我把mosaic开启的比例保留在默认的1.0同时开启了copy_paste增强把同一批图中的目标复制粘贴到另一张图上。这个策略对增加小目标数量非常有效能显著减少漏检。类别不平衡的问题在采集时就提前做了干预。黑斑病在老叶上更常见自然采集时样本量偏大黄龙病早期症状不明显样本量偏小。我在采集后统计了各类数量对样本少的类别用增强多补了几份对样本多的类别适当控制。实际操作中我用Python脚本为黄龙病类额外生成了水平翻转、小角度旋转、亮度调整的增强副本把各类数量拉平到900张左右。注意增强不是越多越好。增强幅度太大病斑边缘模糊了模型学到的就不是“病斑特征”而是“增强痕迹”验证集上精度虚高真实场景反而暴跌。宁可样本量少一点也不要做过度增强。3.3 YOLOv8训练实战超参选择、训练命令与结果复盘数据准备妥当训练就进入了“抄作业”阶段。我用的是YOLOv8n理由很实际目标是要部署到手机或者边缘设备上nano版本体积小、速度快精度损失在可接受范围内。如果纯做效果演示yolov8s或yolov8m会更高。训练命令如下# 在ultralytics环境中执行 yolo detect train \ datacitrus_disease.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ optimizerSGD \ patience30 \ cacheTrue \ projectcitrus_disease_runs \ nameexp几个关键参数的选择逻辑值得说明一下。imgsz640是速度和精度之间的平衡点对叶片病害这种病斑尺度较小的任务640比512好不少再往上到768或1024会显著增加显存占用但精度提升有限。epochs150配合patience30早停因为数据量不大模型一般在80到110轮之间就会收敛开着早停能省不少时间。batch16取决于GPU显存如果显存不够优先降低batch而不是降低图片分辨率。lr00.01配合SGD是目标检测比较稳妥的起点AdamW虽然收敛更快但在这类中小数据集上SGD的泛化性往往更好。训练过程中的loss曲线要重点看两条训练集loss和验证集loss。验证集loss如果在后期反弹说明过拟合了有两种补救方式一是加数据增强、二是降低学习率继续训练。我在第一轮训练中epochs加到200验证集loss在130轮左右开始上升早停机制在150轮附近自动停了最终采用的是best.pt权重而不是last.pt。训完之后的各项指标我关心的排序是Recall mAP50 mAP50-95。原因是农业场景漏检的代价远高于误检。漏掉一个病株可能导致整园病害扩散经济损失巨大误检最多是浪费一次打药成本。所以召回率是第一位。最终结果如下表病害类别PrecisionRecallmAP50溃疡病0.9420.9350.956炭疽病0.9580.9310.961疮痂病0.8710.8530.887黄龙病0.9150.9080.933黑斑病0.9290.9170.941整体mAP50约0.935这在农业病害识别场景算一个能用的水平。但注意看疮痂病的指标明显低于其他几类预感和实际经验一致——疮痂病和溃疡病的早期症状太像了两者的区分是这类任务里最典型的难点。后面我会专门讲处理办法。4. 常见问题与避坑实录4.1 相似病斑误分类疮痂病和溃疡病到底怎么分这类项目里最纠结的问题就是疮痂病和溃疡病的区分。两者在嫩叶上的早期症状确实非常接近都是黄褐色小斑点都可能带晕圈。就看下面这组对比溃疡病病斑中央凹陷像火山口手摸有明显的木栓化质感正反面都可见疮痂病病斑是突出的疣状凸起叶面粗糙叶片常常扭曲畸形背面更明显。但这个区别在手机上几厘米的小图里根本看不清。我试了两种解法。第一种是硬扛加大这两类的样本量特别是不同生育期的样本。早期症状样本越多模型越容易找到区分边界。但效果有限因为早期形态本身信息量就不足。第二种更有效在检测模型基础上串联一个分类模型检测模型负责找出“疑似疮痂/溃疡”的候选框然后把候选框裁切放大送入一个分类网络做精细判别。两个模型各管各的检测模型保证位置准确分类模型在放大后的图上看纹理细节两者配合误分类问题明显缓解。4.2 小病斑与远距离拍摄的漏检模型再强也看不到“针尖”另一个高频问题是漏检尤其当病斑很小的时候。早期溃疡病的病斑可能只有几个像素大小在640的分辨率下YOLOv8的浅层特征图上这些小目标很容易被下采样丢掉。我的经验是两条路并行。一是训练时把imgsz从640提到896分辨率提高后小病斑占的像素更多模型学起来更容易。显存够的话这个调整立竿见影。二是推理阶段用SAHI做切片推理把原图切成有重叠的小块分别检测再合并结果。实际测试中SAHI能让小病斑的召回率提升8到10个百分点。代价是推理时间增加但边缘设备上靠着NCNN或TensorRT优化也还能接受。4.3 部署阶段的真实环境干扰模型跑通了为什么喷药机还是瞎喷模型在验证集上成绩不错不代表真实场景就万事大吉。我在果园实地测试时遇到了几个训练数据里没充分考虑的情况。早晨有露水时叶片水珠反光会干扰病斑识别尤其对黑斑病这种深色病斑反光一上来边缘就糊了。我的解决思路是采集几轮清晨湿叶照片补进数据集把这类场景变成“见过的场景”。另外正午强光下叶片过曝与训练数据的亮度分布差异很大我加了模拟过曝的增强策略把部分训练图的高光提亮让模型适应这种极端情况。这一步走完后果园实测的误检率明显下降。部署路径上最终选择导出为ONNX再转NCNN格式跑在安卓端的YOLOv8n上单张图推理时间在60到80毫秒之间基本达到了“拍照即出结果”的体验。如果算力再紧张些后续还可以量化到int8。4.4 从目标检测到语义分割的扩展下一个版本做什么目前这个数据集只解决了“哪里有病、是什么病”的问题。但农户其实还关心“病有多重该打多少药”。这就不光是目标检测能解决的了需要量化病斑面积占叶片总面积的比例得做语义分割。我目前的规划是在现在这批边界框标注的基础上用Segment Anything辅助生成叶片和病斑的掩膜把标注升级成分割级。成本比从零开始分割标注低不少毕竟检测框已经把病斑位置圈出来了只需要在框内细化边界。有了分割结果后就能算出每个叶片的病斑面积占比再结合叶面积指数进一步估算整体发病程度。这样模型输出的就不再是“有溃疡病”这样一个结论而是“溃疡病中度发生建议喷施某某药剂”这种可以直接指导生产的建议。这个方向目前还在迭代中但这套数据集和训练流程已经打下了一个可复用的基础。农业AI的落地从来不是一蹴而就的事先把数据这一环做扎实后面的路会顺很多。我个人在带项目过程中越来越深刻的体会是数据集构建的每一分钟都不白费。如果一个模型效果不好先别急着换网络结构、调超参数先回头翻翻数据集看看是不是哪类样本太少、哪类标注质量不过关。模型再好给它的“教材”质量不行它就只能学个寂寞。这套柑橘叶片病害数据集从拍摄到标注再到训练每一步都是在跟“真实世界”较劲这也是它跟实验室里那些干净数据集最本质的差别。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价