YOLOv8 土豆叶片病害图像分类系统介绍

YOLOv8 土豆叶片病害分类系统介绍

系统概述

基于 YOLOv8 (您提到的 YOLO11 可能是笔误,目前最新是 YOLOv8) 的土豆叶片病害分类系统是一个专门用于识别和分类土豆叶片常见病害的AI解决方案。该系统能够快速准确地识别多种土豆叶片病害,帮助农民和农业专家早期发现病害,及时采取防治措施。

支持的病害类型

典型的土豆叶片病害分类系统可以识别以下常见病害:

  1. 早疫病 (Early Blight) - 由 Alternaria solani 真菌引起
  2. 晚疫病 (Late Blight) - 由 Phytophthora infestans 引起
  3. **
  4. 健康叶片 (Healthy Leaves)
    在这里插入图片描述

技术实现

1. 模型选择

使用 YOLOv8 的分类模型 (YOLOv8n-cls, YOLOv8s-cls 等),而非检测模型,因为专注于整叶片的分类而非病灶定位。

from ultralytics import YOLO

# 加载自定义训练的分类模型
model = YOLO('potato_disease_cls.pt')  # 自定义训练的模型

2. 数据集准备

需要收集包含以下特征的图像数据集:

  • 各种光照条件下的土豆叶片图像
  • 不同生长阶段的叶片
  • 各种病害发展阶段的样本
  • 不同角度的拍摄

典型数据集结构:

dataset/
├── train/
│   ├── early_blight/
│   ├── late_blight/
│   ├── leaf_mold/
│   ├── bacterial_spot/
│   └── healthy/
├── val/
│   ├── ... (相同结构)
└── test/
    ├── ... (相同结构)

3. 模型训练

训练自定义分类模型的代码示例:

from ultralytics import YOLO

# 加载预训练模型
model = YOLO('yolov8n-cls.pt')  # 使用nano版本

# 训练模型
results = model.train(
    data='path/to/dataset',
    epochs=100,
    imgsz=640,
    batch=16,
    name='potato_disease_cls'
)

4. 系统集成

将训练好的模型集成到Streamlit界面中,针对土豆病害分类进行优化:

# 在Streamlit应用中的分类处理部分
def classify_potato_leaf(image):
    # 预处理图像
    img_np = np.array(image)
    
    # 执行分类
    results = model(img_np)
    
    # 获取土豆病害特定结果
    if hasattr(results[0], 'probs'):
        probs = results[0].probs.top5conf.tolist()
        classes = results[0].probs.top5
        class_names = [results[0].names[i] for i in classes]
        
        # 转换为易理解的病害名称
        disease_names = {
            'early_blight': '早疫病',
            'late_blight': '晚疫病',
            'leaf_mold': '叶霉病',
            'bacterial_spot': '细菌性斑点病',
            'healthy': '健康叶片'
        }
        
        predictions = []
        for name, prob in zip(class_names, probs):
            display_name = disease_names.get(name, name)
            predictions.append({
                "disease": display_name,
                "confidence": prob,
                "scientific_name": name
            })
        
        return predictions
    return []

系统功能增强

1. 病害诊断建议

可以在结果中添加针对每种病害的防治建议:

# 病害防治建议字典
TREATMENT_ADVICE = {
    '早疫病': '1. 使用含嘧菌酯的杀菌剂\n2. 轮作非茄科作物\n3. 移除感染植株',
    '晚疫病': '1. 使用铜基杀菌剂\n2. 确保良好通风\n3. 避免叶片夜间湿润',
    # 其他病害建议...
}

# 在结果显示中添加建议
for pred in predictions:
    advice = TREATMENT_ADVICE.get(pred['disease'], '暂无特定建议')
    st.markdown(f"**防治建议**: {advice}")

2. 病害严重程度评估

可以扩展系统评估病害严重程度:

def estimate_severity(image, disease_type):
    """粗略估计病害严重程度"""
    if disease_type == 'healthy':
        return "无病害"
    
    # 将图像转换为HSV色彩空间
    hsv = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2HSV)
    
    # 根据不同病害特征分析
    if disease_type in ['early_blight', 'late_blight']:
        # 分析褐色区域比例
        lower_brown = np.array([10, 50, 20])
        upper_brown = np.array([30, 255, 200])
        mask = cv2.inRange(hsv, lower_brown, upper_brown)
        affected_ratio = np.sum(mask > 0) / (image.size[0] * image.size[1])
        
        if affected_ratio < 0.1:
            return "轻微"
        elif affected_ratio < 0.3:
            return "中等"
        else:
            return "严重"
    # 其他病害的评估逻辑...

在这里插入图片描述

