YOLOv5农业病害检测案例:田间图像识别部署全流程

1. 引言:当AI走进田间地头

想象一下,你是一位农业技术员,每天需要巡视上百亩的农田,用肉眼检查作物是否生病。这不仅耗时耗力,而且容易因为疲劳或经验不足而漏判、误判。现在,有一种技术可以帮你解决这个问题——让AI自动识别作物病害。

这就是我们今天要聊的YOLOv5在农业病害检测上的应用。你可能听说过YOLO(You Only Look Once),它是一种非常厉害的图像识别技术,简单来说就是“看一眼就知道”。而YOLOv5是它的第五个版本,速度更快、精度更高,特别适合用在农业这种需要快速、准确判断的场景。

本文将带你从零开始,完成一个完整的农业病害检测项目部署。即使你之前没接触过深度学习,也能跟着步骤一步步实现。我们会用真实的田间图像作为例子,让你看到AI是如何识别作物病害的。

2. 准备工作:环境搭建与数据准备

2.1 快速部署YOLOv5环境

首先,我们需要一个能运行YOLOv5的环境。这里推荐使用预配置好的镜像,可以省去很多安装配置的麻烦。

方法一:使用Jupyter Notebook(推荐给新手)

如果你不熟悉命令行操作,Jupyter Notebook是个很好的选择。它提供了一个网页界面,你可以在浏览器里直接写代码、运行代码,就像在用记事本一样简单。

  1. 启动环境后,打开浏览器
  2. 输入提供的地址(通常是类似http://你的IP地址:8888这样的格式)
  3. 输入密码(如果有的话)
  4. 就能看到一个文件管理界面,在这里可以创建新的Notebook文件

方法二:使用SSH连接(适合有一定经验的朋友)

如果你习惯用命令行,可以通过SSH连接到服务器:

  1. 打开你的终端(Windows用户可以用PowerShell或CMD)
  2. 输入:ssh 用户名@服务器地址
  3. 输入密码
  4. 连接成功后,你就进入了一个Linux环境

无论用哪种方式,我们的目标都是进入一个已经预装好YOLOv5的环境。这个环境里包含了所有需要的软件和库,你不需要自己安装Python、PyTorch这些复杂的东西。

2.2 准备农业病害图像数据

AI就像学生,需要通过学习才能识别东西。我们要给它准备“教材”——也就是带有病害标注的图像数据。

从哪里获取数据?

  1. 公开数据集:网上有一些免费的农业病害数据集,比如PlantVillage、AI Challenger等
  2. 自己拍摄:如果你有实际的农田,可以用手机或相机拍摄作物照片
  3. 合作获取:有些农业科研机构会分享数据

数据需要什么样的格式?

YOLOv5需要两种文件:

  • 图像文件:.jpg.png格式的图片
  • 标注文件:.txt文件,记录图片里病害的位置和类型

标注文件的内容看起来像这样:

0 0.5 0.5 0.3 0.3
1 0.2 0.7 0.2 0.2

每一行代表一个病害区域,数字代表病害类型,后面的四个数字代表位置和大小。

数据预处理小技巧:

  • 统一尺寸:把所有图片调整到相同大小,比如640x640像素
  • 数据增强:可以通过旋转、翻转、调整亮度等方式,让数据量“变多”
  • 划分数据集:把数据分成三部分:
    • 训练集(70%):用来教AI识别病害
    • 验证集(20%):用来检查学习效果
    • 测试集(10%):最终考试,看AI学得怎么样

3. 模型训练:教AI识别作物病害

3.1 快速上手:运行第一个训练

现在环境准备好了,数据也准备好了,我们可以开始训练模型了。别担心,代码很简单。

首先,进入YOLOv5的目录:

cd /root/yolov5/

然后创建一个简单的训练脚本train.py

import torch
import yaml
from pathlib import Path

# 1. 设置数据路径
data_yaml = """
path: /root/agriculture_data  # 数据所在目录
train: images/train  # 训练集图片路径
val: images/val      # 验证集图片路径

# 病害类别
names:
  0: leaf_blight    # 叶枯病
  1: powdery_mildew # 白粉病
  2: rust           # 锈病
  3: healthy        # 健康叶片
"""

# 保存数据配置文件
with open('agriculture.yaml', 'w') as f:
    f.write(data_yaml)

# 2. 开始训练
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)

