基于 YOLO11 的番茄九 类 病害智能识别系统

举报
柠檬🍋 发表于 2026/10/17 23:37:40 2026/10/17
【摘要】 基于 YOLO11 的番茄九 类 病害智能识别系统让一张番茄叶片照片告诉农户:“这是什么病、有多严重、怎么治。”一、背景1.1 行业痛点番茄是大棚和大田里产量与产值都最重要的茄科作物之一。但它有个出了名的毛病:怕病——早疫、晚疫、叶霉、斑枯、花叶病毒、黄化曲叶病毒、红蜘蛛、潜叶蛾……每一种都能在一周内把一茬番茄的产量直接打掉一半。而真正的痛点在田间识别:农户/合作社最常见的处理方式仍然是"看...

基于 YOLO11 的番茄九 类 病害智能识别系统

让一张番茄叶片照片告诉农户:“这是什么病、有多严重、怎么治。”

一、背景

在这里插入图片描述

1.1 行业痛点

番茄是大棚和大田里产量与产值都最重要的茄科作物之一。但它有个出了名的毛病:怕病——早疫、晚疫、叶霉、斑枯、花叶病毒、黄化曲叶病毒、红蜘蛛、潜叶蛾……每一种都能在一周内把一茬番茄的产量直接打掉一半。

而真正的痛点在田间识别:

  • 农户/合作社最常见的处理方式仍然是"看叶子 → 凭经验喷药",结果误判 / 漏判很常见,错喷药不仅不治病,还伤叶;
  • 一线农技员人少地广,根本跑不过来;
  • 已有的"农业大模型"或多分类模型多偏图像分类,给不出"病害位置 + 严重程度 + 防治建议"这种结构化结果。

本项目用 YOLO11n 把"番茄叶片病害检测"做成一个九类目标检测 + 防治知识库的组合方案,让识别结果不只是一个标签,而是一份能直接喂给农户的"病害体检报告"。

视频演示与源码 下载

https://www.bilibili.com/video/BV1i4aS6SEt1/

在这里插入图片描述

包含: 📦完整项目源码 📦预训练模型权重

🗂️数据集

1.2 项目运行效果

在这里插入图片描述

在这里插入图片描述

1.3 项目介绍

核心创新点:

维度 说明
病害覆盖 9 类常见番茄叶片病害 + 健康叶片对照,覆盖真菌、病毒、虫害三大类
知识库联动 内置每类病害的"症状描述 + 严重等级 + 防治建议",UI 上结果直接附带防治方案
严重程度分级 healthy / mild / moderate / severe 四档,按等级用不同颜色高亮
多输入 Streamlit 单图 / 批量 / 视频 / 摄像头四类输入,巡田、连拍、监控视频都能消费
行业话术 UI 用番茄红 + 叶片绿,配合配置文件 class_severity / disease_info 自动渲染

在这里插入图片描述

九类病害:

番茄早疫病 / 番茄晚疫病 / 番茄叶霉病 / 番茄斑枯病
番茄花叶病毒病 / 番茄黄化曲叶病毒病
番茄红蜘蛛病 / 番茄潜叶蛾
健康叶片

技术栈:

层 选型
检测模型 YOLO11n(ultralytics 官方,预训练 yolo11n.pt)
训练框架 ultralytics ≥ 8.3
后端推理 Python 3.10 + PyTorch
前端 Streamlit + Plotly
视频解码 OpenCV + imageio-ffmpeg
部署形态 Streamlit / Docker;可下沉到田间巡检 PAD

二、设计框架

┌────────────────────────────────────────────┐
│ 农户 / 农技员 / 智慧农业大屏                │
│ 单叶照片 / 田间连拍 / 巡田视频 / 摄像头     │
└─────────────┬──────────────────────────────┘
              ▼ HTTP(默认 8501)
┌────────────────────────────────────────────┐
│ Streamlit 应用 app/streamlit_app.py         │
│ ├─ infer_image_path() 单帧推理              │
│ ├─ render_disease_info(cls) 调防治建议库    │
│ └─ render_batch_analysis() 类别 + 严重程度  │
└─────────────┬──────────────────────────────┘
              ▼ ultralytics.YOLO
┌────────────────────────────────────────────┐
│ YOLO11n 推理引擎                            │
│ model/best.pt(9 类病害 + 健康)             │
└────────────────────────────────────────────┘

YOLO11 网络结构(一图速通):

 输入 640×640
     │
 ┌───▼──── Backbone(C3k2 + SPPF) ────┐
 │   叶片纹理 / 斑点特征提取            │
 └───┬───────────────────────────────┘
     │
 ┌───▼──── Neck(FPN + PAN) ─────────┐
 │   斑点(小目标)+ 整叶(大目标)融合 │
 └───┬───────────────────────────────┘
     │
 ┌───▼── Head(Decoupled + DFL) ─────┐
 │   9 类分类 + DFL 边框回归          │
 └───┬───────────────────────────────┘
     │
   输出:N×(x1,y1,x2,y2,conf,病害类)

为什么选 YOLO11n:番茄病害的视觉特征横跨多尺度——红蜘蛛是叶背针尖大小的小点,叶霉病是大块黄斑,潜叶蛾是细长银白色潜道,DFL 回归能让边框对这些差异极大的目标都框得准;同时 5MB 级别权重适合下沉到田间 PAD/手机。

检测流程:

叶片图  ──▶ letterbox 640 ──▶ YOLO11n 推理
                                  │
                                  ▼
                        conf ≥ 0.25 + NMS(IoU 0.7)
                                  │
                                  ▼
                       result.plot() 画框
                                  │
                                  ▼
              查询 disease_info[类名] → 拼出"症状+建议+严重等级"