部署建议

  1. 移动端适配:添加响应式设计,方便田间使用手机访问
  2. 离线支持:考虑使用Streamlit打包为独立应用
  3. 定期更新:建立反馈机制持续改进模型
  4. 多语言支持:为不同地区农民提供本地化界面

性能优化

  1. 使用较小的模型版本 (如YOLOv8n-cls) 保证在边缘设备的运行速度
  2. 添加图像预处理步骤,增强田间拍摄图像的质量
  3. 实现批量处理功能,支持大面积田块的快速评估

这个专门针对土豆叶片病害的分类系统将传统农业知识与现代AI技术结合,为精准农业提供实用工具。

在这里插入图片描述

代码获取

import streamlit as st
from PIL import Image
import cv2
import numpy as np
from ultralytics import YOLO
import os
from datetime import datetime
import matplotlib.pyplot as plt
import plotly.express as px

# 设置页面配置
st.set_page_config(
    page_title="AI Vision Classifier",
    page_icon="🧠",
    layout="wide",
    initial_sidebar_state="expanded"
)

# 自定义CSS样式
st.markdown("""
<style>
    .stApp {
        background-color: #f5f5f5;
    }
    .sidebar .sidebar-content {
        background-color: #2c3e50;
        color: white;
    }
    h1 {
        color: #2c3e50;
    }
    .stButton>button {
        background-color: #3498db;
        color: white;
        border-radius: 5px;
        padding: 0.5rem 1rem;
        border: none;
    }
    .stFileUploader>div>div>div>div {
        color: #2c3e50;
    }
    .prediction-card {
        background-color: white;
        border-radius: 10px;
        padding: 1rem;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        margin-bottom: 1rem;
    }
    .confidence-bar {
        height: 20px;
        background: linear-gradient(90deg, #e74c3c, #f39c12, #2ecc71);
        border-radius: 10px;
        margin-top: 0.5rem;
    }
</style>
""", unsafe_allow_html=True)

# 加载模型
@st.cache_resource
def load_model():
    try:
        model = YOLO('yolov8n-cls.pt')  # 使用分类模型
        return model
    except Exception as e:
        st.error(f"加载模型失败: {e}")
        return None

model = load_model()

# 初始化session state
if 'history' not in st.session_state:
    st.session_state.history = []

# 侧边栏
with st.sidebar:
    st.title("⚙️ 设置")
    st.markdown("---")
    
    # 模型参数
    confidence_threshold = st.slider("置信度阈值", 0.0, 1.0, 0.5, 0.01)
    top_k = st.slider("显示前K个结果", 1, 10, 3)
    
    # 输入源选择
    input_source = st.radio("输入源", ["上传图片", "摄像头拍摄"])
    
    st.markdown("---")
    st.markdown("🛠️ 由AI Vision Lab开发")
    st.markdown("v1.0 | © 2023")

# 主界面
st.title("🧠 AI Vision 图像分类系统")
st.markdown("使用YOLOv8分类模型对图像进行智能分类")

# 根据输入源获取图像
img = None
if input_source == "上传图片":
    uploaded_file = st.file_uploader("上传图片", type=["jpg", "jpeg", "png"])
    if uploaded_file is not None:
        img = Image.open(uploaded_file)
        st.image(img, caption="上传的图片", use_column_width=True)
else:
    st.warning("注意: 使用摄像头功能需要在本地运行Streamlit")
    cam_img = st.camera_input("拍摄照片")
    if cam_img is not None:
        img = Image.open(cam_img)

