news 2026/9/18 2:33:15

基于YOLOv11的农作物叶片分割与病虫害识别实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于YOLOv11的农作物叶片分割与病虫害识别实战

简介:这是一份面向计算机视觉开发者、农业科研人员及相关专业学生的YOLOv11实战开发指南,聚焦农作物叶片自动分割与病虫害识别场景。文档共44页,系统梳理了YOLO系列发展历程、YOLOv11网络结构、开发环境搭建、数据集标注与增强、模型训练与调优、分割与识别算法实现,以及系统集成、测试部署和农业应用案例,覆盖从环境准备到项目落地的完整流程。资源包中有1个pdf文件,大小2.27MB,文字、图表、目录显示完整,支持章节跳转和大纲快速定位,适合按需查阅。目前已有60人学习使用,可作为相关课程设计、毕业课题或农业智能化项目的重要参考资料,帮助初学者快速建立YOLOv11项目开发框架,也能为有经验的开发者提供算法优化与系统部署的实用思路。文档仅供学习参考,请勿用于商业用途。

1. 为什么是YOLOv11:叶片分割与识别的一体化选择

农作物病虫害检测长期以来依赖人工田间观察,不仅效率低,而且在大规模种植场景下很难做到及时预警。基于深度学习的自动识别系统可以把这项工作前置到图像端:先分割叶片区域,再识别病斑类型,最后输出位置和类别。YOLOv11 的思路是把目标检测当作单阶段回归问题,一次前向推理就能同时得到多个目标的边界框和分类概率,推理速度远快于两阶段检测器,这让它非常适合部署在无人机、移动端或边缘设备上做实时巡检。本文从一份 44 页的开发指南切入,梳理基于 YOLOv11 实现农作物叶片自动分割与病虫害识别的完整链路,包括网络结构、数据准备、模型训练、双任务实现和系统部署。文中涉及的命令和代码均基于 PyTorch 与 Ultralytics YOLOv11 环境,适合有初步深度学习基础、想快速落地农业视觉应用的工程师参考。

2. YOLOv11网络结构解析与训练超参调优

2.1 从Backbone到Head:YOLOv11的核心组件

YOLO 系列从 v1 到 v11,核心变化集中在骨干网络、特征融合和检测头三个部分。v11 延续了单阶段检测的思想,但在卷积模块上引入了深度可分离卷积与分组卷积的组合,在减少计算量的同时尽量保留特征表达能力。骨干网络负责从输入图像中提取多尺度特征,颈部网络将不同分辨率的特征图做自适应融合,检测头则在融合后的特征图上预测边界框和类别概率。

我在拆解这个项目时,最关注的是颈部网络的自适应特征融合机制。与 YOLOv8 的固定特征金字塔不同,v11 会为不同尺度的特征图生成一组注意力权重,让模型自动决定“小目标应该更依赖浅层特征还是深层特征”。下面是一段简化后的自适应融合模块示例,用于理解它的工作原理:

import torch import torch.nn as nn class AdaptiveFeatureFusion(nn.Module): def __init__(self, in_channels_list, out_channels): super().__init__() self.conv_list = nn.ModuleList([ nn.Conv2d(in_channels, out_channels, kernel_size=1) for in_channels in in_channels_list ]) self.attention = nn.Sequential( nn.Conv2d(len(in_channels_list) * out_channels, out_channels, kernel_size=1), nn.Sigmoid() ) def forward(self, feature_list): convs = [conv(feat) for conv, feat in zip(self.conv_list, feature_list)] concat = torch.cat(convs, dim=1) weights = self.attention(concat) # 将融合权重广播到每个尺度特征图 fused = sum(feat * weights for feat in convs) return fused

这段代码里,conv_list先把不同尺度的特征图统一到相同通道数,attention再用一个卷积层和 Sigmoid 生成逐通道权重。最后每个尺度的特征图都乘以同一组权重再相加,权重越大说明该尺度对当前任务越重要。实际训练时,这个模块会被插入到 FPN 的每一层输出之间,和原始检测头配合使用。