三、代码结构(核心 50 行)

# app/streamlit_app.py(节选)
from pathlib import Path
import streamlit as st, pandas as pd, yaml
from ultralytics import YOLO

ROOT       = Path(__file__).parent.parent
MODEL_PATH = ROOT / "model" / "best.pt"
CFG        = yaml.safe_load(open(ROOT / "configs" / "project.yaml", encoding="utf-8"))
DISEASE_DB = CFG["app"]["disease_info"]                  # ① 病害知识库
SEVERITY   = {"healthy": "🌿 健康", "mild": "🟢 轻度",
              "moderate": "🟠 中度", "severe": "🔴 重度"}

@st.cache_resource(show_spinner=False)
def load_model(p: str) -> YOLO:
    return YOLO(p)                                       # ② 权重只加载一次

def infer_image_path(model: YOLO, image_path: Path, conf: float):
    result = model.predict(str(image_path), conf=conf, verbose=False)[0]   # ③ 推理
    annotated = result.plot()
    rows = []
    if result.boxes is not None:
        for box in result.boxes:
            cls_id = int(box.cls.item())
            x1, y1, x2, y2 = [float(v) for v in box.xyxy[0].tolist()]
            rows.append({
                "class_name": result.names[cls_id],
                "confidence": round(float(box.conf.item()), 4),
                "x1": round(x1, 1), "y1": round(y1, 1),
                "x2": round(x2, 1), "y2": round(y2, 1),
            })
    return annotated[:, :, ::-1], pd.DataFrame(rows)     # ④ BGR→RGB + 结构化结果

def render_disease_info(class_names: list[str]) -> None:                   # ⑤ 防治知识
    for name in dict.fromkeys(class_names):              # 去重保序
        info = DISEASE_DB.get(name)
        if not info: continue
        sev = SEVERITY.get(info["severity"], "")
        st.markdown(f"### {info['icon']} {name}  {sev}")
        st.write(f"**症状**:{info['symptoms']}")
        st.write(f"**防治建议**:{info['advice']}")

# ---------- Streamlit 入口(单图分支) ----------
st.set_page_config(page_title=CFG["app"]["title"], layout="wide")
conf  = st.sidebar.slider("置信度阈值", 0.1, 0.9, 0.25, 0.05)
model = load_model(str(MODEL_PATH))

up = st.file_uploader("上传番茄叶片图片", type=["jpg", "jpeg", "png", "webp", "bmp"])
if up is not None:
    annotated, df = infer_image_path(model, Path(up.name), conf)
    st.image(annotated, caption="检测结果")
    st.dataframe(df)
    render_disease_info(df["class_name"].tolist())       # 拼出"症状 + 防治建议"

5 段解析:

  1. DISEASE_DB —— 9 类病害的"症状 + 严重程度 + 防治建议"全部从 yaml 配置注入,业务专家修订知识库不动一行 Python 代码。
  2. @st.cache_resource —— 把 YOLO 权重缓存到会话级,手机端浏览器刷新页面响应能从 ~2s 降到几十毫秒。
  3. model.predict(...)[0] —— ultralytics 标准一行调用,自动 letterbox、NMS。
  4. 把每个 box 拆成结构化记录,下游图表、CSV 导出、知识库联动统一基于这份 DataFrame。
  5. render_disease_info() —— 用检测到的类名查 DISEASE_DB,把图像分类升级成"病害体检报告"——这是和普通检测项目最大的差异点。

四、训练效果

模型基于 yolo11n.pt 在 5000 张番茄叶片图(覆盖 8 类病害 + 健康对照)上训练 200 个 epoch(实际收敛在 187 epoch 附近),imgsz=640、 batch =16。最终训练表现:

指标 数值
Precision 0.921
Recall 0.862
mAP@0.5 0.944
mAP@0.5:0.95 0.857

训练曲线总览:

训练结果总览

box / cls / dfl 三路损失稳定下降,mAP 在第 100 个 epoch 后已稳定在 0.94+ 水平;mAP@0.5:0.95 也有 0.86,说明病斑边框定位质量过关。

PR 曲线:

PR 曲线

PR 曲线在大部分 Recall 区间保持高 Precision——多数病害类别都能稳定召回;少量交叉类别(如早疫病 vs 斑枯病,斑点形态相近)会有可见的下降,符合视觉先验。

归一化混淆矩阵:

归一化混淆矩阵

对角线整体接近 1,主要混淆集中在"早疫病 ↔ 斑枯病""叶霉病 ↔ 早疫病"两组——它们在视觉上确实非常接近,下一步可以通过加入显微特写样本、边缘高分辨率裁剪进一步压平。

五、项目总结

做对了什么:

  • 从"分类"升级到"检测 + 知识库":识别完直接吐出"病在哪 + 多严重 + 怎么治",这是真正能塞给农户用的形态。
  • 数据构造合理:8 病 + 1 健康 + 5000 张样本,避开了只做单一病害带来的过拟合。
  • 轻量化前端:Streamlit + 配置驱动,没有花哨依赖,田间 PAD 浏览器直接跑,不需要部署原生 App。

还能怎么做:

  1. 加上"严重度回归"——同一种病按"轻/中/重"再细分,提高用药建议精度;
  2. 接入气象 / 棚内温湿度,辅助预测晚疫、灰霉等湿度敏感病害;
  3. 多作物迁移:同一套 YOLO11n 模板覆盖到黄瓜、辣椒、茄子等同科作物,复用 80% 代码与 UI。

一句话总结: 用 YOLO11n + Streamlit 把"番茄叶片诊病"做成一份带防治方案的体检报告,是 5MB 模型撬动十亩大棚的典型样例。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。