# 处理图像
if img is not None and model is not None:
    # 转换图像格式
    img_np = np.array(img)
    
    # 显示处理中的状态
    with st.spinner("AI正在分析图像..."):
        # 执行分类
        results = model(img_np)
        
        # 获取分类结果
        if hasattr(results[0], 'probs'):  # 分类模型
            probs = results[0].probs.top5conf.tolist()
            top5_classes = results[0].probs.top5
            top5_names = [results[0].names[i] for i in top5_classes]
            
            # 创建结果字典
            predictions = []
            for name, prob in zip(top5_names, probs):
                if prob >= confidence_threshold:
                    predictions.append({"class": name, "confidence": prob})
            
            # 只保留前K个结果
            predictions = predictions[:top_k]
            
            # 保存到历史记录
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            st.session_state.history.append({
                "timestamp": timestamp,
                "image": img_np,
                "predictions": predictions
            })
            
            # 显示结果
            st.success("分析完成!")
            st.markdown("## 📊 分类结果")
            
            # 使用卡片式布局显示结果
            cols = st.columns(2)
            with cols[0]:
                st.image(img, caption="输入图像", use_column_width=True)
            
            with cols[1]:
                for pred in predictions:
                    with st.container():
                        st.markdown(f"### {pred['class']}")
                        st.markdown(f"置信度: {pred['confidence']:.2%}")
                        
                        # 自定义置信度条
                        confidence_percent = pred['confidence']
                        bar_color = "#2ecc71" if confidence_percent > 0.7 else "#f39c12" if confidence_percent > 0.4 else "#e74c3c"
                        st.markdown(f"""
                        <div style="width: 100%; background: #ecf0f1; border-radius: 10px;">
                            <div style="width: {confidence_percent*100}%; background: {bar_color}; 
                                        height: 20px; border-radius: 10px; text-align: center; 
                                        color: white; font-weight: bold;">
                                {confidence_percent:.0%}
                            </div>
                        </div>
                        """, unsafe_allow_html=True)
            
            # 可视化置信度分布
            st.markdown("## 📈 置信度分布")
            if len(predictions) > 0:
                fig = px.bar(
                    x=[p["class"] for p in predictions],
                    y=[p["confidence"] for p in predictions],
                    labels={"x": "类别", "y": "置信度"},
                    color=[p["confidence"] for p in predictions],
                    color_continuous_scale="Viridis"
                )
                st.plotly_chart(fig, use_container_width=True)
            
            # 显示历史记录
            if len(st.session_state.history) > 0:
                st.markdown("## 🕒 历史记录")
                history_cols = st.columns(3)
                for i, record in enumerate(st.session_state.history[-3:]):  # 只显示最近3条
                    with history_cols[i % 3]:
                        with st.expander(f"{record['timestamp']}"):
                            st.image(record["image"], use_column_width=True)
                            for pred in record["predictions"][:2]:  # 只显示前2个预测
                                st.markdown(f"**{pred['class']}**: {pred['confidence']:.2%}")
            
            # 添加下载结果按钮
            st.download_button(
                label="下载结果",
                data=f"分类结果:\n" + "\n".join([f"{p['class']}: {p['confidence']:.2%}" for p in predictions]),
                file_name="classification_results.txt",
                mime="text/plain"
            )

# 如果没有加载模型
elif model is None:
    st.error("模型加载失败,请检查模型路径或重新启动应用。")

# 应用说明
with st.expander("ℹ️ 使用说明"):
    st.markdown("""
    ### 如何使用这个AI图像分类器:
    1. 在左侧边栏选择输入源(上传图片或使用摄像头)
    2. 调整置信度阈值和显示结果数量
    3. 上传或拍摄照片
    4. 查看AI的分类结果和置信度
    
    ### 技术说明:
    - 使用Ultralytics YOLOv8分类模型
    - 支持1000个ImageNet类别
    - 结果按置信度排序
    
    ### 注意事项:
    - 对于最佳结果,请使用清晰的物体图像
    - 复杂场景可能需要调整置信度阈值
    """)
### 使用YOLOv8实现柑橘叶子疾病检测 #### 准备工作 为了使用YOLOv8进行柑橘叶片病害识别,需先准备相应的开发环境和数据集。进入`ultralytics-main/ultralytics/models/yolo/detect`文件夹可以找到YOLOv8的目标检测训练代码[^1]。 #### 数据收集与预处理 针对特定的应用场景——柑橘叶面疾病的检测,需要构建专门的数据集。这包括大量标注有健康状态或患病类型的柑橘叶片图像。每张图片应附带标签文件,描述其中存在的病变位置及其类别。这些数据用于模型的学习过程,以提高其对不同病症模式的理解能力。 #### 训练配置调整 在开始训练之前,可能还需要修改一些默认参数来更好地适配当前的任务需求。比如设置合适的输入尺寸、批量大小(batch size),以及定义新的分类列表等。对于柑橘叶子上的多种常见病虫害情况,应当确保自定义类别的准确性以便于后续分析。 ```python from ultralytics import YOLO model = YOLO('yolov8n.yaml') # 加载YOLOv8 nano版本或其他适合的预训练权重 ``` #### 开始训练 通过编写脚本调用上述路径下的API接口并指定好对应的超参选项即可启动整个流程: ```python results = model.train(data='path_to_custom_dataset', epochs=100, imgsz=640) ``` 这里假设已经准备好了一个名为`custom_dataset`的数据集合,并将其放置在一个可访问的位置上;同时设定了迭代次数为100次,单幅图像的最大边长设定为640像素。 #### 测试评估 完成一轮完整的训练周期之后,利用测试集中未见过的真实样本来验证最终成果的有效性和可靠性就显得尤为重要了。可以通过可视化工具直观展示预测框与实际标记之间的吻合程度,从而判断系统的性能表现。 ```python metrics = results.val() # 对验证集做一次推理计算mAP指标 print(metrics.box.map) # 输出平均精度均值MAP@.5:.95的结果 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值