ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv8农田病虫害检测实战:从数据集处理到Flask部署全攻略

YOLOv8农田病虫害检测实战:从数据集处理到Flask部署全攻略 简介基于YOLOv8的农田病虫害监测系统是一份面向毕业设计与课程设计的完整工程资源适合计算机视觉、人工智能、电子信息等专业学生使用主要解决农田场景下病虫害检测与结果可视化的问题。压缩包共8个文件含3个Python脚本分别对应模型训练、视频检测与可视化界面、3个模型权重文件包含预训练权重与最佳模型以及2个说明文档整体约15.91MB轻量便于快速部署。作者已完成毕设实测运行稳定能够生成核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果与标签分布图这些图表可直接用于答辩信服展示。配套完整数据集与部署说明从环境准备到模型训练和推理均有指引上手简单。目前已有59人学习适合拿来即用也便于在此基础上修改实现其他检测任务。1. 农田病虫害检测为什么值得选 YOLOv8先想清楚代价再动手每年毕业季农田病虫害检测都是计算机视觉方向出现频率最高的题目之一。原因很现实它比人脸、车牌这些被写烂的方向多一层农业落地的解释空间数据集也比想象中好找。但很多同学拿到这类打包好的项目双击运行没反应或者跑起来发现检测框全乱飘最后把锅甩给“模型太玄学”。其实 YOLOv8 本身的部署链路已经相当成熟真正决定项目成败的是数据集处理和训练参数这两层没有写在说明里的细节。这篇笔记我从跑过不少 CV 项目的角度出发把“拿 YOLOv8 做农田病虫害检测”从选型到界面串联讲清楚包括哪些坑会让你白干一周以及这个方向值不值得投入。适合两类人拿它做毕设或课程设计的在校生以及想快速落地一个检测 Demo 的工程师。2. 从农田病虫害需求到 YOLOv8 选型检测任务拆解与结构上的关键选择2.1 病虫害检测为什么比通用目标检测更难小目标、遮挡与类间差异农田病虫害检测本质上是一个细粒度目标检测任务难度比 COCO 那 80 类通用物体高出一个档次。通用检测里猫和狗、汽车和自行车之间的差异是“结构级”的而稻瘟病斑点和稻胡麻叶斑病在图像上可能只是颜色深浅、边缘形状的细微差别同一个病害在不同生育期、不同光照下又长得不一样。这就是典型的类间差异小、类内差异大分类器稍有不慎就学偏。除了分类难定位也难。害虫和早期病斑在 1920×1080 的田间照片里往往只占几十个像素属于标准的小目标再加上叶片互相遮挡、虫体藏在叶背、田畦光照不均匀、背景里还有泥土和杂草干扰YOLOv8 直接吃原图很容易漏检。这些特性决定了你不能拿别人训练好的权重直接上田间照片必须用自己的数据集做迁移学习微调而且数据质量直接决定项目能不能过答辩。另外病虫害检测还有一个常被忽略的动态问题害虫会动病斑会随天数扩大。同一个地块隔一周拍标注分布完全不同植株长高了遮挡关系也变了。所以做数据集时不能只从一段视频里连续抽帧否则训练集和验证集高度相似指标虚高现场演示立刻翻车。这个坑后面专门讲。2.2 YOLOv8 在技术栈里的位置为什么它是毕设和工程落地的均衡解选型阶段很多同学纠结Faster R-CNN 精度是不是更高SSD 是不是更轻YOLOv5 是不是资料更多我的判断很直接做毕设或快速落地YOLOv8 是目前综合成本最低的选择。Faster R-CNN 精度上限高但两阶段结构在边缘设备上推理慢训练调参也更繁琐SSD 年代较早对小目标并不友好生态也凉了YOLOv5 和 v8 同源但 v8 的 ultralytics 统一接口把训练、验证、导出、推理全封装好了少写大量胶水代码。YOLOv8 在结构上有几个关键点值得在答辩时讲清楚骨干网络用了 C2f 模块替代原来的 C3梯度流更丰富小目标特征保留得更好检测头改成 anchor-free不再需要预设锚框对目标尺寸分布不固定的农业场景更省心分类和回归头解耦收敛速度和精度都有提升。这些不是噱头而是它在农田场景下比老版本更稳的直接原因。再补一个模型尺寸的选择维度。YOLOv8 提供 n/s/m/l/x 五档n 是 nanox 是超大版。农田病虫害我一般建议从 s 或 m 起步n 在复杂背景下病斑漏检明显l/x 对显存和推理时间要求高毕设演示没必要。手头只有 GTX 1660Ti 6GB 这种卡用 s 配 batch 16 就很稳如果数据集超过一万张再考虑 m。模型体积农田场景定位显存需求640 输入适合人群YOLOv8n约 6 MB快速 Demo、边缘设备原型2~4 GB纯跑通流程YOLOv8s约 22 MB毕设主力、中等数据集4~6 GB大多数场景YOLOv8m约 49 MB大数据集精度优先6~8 GB追求指标YOLOv8l/x超过 80 MB服务器离线分析10 GB 以上不推荐毕设2.3 一个完整监测系统由哪几块组成模型、数据、界面与部署四件套这类标题里写着“源码、可视化界面、完整数据集、部署教程”的项目拆开看就是四件套标注好的数据集、训练脚本、推理接口、展示界面。你拿到手之后要做的不是直接跑 demo而是把这四块的依赖关系理清楚才能自由更换数据集和权重。训练链路的常见结构是田间图像 labelme 或 LabelImg 标注 → 转换成 YOLO 格式的 txt 标签 → 写 data.yaml 描述类别 → ultralytics 训练出 best.pt。推理链路则是best.pt 加载进 YOLO 类 → 对上传图片做预测 → 把框和类别送回界面层展示。界面层一般用 PyQt5 做桌面程序或者 Flask 做网页版也有用 Streamlit 几分钟搭一个的。“简单部署即可运行”这句话通常指的不是零配置而是依赖清单完整、启动脚本齐全、权重文件已经训练好你只需建一个 Python 环境装好 requirements 就能把界面拉起来。但依赖版本和路径问题依然存在后面第 5 章会专门讲。建议你拿到项目后先别急着点运行按训练链路、推理链路、界面链路三个层次各跑一遍哪个环节报错就锁定哪一层比对着整个项目瞎试高效得多。3. 用 YOLOv8 跑通训练闭环环境搭建、数据集整理与训练命令实录3.1 环境搭建CPU 也能跑但显存决定效率上限环境搭建是第一个分水岭。很多人在 Ubuntu 20.04 上照着教程搭 YOLOv8 CPU 版本装完发现训练一个 epoch 要十几分钟直接放弃。我的建议是分两步走先把环境跑通再决定用 CPU 还是 GPU。如果你只是做课程设计的演示CPU 版完全可以接受因为推理一张图只要一两秒但如果你想认真调参训练没有 NVIDIA 显卡会很痛苦。安装命令如下conda create -n pest python3.9 -y conda activate pest pip install ultralytics # CPU 版本直接装默认 torch 即可 pip install torch torchvision # GPU 版本按你的 CUDA 版本选择例如 CUDA 11.8 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118Python 版本我强烈建议锁在 3.8 到 3.10 之间。3.11 以上装某些依赖会出现二进制包缺失3.7 以下又带不动新版本 ultralytics。装完跑一句yolo predict sourcehttps://ultralytics.com/images/bus.jpg能输出检测结果图就说明环境通了。GPU 环境可以用nvidia-smi看驱动支持的 CUDA 版本再回推 torch 的 cu 版本号版本对不上会出现Torch not compiled with CUDA enabled的报错。3.2 数据集整理labelme 标注转 YOLO 格式的完整转换脚本数据集整理是整个项目里最耗时间、也最影响结果的一步。常见做法是先用 labelme 标注因为它能画多边形和矩形适配病斑的不规则形状但 YOLO 训练需要的是 txt 格式的归一化中心点坐标所以必须写转换脚本。标签文件里每一行是类别id x_center y_center width height全部除以图像宽高做归一化。类别 id 从 0 开始顺序必须和 data.yaml 里的 names 列表完全一致否则训练出的模型类别全错位。转换脚本如下import json import os from glob import glob def convert_labelme_to_yolo(json_path, out_dir, classes): with open(json_path, r, encodingutf-8) as f: data json.load(f) img_w data[imageWidth] img_h data[imageHeight] base_name os.path.splitext(os.path.basename(json_path))[0] lines [] for shape in data[shapes]: label shape[label] if label not in classes: continue cls_id classes.index(label) pts shape[points] xs [p[0] for p in pts] ys [p[1] for p in pts] x_min, x_max min(xs), max(xs) y_min, y_max min(ys), max(ys) x_center ((x_min x_max) / 2) / img_w y_center ((y_min y_max) / 2) / img_h box_w (x_max - x_min) / img_w box_h (y_max - y_min) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}) with open(os.path.join(out_dir, base_name .txt), w) as f: f.write(\n.join(lines)) classes [rice_blast, rice_bacterial_blight, rice_brown_spot] os.makedirs(labels_all, exist_okTrue) for jp in glob(labelme_jsons/*.json): convert_labelme_to_yolo(jp, labels_all, classes)脚本的逻辑很直接读取 labelme 的 JSON取出每个标注框的 label 和四个顶点坐标计算外接矩形的中心、宽高做归一化后写入 txt。注意我用的是外接矩形所以多边形标注的倾斜部分会被包进去如果你的病斑是细长条状介意背景干扰的话可以改用旋转框但 YOLOv8 默认不支持旋转框需要换 YOLOv8-OBB复杂度会上升。标注文件转完后还要划分训练集和验证集。我最常用的是随机抽样但前提是数据不是从同一段视频连帧抽的。划分比例按 8:2 或 9:1验证集不能太少否则 mAP 波动大。目录结构固定为images/train、images/val、labels/train、labels/val四份图片和 txt 文件名要一一对应。这里有个常见的低级错误jpg 和 txt 主名不一致导致训练时标签加载不到ultralytics 会静默跳过造成 loss 异常低或直接无法收敛。3.3 训练命令与关键参数把 epochs、batch 和 imgsz 填对数据准备好了训练前要写一个 data.yaml 告诉模型去哪里找数据。路径建议写绝对路径相对路径在换目录后经常出问题。yaml 内容如下path: /home/user/pest_dataset train: images/train val: images/val nc: 3 names: 0: rice_blast 1: rice_bacterial_blight 2: rice_brown_spot然后启动训练。这是最核心的一条命令参数含义直接影响结果yolo train \ modelyolov8s.pt \ datadata.yaml \ epochs100 \ imgsz640 \ batch16 \ device0 \ patience20 \ workers4参数逐个说。epochs100是最大训练轮数实际会配合patience20早停也就是 20 个 epoch 内验证集指标不涨就自动停防止过拟合。batch16受显存限制GTX 1660Ti 6GB 跑 s 模型比较稳显存不够就降到 8。imgsz640是输入分辨率如果你的数据集里病斑普遍很小可以试imgsz960但训练时间会明显变长且 batch 得同步调小。device0指定 GPUCPU 机器改成devicecpu。workers是数据加载线程数Windows 上容易报错设 2~4 稳妥。训练过程中不要只盯 loss。每跑完一个 epochruns/detect/train/目录下会生成results.png里面有损失函数曲线图、精确率、召回率和 mAP 曲线的趋势。你真正该关心的是 mAP50 曲线有没有在爬升而不是训练集 loss 降到多低。训练结束会同时产出best.pt和last.pt部署一律用best.pt它对应验证集表现最好的那一个 epoch泛化通常更好。3.4 用训练好的权重做推理先别接界面用命令行验证效果模型训完先别急着写界面用命令行跑一遍推理确认权重本身没问题。推理命令如下yolo predict \ modelruns/detect/train/weights/best.pt \ sourcetest_images/ \ conf0.25 \ iou0.45 \ saveTrueconf0.25是置信度阈值低于 0.25 的框会被丢弃iou0.45是 NMS 去重阈值两个重叠框的 IoU 大于 0.45 时只保留置信度高的。这两个参数在界面里也可以让用户调但默认值建议 0.25 和 0.45。如果跑出来的框大量重叠把 iou 调低到 0.3如果漏检多而误检少把 conf 调低到 0.15 试试。命令行输出图和保存结果都在runs/detect/predict/下直接翻图看效果翻车点比看指标更直观。4. 可视化界面与部署把模型封装成能交给老师的系统4.1 导出与封装从 PyTorch 权重到稳定推理接口训练好的 best.pt 是 PyTorch 权重直接拿来做界面有两个问题一是依赖 torch 这个重库二是推理速度受 Python 动态图影响。常见做法是先导出 ONNX再用 onnxruntime 做推理依赖更轻CPU 上速度也比 PyTorch 推理快一截。导出命令from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) model.export(formatonnx, imgsz640, halfFalse)执行完会在同目录生成.onnx文件。这里特别注意halfFalse半精度 FP16 在 GPU 上能提速但 CPU 上不支持会直接报错毕设部署基本都用 CPU 跑保持 FP32 就好。ONNX 导出成功后推理接口可以用 onnxruntime 写或者干脆继续用 ultralytics 加载 onnx 文件后者更省事。from ultralytics import YOLO model YOLO(best.onnx) results model.predict(img, conf0.25, iou0.45)用 ONNX 还有一个好处如果以后想往边缘设备迁移比如在 RK3588 这类开发板上做部署onnx 可以再转成 rknn 格式PyTorch 权重反而要多一步处理。所以无论当前用不用先导出 onnx 都不亏算是给项目留了后悔药。4.2 三种可视化界面方案怎么选PyQt、Flask 还是 Streamlit可视化界面是毕设答辩的加分项但不是技术难点。常见方案就三种先看表格再选别一上来就 PyQt方案形态开发成本部署复杂度适合场景PyQt5桌面窗口高需要写布局打包 exe 有坑想展示完整桌面应用Flask 网页浏览器访问低几十行起服务即可答辩演示最稳妥Streamlit自动生成网页极低依赖简单快速原型、内部验证我一般推荐 Flask 网页版原因很实际答辩现场只需要一个浏览器打开 localhost不需要安装额外软件也不怕 PyInstaller 打包时缺 DLL。而且 Flask 天然支持后面扩展摄像头实时检测你只需要再加一个img标签轮询帧就行。本地运行时所有代码都在一台机器上也方便演示“从上传图片到出结果”的完整流程。4.3 Flask 封装推理接口的最小实现从图片上传到返回检测框下面是一个可直接跑的最小 Flask 应用把 ONNX 模型封装成 HTTP 接口前端上传图片后端返回检测框坐标和类别。代码逻辑分为三块加载模型、解析上传文件、执行推理并组织返回数据。import cv2 import numpy as np from flask import Flask, request, jsonify from ultralytics import YOLO app Flask(__name__) model YOLO(best.onnx) app.route(/detect, methods[POST]) def detect(): file request.files.get(image) if file is None: return jsonify({error: no image}), 400 img_bytes np.frombuffer(file.read(), np.uint8) img cv2.imdecode(img_bytes, cv2.IMREAD_COLOR) results model.predict(img, conf0.25, iou0.45) boxes results[0].boxes.xyxy.cpu().numpy() classes results[0].boxes.cls.cpu().numpy().astype(int) names results[0].names detections [] for box, cls_id in zip(boxes, classes): detections.append({ bbox: box.tolist(), class_id: int(cls_id), class_name: names[cls_id] }) return jsonify({count: len(detections), detections: detections}) if __name__ __main__: app.run(host0.0.0.0, port5000)接口逻辑不复杂但有几个细节容易踩一是model.predict里不再需要传source因为传入的已经是解码后的 ndarray二是cv2.imdecode处理的是内存字节直接用cv2.imread(path)会读不到上传的临时文件三是返回前要把 numpy 类型转成 Python 原生类型否则 jsonify 会报Object of type ndarray is not JSON serializable。前端配一个表单上传页就能完成整个演示闭环这也是标题里所谓“功能完善、操作简单”最常见的技术栈落法。4.4 部署自检清单requirements、启动脚本与路径规范部署说的“简单即可运行”实际落实在三件事上。第一requirements.txt 锁住核心依赖版本避免换一台机器版本漂移ultralytics8.0.0 flask2.0.0 opencv-python4.5.0 numpy1.21.0 onnxruntime1.14.0第二启动脚本一键起服务。Windows 下给一个start.batLinux 下给一个run.sh内容就是激活环境加启动 Flask别让用户去手动敲命令。第三项目路径不能有中文。ultralytics 和 OpenCV 对中文路径的支持一直不完善放到D:\毕设\病虫害\下面大概率读图失败。我会在部署文档第一行就写所有目录名、文件名用英文不要带空格。把这三件事做到才算真正达到了“简单部署即可运行”。5. 农田病虫害检测避坑指南数据、训练与界面三层最常见的翻车点5.1 训练 loss 不降或直接 NaN现象训练到第 5 个 epochloss 曲线完全不动或者某一步直接变成 NaN之后指标全乱。这种情况新手最容易慌以为是模型坏了。原因八成出在标签文件上。最常见的是某个 txt 标签里写了超出nc范围的类别 id或者 data.yaml 的 names 顺序和转换脚本里的 classes 顺序不一致也有少部分是学习率太大尤其是用了自定义优化器参数时。另外空的标签文件也会让模型在该图上无梯度更新影响收敛。解决先检查labels/train下有没有 0 字节的 txt有就删掉对应图片或重新标注再写一段代码遍历所有 txt确认最大类别 id 小于nc最后把lr0显式设为 0.01不要随意调大。用yolo train时加verboseTrue能打印每个 batch 的 loss定位出问题的那一步。5.2 小目标漏检严重病斑根本框不出来现象验证集 mAP 看着有 0.7但实际拿手机拍一张田间的稻瘟病斑图模型一个框都不出。这种情况在病虫害场景里极其常见因为病斑在整张图中的占比实在太小。原因输入分辨率不够。imgsz640时一个 20×20 像素的病斑下采样到特征图只剩 2~3 个像素C2f 模块再强也救不回来。另一个原因是训练数据里小目标占比本来就低模型对大目标过拟合了。解决优先把imgsz提到 960batch 同步减半如果还不行就做切片推理——把大图切成 640×640 的重叠块逐块检测再合并结果。数据层面标注时别偷懒小病斑也要仔细框或者用离线切图把原始大图切成小图后再标注让模型看到更多“放大”后的病斑样本。这一步是最耗时间的但也是效果提升最明显的。5.3 mAP 高但界面演示乱框重影现象训练指标很好但界面上一张图同时框出十几个重叠框同一个病斑被标成两个类别演示效果像模型疯了一样。原因推理时的conf阈值太低比如设了 0.1模型把大量低置信度预测也吐出来。另一个隐蔽原因是训练集和验证集高度相似也就是数据泄漏模型指标虚高对真实场景的泛化其实很差。解决把界面里默认conf提到 0.3 以上先看演示效果。同时检查数据划分如果训练集和验证集是从同一段视频连续帧抽的必须重新划分。我的习惯是不同时间、不同田块、不同设备拍的照片放进不同集合保证验证集与训练集在拍摄条件上有本质差异这样 mAP 才可信。数据泄漏会让你的毕设现场翻车防人之心不可无。5.4 界面启动报错 ModuleNotFoundError 或版本冲突现象所有文件都在requirements 也装了但运行python app.py直接报ModuleNotFoundError: No module named torch或者cv2导入失败。还有的情况是 torch 装好了但报 CUDA 版本不匹配。原因最常见是 Python 版本和包版本不匹配。3.11 及以上装某些旧版 opencv 或 onnxruntime 会拉不到对应 wheeltorch 的 cu 版本和本机显卡驱动不匹配也会让 import 报错。还有一个隐蔽情况是 conda 环境没激活包装到了 base 环境里命令跑的时候却用的是另一个环境。解决删除环境重建Python 锁 3.9再按 requirements 逐个装。装 torch 前先nvidia-smi查驱动版本再选对应 cu 版本没有 NVIDIA 显卡的机器直接装 CPU 版 torch不要强行装 cu 版本。启动脚本里显式conda activate pest不要依赖用户手动激活。这一套做完能解决九成环境问题。5.5 中文路径导致读取图片失败现象程序不报错但返回的检测结果是空的或者在cv2.imread那一步返回 None后面直接抛异常。用户如果按中文习惯把项目目录命名为“病虫害检测”大概率踩中。原因OpenCV 的imread在 Windows 上对中文路径支持不完整ultralytics 内部的路径处理在中文路径下也可能乱码。这个问题在 Linux 上稍好但 Windows 下几乎是必然复现的。解决项目根目录、数据集目录、图片文件名全部改成英文目录中间不要有空格。如果甲方硬要用中文文件名可以在读取时改用np.fromfile加cv2.imdecode组合能绕过一部分问题但治标不治本。我一般直接把规范写进部署文档第 1 条本系统不支持中文路径请勿修改目录名。6. 模型验证与进阶从能跑到跑得稳我的验收习惯6.1 用“陌生文件夹”做最终验收训练完成、界面能跑之后我最后一步不是看 mAP而是新建一个完全没有参与训练的测试文件夹里面放十几张不同光线、不同角度、不同田块的照片手动数一遍每张图有几个病斑再去跑推理按图对比。这个动作能在五分钟内暴露模型的真实水平比任何指标都诚实。我把这个文件夹命名为final_test长期保留每次调参后都跑一遍作为回归测试。另外我会随手记录每张图的置信度分布如果一张图的最佳框只有 0.3 的置信度说明模型对这类样本学得不够该补数据了。6.2 进阶方向切图、数据增强与边缘部署如果项目还有余力提升三个方向按性价比排序。第一是高频切片推理把大图切成 640 重叠块病斑漏检率能显著下降缺点是推理时间变长但界面演示时只对上传单图操作完全能接受。第二是数据增强配置ultralytics 默认增强对农业场景基本够用别乱加 mosaic因为 mosaic 拼接会让病斑被切割得更碎小目标反而更难学。第三是模型导出链路的延伸目前你已经有了 onnx后续可以按 RK3588 这类边缘开发板的工具链转成 rknn 或 ncnn 格式实现田间本地化实时检测这就是一个可以写进论文的落地延伸点了。我最早做这类项目时拿到数据集就直接训练验证集指标好看实地拍一张全乱框后来才反应过来训练集和验证集来自同一批录像抽帧。从那以后我坚持任何演示图片都不放进训练集陌生图片才是模型真正的试金石。这套流程你照着走一遍大概率能少熬几个夜。希望帮到你。本文还有配套的精品资源点击获取
返回列表