# 训练参数设置
args = {
    'data': 'agriculture.yaml',      # 数据配置文件
    'epochs': 50,                    # 训练轮数
    'batch-size': 16,                # 每次处理的图片数量
    'img-size': 640,                 # 图片大小
    'device': '0',                   # 使用GPU(如果是CPU就写'cpu')
    'workers': 4,                    # 数据加载线程数
    'name': 'agriculture_disease'    # 实验名称
}

# 开始训练!
results = model.train(**args)
print("训练完成!")

运行这个脚本:

python train.py

训练过程可能需要一些时间(从几十分钟到几小时不等,取决于数据量和电脑性能)。你可以看到屏幕上不断输出训练进度和效果指标。

3.2 理解训练过程:AI是怎么学习的

你可能好奇,训练过程中那些数字是什么意思?我来简单解释一下:

  • Epoch:训练轮数。就像学生复习功课,一遍遍看同样的内容
  • Loss:损失值。表示AI预测的结果和真实答案的差距,这个值越小越好
  • mAP:平均精度。这是衡量识别准确度的主要指标,值越高说明识别越准
  • Precision:精确率。识别出来的病害中,有多少是真正的病害
  • Recall:召回率。所有真正的病害中,有多少被识别出来了

训练时要注意什么?

  1. 观察Loss曲线:正常情况下,Loss应该逐渐下降然后稳定。如果一直波动很大,可能需要调整学习率
  2. 关注mAP值:训练后期,mAP应该稳定在一个较高的值(比如0.8以上)
  3. 防止过拟合:如果训练集上效果很好,但验证集上效果差,说明模型“死记硬背”了训练数据,没有真正学会。可以通过数据增强、减少训练轮数来解决

3.3 模型选择:用哪个版本的YOLOv5?

YOLOv5有多个版本,就像手机有不同的型号:

模型版本特点适合场景速度精度
YOLOv5n最轻量手机、嵌入式设备⚡⚡⚡⚡⚡⭐⭐
YOLOv5s小型普通电脑、快速检测⚡⚡⚡⚡⭐⭐⭐
YOLOv5m中型平衡速度与精度⚡⚡⚡⭐⭐⭐⭐
YOLOv5l大型高精度要求场景⚡⚡⭐⭐⭐⭐⭐
YOLOv5x超大型科研、竞赛⭐⭐⭐⭐⭐

对于农业病害检测,我的建议是:

  • 如果要在手机上或田间设备上运行,选YOLOv5nYOLOv5s
  • 如果在服务器或高性能电脑上运行,选YOLOv5mYOLOv5l
  • 刚开始尝试时,用YOLOv5s,训练快,效果也不错

4. 实际应用:在田间部署病害检测系统

4.1 模型测试:看看AI学得怎么样

训练完成后,我们需要测试模型的实际效果。创建一个测试脚本test.py

import torch
from PIL import Image
import matplotlib.pyplot as plt

# 加载训练好的模型
model = torch.hub.load('ultralytics/yolov5', 'custom', 
                      path='runs/train/agriculture_disease/weights/best.pt')

# 测试单张图片
img_path = "test_image.jpg"  # 替换为你的测试图片路径
results = model(img_path)

# 显示结果
results.show()  # 弹出窗口显示识别结果
results.save()  # 保存结果图片到runs/detect/exp

# 打印详细信息
print("识别结果:")
print(results.pandas().xyxy[0])  # 用表格形式显示结果

# 统计病害数量
detections = results.pandas().xyxy[0]
disease_count = len(detections[detections['name'] != 'healthy'])
print(f"\n检测到病害数量:{disease_count}")
print(f"病害类型分布:")
print(detections['name'].value_counts())

运行测试:

python test.py

你会看到图片上出现了方框,标出了病害的位置和类型。方框旁边的数字是置信度,表示AI对这个判断的把握程度(0-1之间,越接近1把握越大)。

4.2 批量处理:一次检测多张图片

在实际应用中,我们可能需要一次处理很多张图片。YOLOv5支持批量处理,非常方便:

import torch
import glob

# 加载模型
model = torch.hub.load('ultralytics/yolov5', 'custom',
                      path='runs/train/agriculture_disease/weights/best.pt')