检测头部分,v11 采用多尺度预测,在三个不同分辨率的特征图上分别输出边界框和类别概率。针对农作物叶片这种目标大小差异明显的场景,多尺度预测能有效提升小叶片和重叠叶片的召回率。表 1 汇总了 YOLOv11 各主要组件的作用,方便和传统 CNN 分类器对比。

组件作用与叶片任务的关系
Backbone提取图像特征,逐层下采样叶片纹理、病斑边缘特征主要从浅层和中间层获得
Neck(自适应融合)融合多尺度特征,增强小目标响应解决叶片大小不一、密集遮挡问题
Head(多尺度预测)在不同特征图上回归框和类别同时识别病斑类别和叶片位置

2.2 训练命令与超参设置

在 Ultralytics 框架下,训练一个 YOLOv11 模型非常直接。我一般会把数据集放在dataset/目录下,结构遵循 YOLO 格式,然后执行下面的命令:

yolo detect train \ model=yolo11s.pt \ data=datasets/crop_leaf.yaml \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ lrf=0.01 \ optimizer=SGD \ device=0

参数说明:yolo11s.pt是官方提供的预训练权重,能用迁移学习加速收敛;imgsz控制输入大小,叶片任务里 640 是一个平衡速度和精度的值,如果小目标特别多,可以尝试 960;batch要根据显存调整,训练时观察显存占用,尽量不超过 90%;lr0是初始学习率,SGD 优化器通常配 0.01,Adam 则建议从 0.001 开始。

超参数方面,我整理了一份经过田间数据验证的参考范围,如表 2 所示。需要特别强调的是,不要一味增加数据增强强度,过度的旋转和裁剪会让叶片形态失真,导致模型在真实场景下的泛化能力下降,一般训练集和验证集分布差异大的时候,增强强度反而要低一些。

超参数推荐范围调整经验
imgsz640-960叶片目标小,增大输入尺寸有明显收益,但训练时间翻倍
lr00.01(SGD) / 0.001(Adam)学习率过大会导致loss震荡,过小会收敛缓慢
mosaic1.0能提升密集叶片场景的稳定性,但最后10轮建议关闭
hsv_h / hsv_s0.015 / 0.7适度调整色相饱和度,模拟不同光照
fliplr0.5水平翻转对叶片镜像对称特性是安全的

3. 数据集工程:从田间图像到YOLO格式的转换

3.1 数据收集与标注规范

数据集是这类农业视觉项目的最大瓶颈。公开数据集如 PlantVillage 虽然包含多种作物叶片,但真实田间环境下的复杂背景、光照变化和遮挡,是公开数据基本覆盖不到的。我通常建议用无人机或手机实地采集,一天可以拍几千张,关键是控制多样性:不同生长阶段、不同角度、不同天气条件都要纳入。数据收集时尽量让叶片占画面主体,不要引入过多的土壤和天空背景,否则模型会把背景纹理误学成叶片特征。

标注工具方面,LabelImg 对 YOLO 格式的支持比较成熟。安装和启动命令:

pip install labelImg labelImg

打开 LabelImg 后,先把图像目录和标签目录分别设置好,然后框选叶片或病斑区域,选择对应类别。标注规范上,我一般要求两个原则:一是叶片边缘要完全贴合目标,不能包含太多背景;二是对于重叠叶片,允许用多个框去覆盖,而不是试图画一个包含所有叶片的大框。YOLO 格式的标注文件是.txt,每一行对应一个目标,格式为class_index center_x center_y width height,数值都归一化到 0-1。比如0 0.512 0.433 0.286 0.215,表示类别 0,中心点归一化坐标和宽高。

3.2 数据增强与划分

采集到的原始图像不能直接全部丢进模型训练,需要先清洗低质量图片,再按比例划分训练集、验证集和测试集。我常用的划分比例是 8:1:1,划分后目录结构如下:

dataset/ ├── train/ │ ├── images/ │ └── labels/ ├── val/ │ ├── images/ │ └── labels/ └── test/ ├── images/ └── labels/

划分代码可以用 Python 的random.shuffle实现,但要注意保留原始文件名的对应关系。下面是一段常见的划分脚本:

import os import random import shutil image_dir = 'raw_images' label_dir = 'raw_labels' train_ratio, val_ratio = 0.8, 0.1 image_files = [f for f in os.listdir(image_dir) if f.endswith('.jpg')] random.shuffle(image_files) train_cnt = int(len(image_files) * train_ratio) val_cnt = int(len(image_files) * val_ratio) for i, img_name in enumerate(image_files): if i < train_cnt: split = 'train' elif i < train_cnt + val_cnt: split = 'val' else: split = 'test' os.makedirs(f'dataset/{split}/images', exist_ok=True) os.makedirs(f'dataset/{split}/labels', exist_ok=True) shutil.copy(f'{image_dir}/{img_name}', f'dataset/{split}/images/') label_name = img_name.replace('.jpg', '.txt') shutil.copy(f'{label_dir}/{label_name}', f'dataset/{split}/labels/')

划分完成后,还需要补充数据增强。Ultralytics 在训练时默认开启mosaichsv等在线增强,但你也可以离线生成增强样本。对于田间叶片图像,我比较依赖以下几种增强方式,表 3 列出了它们的参数范围和使用场景,增强后的样本建议先人工抽检几张,确认没有破坏叶片结构。

增强方式参数用途
随机旋转角度 ±15°模拟叶片自然朝向,但不要超过30°,否则背景占比过高
亮度对比亮度 0.8-1.2,对比度 0.9-1.1应对不同时段田间光照
高斯噪声方差 0.01-0.03增强模型对传感器噪声的鲁棒性
随机裁剪缩放 0.5-1.0模拟不同拍摄距离,但注意目标不要过小
MixUpalpha=0.2适合病斑类别样本不平衡时使用

4. 分割与识别双任务实现:U-Net与YOLOv11的配合

4.1 传统分割与深度学习分割的取舍

叶片分割的目标是把叶片区域从背景中分离出来。传统方法里,阈值分割最简单,利用叶片绿色与土壤棕色的颜色差异,在 HSV 空间设定绿色通道阈值即可。下面这段代码是用 OpenCV 实现的自适应阈值分割,适合快速验证颜色特征明显的叶片图像:

import cv2 import numpy as np image = cv2.imread('leaf_crop.jpg') hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 绿色范围是经验值,需要根据实际图像微调 lower_green = np.array([35, 40, 40]) upper_green = np.array([85, 255, 255]) mask = cv2.inRange(hsv, lower_green, upper_green) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((5,5), np.uint8)) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2) cv2.imwrite('leaf_segmentation_result.jpg', image)

这段代码先通过inRange筛选绿色像素,得到二值掩码,再通过开闭运算去除小噪点并连接断裂区域,最后用找轮廓拿到叶片外接矩形。参数lower_greenupper_green是 HSV 中绿色的范围,受光照影响明显,田间阴影下可能需要把V通道下限调低。

但传统分割的最大问题是泛化能力差。一旦出现枯黄叶片、病斑颜色改变或光线过强,固定阈值就会失效。深度学习方法里 U-Net 是经典选择,编码器逐层压缩特征,解码器通过跳跃连接恢复空间细节,对边界粗糙的叶片有较好的分割结果。表 4 列出了几种分割方法的优缺点,实际项目中我会先用一个轻量语义分割网络做叶片区域提取,再把结果区域送入 YOLOv11 做病虫害检测,形成两阶段链路。

方法优点局限
全局阈值分割实现简单、速度快光照变化大时分割不稳定
Canny 边缘检测能提取明显叶脉和轮廓对密集叶片会产生大量断裂边缘
U-Net 语义分割像素级精度高、边界平滑训练数据要求高,小数据集容易过拟合
YOLOv11 实例分割端到端输出掩码和框掩码质量取决于模型容量,推理成本更高

4.2 基于YOLOv11的病虫害识别与分割改进

处理病虫害识别时,我把 YOLOv11 当作一个强特征提取器,在它的检测头之上接入一个轻量分割分支,共享骨干网络的权重。这样训练时只需要一份标注数据,包含叶片框、分割掩码和病虫害类别。如果你想用 Ultralytics 提供的预训练权重,可以加载yolo11-seg.pt直接训练分割模型:

yolo segment train \ model=yolo11n-seg.pt \ data=crop_leaf_seg.yaml \ epochs=80 \ imgsz=640 \ batch=16

训练完成后,推理时的输出除了边界框,还会多一个分割掩码。我一般会在后处理里把掩码区域提取出来,统计病斑面积占叶片面积的比例,这个比例可以当作病虫害严重程度的量化指标。

from ultralytics import YOLO model = YOLO('best.pt') results = model.predict('field_image.jpg', conf=0.3, save=True) for result in results: if result.masks is not None: # masks.data 存储每个目标的二值掩码 for mask in result.masks.data: leaf_area = mask.sum().item() # 结合分类结果,进一步计算病斑占比 print(f'leaf pixel area: {leaf_area}')

这里的conf=0.3是置信度阈值,田间环境建议设置 0.3 到 0.5 之间,阈值太低会引入大量背景误检。分割掩码的像素面积可以归一到图像大小,作为后续绿植指数计算的基础。

5. 系统集成与测试:接口设计、性能瓶颈与排错

5.1 模块集成与推理服务

把训练好的模型集成成系统,我习惯用 FastAPI 包装一个推理接口。这个接口接收图像路径或二进制文件,返回叶片框、病虫害类别、置信度和分割掩码的 Base64 编码。下面的代码实现了一个最小可用的推理服务:

import base64 import cv2 import numpy as np from fastapi import FastAPI, UploadFile from ultralytics import YOLO app = FastAPI() model = YOLO('crop_leaf_seg.pt') @app.post('/predict') async def predict(file: UploadFile): image_bytes = await file.read() np_arr = np.frombuffer(image_bytes, np.uint8) img = cv2.imdecode(np_arr, cv2.IMREAD_COLOR) results = model.predict(img, conf=0.4) result = results[0] boxes = result.boxes.xyxy.tolist() classes = result.boxes.cls.tolist() confs = result.boxes.conf.tolist() # 将掩码转成 base64,方便前端或移动端直接渲染 if result.masks is not None: mask_bytes = result.masks.data.cpu().numpy().astype(np.uint8) mask_base64 = base64.b64encode(mask_bytes.tobytes()).decode() else: mask_base64 = None return { 'boxes': boxes, 'classes': classes, 'confidences': confs, 'mask_base64': mask_base64, 'num_targets': len(boxes) }

这个接口的关键点是图像解码和掩码序列化。cv2.imdecode用于处理上传的图片字节流,避免直接写临时文件;mask_base64把掩码数据打包成字符串,方便网络传输。实际生产环境还需要加一个预处理步骤,把图片缩放到模型输入尺寸之前保持横纵比不变,否则会引入形变。

5.2 性能瓶颈与排错

系统集成后,首先要测的是单请求推理耗时。在 GPU 上 YOLOv11s 对 640x640 图像的推理时长通常为几毫秒到十几毫秒,但如果部署在 CPU 上,耗时会涨到几百毫秒,这时就需要做模型量化和批处理。Ultralytics 提供了导出接口,可以直接导出 FP16 或 INT8 的 TensorRT 引擎:

yolo export model=best.pt format=engine device=0 half=True

导出后推理速度提升明显,但要注意 INT8 量化可能让叶片和病斑这类小目标的精度下降几个点。表 5 是功能测试时需要覆盖的用例,以及对应的验证点。

测试模块测试输入预期结果
叶片分割单张含背景的叶片图像分割掩码只覆盖叶片区域,不包含土壤
病虫害识别同时含健康和病害叶片的图像正确框出病害位置,类别准确
批量推理连续上传 100 张图像内存稳定,无溢出,平均耗时符合要求
异常输入全黑图像 / 非作物图像返回空框或给出低置信度,不崩溃

排错时最常见的坑是图像通道顺序。OpenCV 默认 BGR,而 Ultralytics 内部使用 RGB,如果直接用cv2.imread读取图像并喂给模型,颜色会混乱,导致病害识别率大幅下降。正确的做法是使用模型预测时传入文件路径,或者显式转换通道顺序以后再调用。

6. 实用技巧:小目标叶片检测的优化与推理结果保存

