资讯动态

基于YOLOv8的茶叶病害检测系统:从训练到部署全流程解析

发布时间:2026/9/8 14:18:17 来源:尧图企业网站定制
简介面向茶叶病害快速检测与自动化识别需求这套基于YOLOv8的完整系统方案包含Python源码、YOLOv8n ONNX模型、评估指标曲线以及基于PyQt5制作的精美GUI界面。系统在Windows10、Anaconda3、Python3.8环境下配置torch1.9.0与ultralytics8.2.70运行通过模型支持茶饼病、茶褐枯病、茶叶锈病、红蜘蛛危害叶片、茶蚊虫危害叶片、健康茶叶、茶白星病、一般病害共8类目标的检测与标记覆盖茶树常见生长问题。包体共98个文件总大小约12.82MB主要文件类型包括74张jpg测试图像、6张png图片、6个xml标注文件、3个Python脚本、3个txt说明文件以及1个ONNX模型等并附带启动配置与界面资源目录划分清晰方便直接运行和二次修改。当前已有481人学习下载适合农业工程、计算机视觉领域的初学者或开发者用于毕业设计、科研比对、模型部署演练也可作为茶叶种植智能化监测的桌面端演示工具。 开头≥200字茶树长在野外叶片颜色、光照、背景比实验室里拍的验证集复杂太多了。我前两年帮农技站的朋友做茶树病害普查需要拍一堆叶片照片回来人工数病斑效率和准确率都不够。后来我搭了这套“基于yolov8的茶叶病害检测系统”用python把训练、导出、部署整条链路走通最后交付的是一个带onnx模型和精美GUI界面的离线工具。你双击打开界面拖进去一张茶园照片几秒钟就能标出茶饼病、茶轮斑病这些区域还能直接检测视频和摄像头直播画面。这篇文章就把我这个项目的完整方案拆开讲一遍。内容覆盖为什么选yolov8做茶叶病害检测、数据怎么标注和训练、pt模型怎么转成onnx、GUI界面怎么和推理逻辑无缝整合以及我在实测中踩过的坑和调优经验。不管你是刚入门目标检测、被导师扔了一个农业检测课题还是想做一套能交付给非技术用户使用的检测工具这个项目从技术选型到代码组织都有可以直接抄作业的参考价值。1. 为什么是yolov8茶叶病害检测的选型逻辑1.1 茶园场景的检测难点茶叶病害检测和通用物体检测有非常大的区别。第一个难点是目标小病害初期的病斑往往只有十几个像素一张640分辨率的图片里可能同时存在几十个病斑第二个难点是背景杂茶垄里的老叶片、枯叶、昆虫、杂草都会干扰模型尤其是枯叶的颜色和茶饼病病斑非常接近第三个难点是类间差异小茶轮斑病和茶炭疽病在视觉上就很容易混淆人的肉眼都要仔细看模型如果只是端到端训练收敛起来很费力。这些问题决定了我们不能用一个普通的分类网络在家用相机拍的照片上跑一跑就完事必须有目标检测模型去定位病斑位置而且模型必须对多尺度、小目标有足够强的表达能力。1.2 yolov8的核心优势我在选型的时候对比过SSD、Faster R-CNN、yolov5和yolov8。Faster R-CNN精度上限高但推理速度吃紧在CPU上跑视频流基本不现实SSD对小目标不友好加上我手里训练资源有限就不考虑了。yolov5在当时已经很成熟但对比下来yolov8把C2f模块和Anchor-Free检测头组合在一起特征融合效率更高在同等精度下模型更小训练也更容易收敛这对农业场景里“效果重要、部署也要省事”的需求非常匹配。另外yolov8本身在工程化上做得很完善官方仓库自带训练、验证、导出一条龙脚本支持导出onnxGUI推理部分又不需要依赖完整的PyTorch环境直接用onnxruntime就够了。这套“yolov8训练onnx部署”的组合拳是我最终确定方案的决定性因素。1.3 项目的整体架构这套茶叶病害检测系统在结构上分成三条线离线训练线、模型转换线、GUI部署线。离线训练线负责数据标注和模型训练产出best.pt权重文件模型转换线把best.pt导出成best.onnx顺便做输入输出形状验证GUI部署线用PyQt5写界面内部调用onnxruntime做推理把检测框和置信度画在界面上。选这个架构有两个好处第一农户或者农技站的人不需要安装Python环境也不需要懂模型双击exe就能用第二以后换成其他作物时只需要重新训练模型GUI代码几乎不用改。整个系统的技术栈和职责如下表所示模块使用技术职责模型训练Ultralytics YOLOv8训练茶叶病害检测权重模型转换onnx / onnxruntime将PyTorch模型转为通用部署格式界面开发PyQt5 QThread图片/视频/摄像头检测交互指标展示matplotlib绘制损失曲线与PR曲线打包交付PyInstaller打包为独立可执行程序2. 数据集整理与训练模型效果的根基2.1 公开数据集与自采数据的组合茶叶病害检测效果好不好一半以上取决于数据。当时我的数据来源分两块一是公开的茶叶病虫害数据集像网络上能搜到的茶树病害图像库二是自己在茶园用手机和微距相机补拍的照片。公开数据的好处是类别齐全坏处是拍摄环境相对单一直接拿来做训练遇到真实茶园复杂背景就会掉点自采数据的价值就在于能覆盖逆光、老叶、重叠叶片这些模型容易出问题的场景。我的组合比例大约是公开数据占七成、自采数据占三成但自采数据会单独做一次清洗。实际清洗的时候我发现很多公开数据的标签框打得特别松框内有大片背景这会让模型把背景特征一起学进去所以清洗时我会重新标注一部分质量差的样本宁缺毋滥。2.2 类别标注与技术细节我最终保留了四个主要病害类别茶饼病、茶轮斑病、茶炭疽病和茶白星病另外加了一个“健康叶片”类别作为背景抑制。这里有个容易被新手忽略的点目标检测任务的“背景”不是单独一个类别模型是靠大量的负样本学会抑制背景的所以我在训练数据里特意保留了大量没有病害的健康叶片照片让模型知道“看到正常叶片时不要乱框”。标注工具用的labelimg标注时框的紧贴程度很重要。病害小目标尤其如此框稍微大一点gt框和预测框的IoU计算就会受影响。我的经验是病斑目标宁可框紧一点也不要留太多背景同时不同标注员之间要保持一致的标注风格否则模型对目标边界的判断会不稳定。数据增强方面我开启了yolov8自带的mosaic、翻转和色彩增强mosaic对提升小目标检测效果很有帮助因为它强制模型学习拼接图像中不同尺度的目标。2.3 训练超参数与损失曲线解读训练命令如下yolo detect train datatea_disease.yaml modelyolov8n.pt epochs200 imgsz640 batch16 device0这里我选择在yolov8n基础模型上做迁移学习而不是从头训练。茶叶病害数据量再大也大不过COCO用ImageNet和COCO上预训练好的权重做初始化收敛速度快很多最终精度也更高。imgsz640是个性价比很高的选择低于640时小病斑容易丢高于640时显存和推理耗时明显上升而且训练收益并不大。训练过程中需要重点盯住box_loss、cls_loss和dfl_loss三条曲线。如果训练集loss持续下降但验证集loss在某个epoch后反弹说明过拟合了此时应该减少epoch数或者增加数据增强如果cls_loss降得很慢通常说明类别数过多或者相似类别的样本量不均衡。我的做法是每隔20个epoch用验证集跑一次mAP观察mAP50和mAP50-95的走势最终保存下来的是验证集上mAP50-95最高的那版权重而不是最后一个epoch的权重。实际测试下来我的模型在自建验证集上mAP50大约在0.82到0.86之间已经能满足生产环境初步筛查的需求。3. pt转onnx部署的关键一跳3.1 为什么不用pt直接部署有朋友问我训练好的best.pt不是直接能model.predict()吗为什么还要多此一举导出onnx原因在于交付场景。第一best.pt依赖PyTorch框架目标机器上必须装对应版本的torch、torchvision和一堆CUDA库占用好几个G空间对农技站那种普通办公电脑很不友好第二onnxruntime的CPU推理效率比PyTorch原生的CPU推理更高特别是在Intel处理器上它会自动利用指令集做优化第三ONNX是开放格式以后想换到NVIDIA的TensorRT、Intel的OpenVINO或者瑞芯微的RKNN都可以从onnx继续转换不会被PyTorch锁死。3.2 导出过程和验证逻辑导出命令用的是Ultralytics自带的接口yolo export modelbest.pt formatonnx opset12 dynamicFalse simplifyTruesimplifyTrue表示用onnx-simplifier对计算图做常量折叠和冗余节点消除导出后的模型体积更小推理速度也更稳。dynamicFalse的意思是输入输出尺寸固定为640x640这样在CPU上推理时的内存布局最优。如果你需要GUI里灵活调整分辨率可以考虑dynamicTrue但推理性能会稍有下降。导出完成后我强烈建议做一次“输出一致性验证”分别用best.pt和best.onnx对同一张图片做推理比较两者的检测框坐标和类别差异。理论上pt和onnx的数值精度差异应该在1e-3量级如果差异很大先检查是否忘了model.eval()再检查onnx算子的精度选项。我遇到过一次dfl层在onnx下表现异常的情况解决方案是把opset升级到更高版本重新导出。3.3 onnxruntime推理实现部署端的推理代码需要自己实现完整的预处理、前处理和NMS后处理。预处理部分yolov8要求输入格式是(1, 3, 640, 640)的RGB图像像素值归一化到0到1并且要按高度、宽度顺序resize不能搞反通道顺序。NMS后处理的部分代码整理如下import cv2 import numpy as np import onnxruntime as ort session ort.InferenceSession(best.onnx, providers[CPUExecutionProvider]) input_name session.get_inputs()[0].name # 假设model已经返回(1, 84, 8400)的原始输出 outputs session.run(None, {input_name: blob})[0][0] # shape: 84x8400 # 转置后拆分前4行是box信息后80行是类别得分 boxes outputs[:4, :].T scores outputs[4:, :].T # 每个anchor取最大类得分 class_ids np.argmax(scores, axis1) confidences scores[np.arange(scores.shape[0]), class_ids]拿到结果后再做坐标解码把相对于640x640的坐标映射回原图尺寸。这一步最容易出的问题是坐标映射公式写错导致检测框位置偏了。我建议单独写一个map_to_original_image的小工具函数用几个已知位置的标定图去验证坐标映射是否正确比自己凭肉眼判断可靠得多。实测在我的办公电脑i5-9400FCPU上onnx模型处理一张640x640图片大约需要90ms在GTX 1660Ti上只需要15ms。如果放到没有独立显卡的机器上优先选择yolov8n版本CPU推理时间可以压到50ms以内。4. GUI界面与推理流程整合4.1 界面功能规划这套GUI我用的是PyQt5界面布局参考了常见图像标注工具的习惯。左侧是图像预览区右侧是功能面板和检测结果列表底部是日志输出区。功能上我做了三种输入来源图片文件、视频文件和摄像头实时画面。图片检测是最基础的功能点击“打开图片”后主窗口立即在预览区显示原图再点击“开始检测”就能叠加检测框。视频检测的逻辑要复杂一些需要循环读取视频帧每帧做一次推理并绘制结果最后通过QTimer按帧间隔刷新画面。摄像头检测和视频检测代码结构基本相同区别在于数据源换成cv2.VideoCapture(0)并额外处理摄像头断连的情况。4.2 多线程设计避免界面卡死的关键GUI最忌讳把推理逻辑直接写进按钮的回调函数里。一张图推理90ms还好如果是视频流推理耗时直接跑到UI主线程里窗口会变成“未响应”体验非常糟糕。我用QThread把推理任务拆到子线程class DetectWorker(QThread): frame_ready pyqtSignal(object) log_message pyqtSignal(str) def __init__(self, session, source_type): super().__init__() self.session session self.source_type source_type self._running True def run(self): while self._running: # 读取图片/视频帧 - 预处理 - onnx推理 - NMS - 绘制结果 self.frame_ready.emit(result) self.msleep(10)子线程通过pyqtSignal把处理结果回传给主线程主线程只负责把图像显示到控件上。停止检测时先调用worker.stop()再worker.wait()确保线程完全退出后再重新启动新线程否则会出现重复检测的诡异问题。我当时在这个地方卡了半天最后的教训是QThread对象千万不要重复start需要就新建实例。4.3 评估指标曲线与模型信息展示这个项目要求“评估指标曲线”我在GUI右侧加了一个“训练指标”页签把训练阶段保存的results.png和混淆矩阵嵌入显示。界面里用QLabel加载图片配合matplotlib把PR曲线画成可交互的图表。主界面上清晰展示当前模型名称、输入分辨率、每帧耗时等信息方便非技术用户了解当前状态。我建议在交付给非技术用户前把GUI里的英文按钮全部改成中文检测置信度阈值提供可拖动的滑条而不是输入框。置信度滑条是很多用户实际使用时的刚需阈值调低能检出更多病斑但伴随误检阈值调高漏检增多但结果干净这个平衡点应该让使用的人根据现场情况自己掌握。5. 实测中的坑与调优从能跑到好用5.1 小目标漏检与输入分辨率第一轮部署到茶园实测时我发现茶饼病的初期病斑漏检率比较高。排查了很久问题不在模型结构而在输入分辨率。茶饼病初期病斑在原始照片里往往只有20x20像素resize到640x640后病斑只剩下3x3像素特征基本被压缩没了。后来我把输入分辨率提高到960并且配合更大尺寸的mosaic增强重新训练。漏检率明显下降CPU推理耗时从90ms涨到200ms左右但考虑到实际场景里主要是单张图片检测这点性能开销可以接受。如果你用的是摄像头实时检测建议保持640或768分辨率优先保证帧率。5.2 相似病害类别误检与样本平衡茶轮斑病和茶炭疽病的视觉差异非常细微模型经常把两者混淆。单纯增加epoch数没有效果后来我针对这两个类别做了两件事一是重新整理验证集发现原始标注里有一部分样本的类别标签就标错了这直接误导了模型二是针对这两个类别做更激进的数据增强比如随机裁剪局部病斑、调整亮度对比度让模型更多关注病斑本身的纹理特征而不是全局颜色。这里还要提一个非常重要的认知检测模型对“颜色”极其敏感。茶叶病害在不同光照下颜色差异很大如果训练数据里晴天照片占大多数阴天照片的检测效果会直线下降。我在数据增强里加入了亮度扰动和HSV增强相当于用很小的成本把训练数据的“光照多样性”大幅提升这个操作比调任何超参数都管用。5.3 打包与onnxruntime兼容性用PyInstaller打包GUI时踩过一个典型的坑onnxruntime的动态库在打包后经常找不到运行exe会直接报错。解决方法是额外检查打包日志把onnxruntime/capi下的动态库文件手动加进打包数据里。另外PyInstaller默认的打包体积很大主要是把不需要的库也打进去了可以用--exclude-module排除tkinter、pytest等完全用不到的模块能明显缩小体积。5.4 视频检测帧率不足的优化方向如果视频检测跑不满实时性我建议按优先级依次尝试换成yolov8n的onnx模型、把输入分辨率降到480、开启onnxruntime的intra_op_num_threads参数、最后再考虑用OpenVINO或TensorRT替换CPU/GPU执行器。这一套组合拳下来大多数普通电脑都能跑到10FPS以上做普查筛选已经够用。最终交付给农技站使用时整个流程是打开exe拖入茶园照片滑条调整置信度点导出报告系统自动生成带检测结果的图片和csv统计表。这套东西不用连服务器、不用装Python也几乎没有学习成本这才是农业检测工具该有的样子。如果你也想做类似的检测系统我建议先别急着调参先想清楚你的目标用户是在什么环境下使用这套工具。如果是在实验室里做研究追求mAP就行如果是给生产一线用稳定性和易用性比精度更重要。这套基于yolov8onnxGUI的架构我觉得是兼顾效果与交付成本的一条很成熟的路径后面我会继续往模型轻量化方向折腾。本文还有配套的精品资源点击获取

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

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

免费获取报价