# 获取所有待检测图片
image_files = glob.glob("/path/to/field_images/*.jpg")  # 修改为你的图片路径

# 批量检测
results = model(image_files)

# 保存所有结果
results.save()

# 生成检测报告
for i, result in enumerate(results):
    detections = result.pandas().xyxy[0]
    disease_count = len(detections[detections['name'] != 'healthy'])
    
    print(f"图片 {image_files[i]}:")
    print(f"  检测到病害区域:{disease_count}个")
    if disease_count > 0:
        print(f"  病害类型:{', '.join(detections[detections['name'] != 'healthy']['name'].unique())}")
    print()

4.3 部署到实际环境:几种实用方案

方案一:Web应用(适合农技人员使用)

用Flask或FastAPI搭建一个简单的网页应用:

# app.py
from flask import Flask, request, jsonify, render_template
import torch
from PIL import Image
import io

app = Flask(__name__)

# 加载模型
model = torch.hub.load('ultralytics/yolov5', 'custom',
                      path='runs/train/agriculture_disease/weights/best.pt')

@app.route('/')
def index():
    return render_template('index.html')  # 上传页面

@app.route('/detect', methods=['POST'])
def detect():
    if 'file' not in request.files:
        return jsonify({'error': '没有上传文件'})
    
    file = request.files['file']
    img = Image.open(io.BytesIO(file.read()))
    
    # 检测
    results = model(img)
    
    # 处理结果
    detections = results.pandas().xyxy[0]
    disease_info = []
    
    for _, row in detections.iterrows():
        if row['name'] != 'healthy':
            disease_info.append({
                'disease': row['name'],
                'confidence': float(row['confidence']),
                'position': {
                    'x1': int(row['xmin']),
                    'y1': int(row['ymin']),
                    'x2': int(row['xmax']),
                    'y2': int(row['ymax'])
                }
            })
    
    return jsonify({
        'image_size': img.size,
        'disease_count': len(disease_info),
        'diseases': disease_info,
        'result_image': results.render()[0].tolist()  # 处理后的图片
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

运行后,在浏览器打开http://服务器地址:5000,就能上传图片进行检测了。

方案二:移动端应用(适合田间实地使用)

可以将模型转换为ONNX或TensorFlow Lite格式,部署到手机APP上:

# 转换为ONNX格式
import torch

model = torch.hub.load('ultralytics/yolov5', 'custom',
                      path='runs/train/agriculture_disease/weights/best.pt')

# 导出为ONNX
dummy_input = torch.randn(1, 3, 640, 640)
torch.onnx.export(model.model, dummy_input, "agriculture_model.onnx",
                  input_names=['images'], output_names=['output'])

方案三:边缘设备部署(适合固定监测点)

使用树莓派或Jetson Nano等设备,实现24小时不间断监测:

# raspberry_pi_detection.py
import cv2
import torch
import time
from datetime import datetime

# 初始化摄像头
camera = cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 640)

# 加载模型(使用轻量版)
model = torch.hub.load('ultralytics/yolov5', 'custom',
                      path='runs/train/agriculture_disease/weights/best.pt')

print("开始监测...按q键退出")

while True:
    ret, frame = camera.read()
    if not ret:
        break
    
    # 检测
    results = model(frame)
    
    # 显示结果
    annotated_frame = results.render()[0]
    cv2.imshow('病害监测', annotated_frame)
    
    # 如果有病害,保存图片并记录
    detections = results.pandas().xyxy[0]
    if len(detections[detections['name'] != 'healthy']) > 0:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        cv2.imwrite(f"disease_detected_{timestamp}.jpg", annotated_frame)
        print(f"[{timestamp}] 检测到病害!")
    
    # 每5秒检测一次
    time.sleep(5)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

camera.release()
cv2.destroyAllWindows()

5. 优化与提升:让检测更准更快

5.1 数据质量提升:好数据决定好模型

常见问题及解决方法:

  1. 图片模糊或光线不好

    • 解决方法:使用图像增强技术
    import cv2
    import numpy as np
    
    def enhance_image(image):
        # 调整对比度
        alpha = 1.5  # 对比度系数
        beta = 10    # 亮度调整
        enhanced = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
        
        # 锐化
        kernel = np.array([[-1,-1,-1],
                          [-1, 9,-1],
                          [-1,-1,-1]])
        sharpened = cv2.filter2D(enhanced, -1, kernel)
        
        return sharpened
    
  2. 病害样本太少

    • 解决方法:使用数据增强
    import albumentations as A
    
    transform = A.Compose([
        A.RandomRotate90(p=0.5),      # 随机旋转
        A.Flip(p=0.5),                # 随机翻转
        A.RandomBrightnessContrast(p=0.2),  # 随机亮度对比度
        A.HueSaturationValue(p=0.2),  # 随机色相饱和度
        A.RandomResizedCrop(640, 640, scale=(0.8, 1.0)),  # 随机裁剪
    ])
    

5.2 模型优化技巧:提升检测效果

技巧一:调整检测阈值

# 创建模型时调整置信度阈值
model = torch.hub.load('ultralytics/yolov5', 'custom',
                      path='模型路径',
                      conf_thres=0.25,  # 置信度阈值,默认0.25
                      iou_thres=0.45)   # IOU阈值,默认0.45

# 或者运行时调整
results = model(img, conf_thres=0.3)  # 提高阈值,减少误检

技巧二:使用集成学习

# 加载多个模型,综合判断
model1 = torch.hub.load('ultralytics/yolov5', 'custom', path='model1.pt')
model2 = torch.hub.load('ultralytics/yolov5', 'custom', path='model2.pt')

results1 = model1(img)
results2 = model2(img)

# 合并结果(简单示例)
def merge_results(r1, r2):
    # 这里可以实现更复杂的合并逻辑
    merged = r1 if len(r1) > len(r2) else r2
    return merged

技巧三:后处理优化

def post_process(results, min_area=100, max_area=10000):
    """过滤掉面积过大或过小的检测框"""
    detections = results.pandas().xyxy[0]
    
    filtered = []
    for _, row in detections.iterrows():
        width = row['xmax'] - row['xmin']
        height = row['ymax'] - row['ymin']
        area = width * height
        
        if min_area <= area <= max_area:
            filtered.append(row)
    
    return filtered

5.3 性能优化:让检测更快

方法一:减小输入尺寸

# 使用更小的图片尺寸
results = model(img, size=320)  # 默认640,改为320可以更快

方法二:量化模型

# 模型量化,减少内存占用和计算量
quantized_model = torch.quantization.quantize_dynamic(
    model, {torch.nn.Linear}, dtype=torch.qint8
)

方法三:使用半精度浮点数

# 使用FP16精度,速度更快,内存占用更少
model.half()  # 转换为半精度
results = model(img.half() if img.is_cuda else img)

6. 实际案例:番茄病害检测系统

让我们看一个完整的实际案例——番茄病害检测系统。

6.1 项目背景

某番茄种植基地面临以下问题:

  • 种植面积大(500亩),人工巡检困难
  • 病害发现不及时,经常扩散后才处理
  • 不同技术员判断标准不一,误判率高

6.2 解决方案实施

第一步:数据收集

  • 收集了3000张番茄叶片图片
  • 标注了4种常见病害:早疫病、晚疫病、白粉病、叶霉病
  • 同时标注健康叶片作为对照

第二步:模型训练

# 训练配置
training_config = {
    'data': 'tomato_disease.yaml',
    'epochs': 100,
    'batch_size': 32,
    'img_size': 640,
    'model': 'yolov5m',  # 使用中型模型
    'patience': 20,  # 早停策略,防止过拟合
    'optimizer': 'AdamW',
    'lr0': 0.01,  # 初始学习率
}

第三步:部署应用

# 完整的田间监测系统
class TomatoDiseaseMonitor:
    def __init__(self, model_path):
        self.model = torch.hub.load('ultralytics/yolov5', 'custom', path=model_path)
        self.disease_history = []  # 记录病害历史
        
    def monitor_field(self, image_source):
        """监测整个田块"""
        if isinstance(image_source, str):
            # 如果是图片路径
            results = self.model(image_source)
        else:
            # 如果是摄像头
            results = self.model(image_source)
        
        return self.analyze_results(results)
    
    def analyze_results(self, results):
        """分析检测结果"""
        detections = results.pandas().xyxy[0]
        
        analysis = {
            'total_detections': len(detections),
            'disease_count': len(detections[detections['name'] != 'healthy']),
            'disease_types': {},
            'severity': 'low'  # 病害严重程度
        }
        
        # 统计各类病害数量
        for disease in detections['name'].unique():
            count = len(detections[detections['name'] == disease])
            analysis['disease_types'][disease] = count
        
        # 判断严重程度
        disease_ratio = analysis['disease_count'] / max(analysis['total_detections'], 1)
        if disease_ratio > 0.3:
            analysis['severity'] = 'high'
            analysis['recommendation'] = '立即处理!病害严重'
        elif disease_ratio > 0.1:
            analysis['severity'] = 'medium'
            analysis['recommendation'] = '建议近期处理'
        else:
            analysis['severity'] = 'low'
            analysis['recommendation'] = '定期观察即可'
        
        # 记录到历史
        self.disease_history.append({
            'timestamp': datetime.now(),
            'analysis': analysis
        })
        
        return analysis
    
    def generate_report(self, days=7):
        """生成病害趋势报告"""
        recent_history = self.disease_history[-days*24:]  # 最近N天的数据
        
        if not recent_history:
            return "暂无数据"
        
        report = f"最近{days}天病害监测报告\n"
        report += "="*40 + "\n"
        
        # 统计趋势
        daily_counts = {}
        for record in recent_history:
            date = record['timestamp'].strftime("%Y-%m-%d")
            if date not in daily_counts:
                daily_counts[date] = []
            daily_counts[date].append(record['analysis']['disease_count'])
        
        for date, counts in daily_counts.items():
            avg_count = sum(counts) / len(counts)
            report += f"{date}: 平均每天检测到{avg_count:.1f}处病害\n"
        
        return report

6.3 实施效果

经过3个月的运行,该系统取得了显著效果:

  1. 效率提升

    • 巡检时间从每天8小时减少到2小时
    • 病害发现时间平均提前5-7天
  2. 准确率提升

    • 病害识别准确率达到92%
    • 误判率从人工的15%降低到3%
  3. 经济效益

    • 减少农药使用量约30%
    • 提高产量约15%
    • 年节省人工成本约20万元

7. 总结与展望

7.1 关键要点回顾

通过这个完整的农业病害检测项目,我们学到了:

  1. 环境搭建很简单:使用预配置的镜像,几分钟就能准备好开发环境
  2. 数据是核心:好的标注数据决定了模型的上限,农业图像要特别注意光照、角度、背景的影响
  3. 训练需要耐心:不要指望一次训练就能得到完美模型,需要多次调整参数
  4. 部署要实用:根据实际场景选择部署方式,田间使用要考虑设备性能和网络条件
  5. 持续优化很重要:模型上线后还要不断收集新数据,持续优化

7.2 实际应用建议

如果你要在自己的农场或项目中应用这个技术:

起步阶段(小规模试验)

  • 先用手机拍摄100-200张作物图片
  • 使用YOLOv5s模型快速训练一个基础版本
  • 在少量作物上测试效果

扩展阶段(中等规模)

  • 建立系统的数据采集流程
  • 训练更精确的模型(YOLOv5m或YOLOv5l)
  • 开发简单的Web界面供技术人员使用

成熟阶段(大规模应用)

  • 部署到边缘设备,实现24小时监测
  • 与农业物联网系统集成
  • 建立病害预警和决策支持系统

7.3 未来发展方向

农业AI检测技术还在快速发展,未来可能会有这些变化:

  1. 多模态检测:结合图像、光谱、气象等多维度数据
  2. 实时预警系统:不仅检测病害,还能预测扩散趋势
  3. 自动化处理:与无人机、机器人结合,实现自动施药
  4. 知识图谱:建立作物病害知识库,提供处理建议

7.4 开始你的第一个项目

如果你现在就想开始,我建议:

  1. 从简单的开始:先选一种作物、一种病害
  2. 用公开数据练手:网上有很多农业数据集,可以先用来熟悉流程
  3. 小步快跑:不要追求完美,先做出能用的版本,再慢慢优化
  4. 结合实际需求:多和农业技术人员交流,了解真实需求

记住,技术是为业务服务的。最好的AI系统不是技术最先进的,而是最能解决实际问题的。从一个小点切入,解决一个具体问题,你就能看到AI给农业带来的真实价值。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

更多推荐