小目标检测是叶片分割项目里最让人头疼的部分。无人机俯拍时,单片叶子可能只有十几个像素,YOLOv11 默认的 640 输入尺寸很容易丢失这些细节。我常用的优化手段有三个:一是将imgsz提升到 960,虽然训练时间增加约一倍,但小目标召回率通常能提升 5-8 个百分点;二是打开 YOLOv11 的sa(自注意力)模块,在检测头之前增加对局部区域的关注;三是调整类别平衡损失权重,让模型更重视小目标类别。

推理阶段,除了保存标注图片,我还会把结构化结果写成 JSON,方便后续统计和展示。下面是一段结果保存代码:

import json from ultralytics import YOLO model = YOLO('best.pt') results = model('test_image.jpg', conf=0.35) output = [] for result in results: boxes = result.boxes.xyxy.cpu().numpy().tolist() classes = result.boxes.cls.cpu().numpy().astype(int).tolist() confs = result.boxes.conf.cpu().numpy().tolist() for box, cls, conf in zip(boxes, classes, confs): output.append({ "bbox": box, "class_id": cls, "confidence": round(conf, 4) }) # 保存为 json 文件,文件名和图像名保持对应 with open('result.json', 'w', encoding='utf-8') as f: json.dump({"detections": output}, f, ensure_ascii=False, indent=2)

这份 JSON 既可以直接送进数据库,也可以用于后续生成田间病虫害热力图。需要注意,如果输出掩码,建议把掩码存储为 RLE 编码的字符串而不是原始数组,不然 JSON 文件会非常大。针对叶片的实际应用里,我更推荐把confidence阈值和分割面积阈值一起写入配置,便于不同任务场景下切换。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 2:32:49

Tempo 与 Wagmi 集成实战:在 React/Core 中接入 Tempo L1 支付链

Tempo 与 Wagmi 集成实战&#xff1a;在 React/Core 中接入 Tempo L1 支付链 【免费下载链接】wagmi Reactive primitives for Ethereum apps 项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi Tempo 是一条为支付场景量身定制的 Layer 1 区块链&#xff0c;将代…

作者头像 李华
网站建设 2026/9/18 2:32:47

腾讯为什么开源蓝鲸PaaS?blueking-paas背后的企业级SaaS平台故事

腾讯为什么开源蓝鲸PaaS&#xff1f;blueking-paas背后的企业级SaaS平台故事 【免费下载链接】blueking-paas 蓝鲸智云 PaaS 平台是一个开放式的开发平台&#xff0c;让开发者可以方便快捷地创建、开发、部署和管理 SaaS 应用。它提供了完善的前后台开发框架、服务总线&#xf…

作者头像 李华
网站建设 2026/9/18 2:32:14

5分钟上手Pixelle-Video:AI短视频自动生成完整教程

5分钟上手Pixelle-Video&#xff1a;AI短视频自动生成完整教程 【免费下载链接】Pixelle-Video &#x1f680; AI 全自动短视频引擎 | AI Fully Automated Short Video Engine 项目地址: https://gitcode.com/GitHub_Trending/pi/Pixelle-Video 做短视频最劝退的环节不是…

作者头像 李华
网站建设 2026/9/18 2:28:48

OpenHarmony上Flutter渲染SVG图片的完整实践指南

去年年底我接到一个需求&#xff0c;要在 OpenHarmony 的板子上跑一套 Flutter 应用&#xff0c;里面图标、插画、启动背景全是 SVG 素材。试了一圈发现&#xff0c;网上讲 Flutter 渲染 SVG 的文章很多&#xff0c;但专门针对 OpenHarmony 这个宿主系统的少之又少&#xff0c;…

作者头像 李华
网站建设 2026/9/18 2:28:23

小样本图像分类实战:PIL实现亮度对比度翻转旋转数据增强

简介&#xff1a;对于深度学习初学者和面临小样本图像分类问题的开发者&#xff0c;这份PDF资料提供了一套可直接落地的数据集扩充方案。资源围绕图像亮度增强、对比度增强、水平翻转与随机方向旋转四种经典变换&#xff0c;结合PIL库给出完整Python实现&#xff0c;演示如何将…

作者头像 李华