
简介这是一份面向计算机视觉开发者、农业科研人员及相关专业学生的YOLOv11实战开发指南聚焦农作物叶片自动分割与病虫害识别场景。文档共44页系统梳理了YOLO系列发展历程、YOLOv11网络结构、开发环境搭建、数据集标注与增强、模型训练与调优、分割与识别算法实现以及系统集成、测试部署和农业应用案例覆盖从环境准备到项目落地的完整流程。资源包中有1个pdf文件大小2.27MB文字、图表、目录显示完整支持章节跳转和大纲快速定位适合按需查阅。目前已有60人学习使用可作为相关课程设计、毕业课题或农业智能化项目的重要参考资料帮助初学者快速建立YOLOv11项目开发框架也能为有经验的开发者提供算法优化与系统部署的实用思路。文档仅供学习参考请勿用于商业用途。1. 为什么是YOLOv11叶片分割与识别的一体化选择农作物病虫害检测长期以来依赖人工田间观察不仅效率低而且在大规模种植场景下很难做到及时预警。基于深度学习的自动识别系统可以把这项工作前置到图像端先分割叶片区域再识别病斑类型最后输出位置和类别。YOLOv11 的思路是把目标检测当作单阶段回归问题一次前向推理就能同时得到多个目标的边界框和分类概率推理速度远快于两阶段检测器这让它非常适合部署在无人机、移动端或边缘设备上做实时巡检。本文从一份 44 页的开发指南切入梳理基于 YOLOv11 实现农作物叶片自动分割与病虫害识别的完整链路包括网络结构、数据准备、模型训练、双任务实现和系统部署。文中涉及的命令和代码均基于 PyTorch 与 Ultralytics YOLOv11 环境适合有初步深度学习基础、想快速落地农业视觉应用的工程师参考。2. YOLOv11网络结构解析与训练超参调优2.1 从Backbone到HeadYOLOv11的核心组件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_size1) for in_channels in in_channels_list ]) self.attention nn.Sequential( nn.Conv2d(len(in_channels_list) * out_channels, out_channels, kernel_size1), nn.Sigmoid() ) def forward(self, feature_list): convs [conv(feat) for conv, feat in zip(self.conv_list, feature_list)] concat torch.cat(convs, dim1) 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 \ modelyolo11s.pt \ datadatasets/crop_leaf.yaml \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ optimizerSGD \ device0参数说明yolo11s.pt是官方提供的预训练权重能用迁移学习加速收敛imgsz控制输入大小叶片任务里 640 是一个平衡速度和精度的值如果小目标特别多可以尝试 960batch要根据显存调整训练时观察显存占用尽量不超过 90%lr0是初始学习率SGD 优化器通常配 0.01Adam 则建议从 0.001 开始。超参数方面我整理了一份经过田间数据验证的参考范围如表 2 所示。需要特别强调的是不要一味增加数据增强强度过度的旋转和裁剪会让叶片形态失真导致模型在真实场景下的泛化能力下降一般训练集和验证集分布差异大的时候增强强度反而要低一些。超参数推荐范围调整经验imgsz640-960叶片目标小增大输入尺寸有明显收益但训练时间翻倍lr00.01SGD / 0.001Adam学习率过大会导致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(fdataset/{split}/images, exist_okTrue) os.makedirs(fdataset/{split}/labels, exist_okTrue) shutil.copy(f{image_dir}/{img_name}, fdataset/{split}/images/) label_name img_name.replace(.jpg, .txt) shutil.copy(f{label_dir}/{label_name}, fdataset/{split}/labels/)划分完成后还需要补充数据增强。Ultralytics 在训练时默认开启mosaic、hsv等在线增强但你也可以离线生成增强样本。对于田间叶片图像我比较依赖以下几种增强方式表 3 列出了它们的参数范围和使用场景增强后的样本建议先人工抽检几张确认没有破坏叶片结构。增强方式参数用途随机旋转角度 ±15°模拟叶片自然朝向但不要超过30°否则背景占比过高亮度对比亮度 0.8-1.2对比度 0.9-1.1应对不同时段田间光照高斯噪声方差 0.01-0.03增强模型对传感器噪声的鲁棒性随机裁剪缩放 0.5-1.0模拟不同拍摄距离但注意目标不要过小MixUpalpha0.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), (xw, yh), (0, 255, 0), 2) cv2.imwrite(leaf_segmentation_result.jpg, image)这段代码先通过inRange筛选绿色像素得到二值掩码再通过开闭运算去除小噪点并连接断裂区域最后用找轮廓拿到叶片外接矩形。参数lower_green和upper_green是 HSV 中绿色的范围受光照影响明显田间阴影下可能需要把V通道下限调低。但传统分割的最大问题是泛化能力差。一旦出现枯黄叶片、病斑颜色改变或光线过强固定阈值就会失效。深度学习方法里 U-Net 是经典选择编码器逐层压缩特征解码器通过跳跃连接恢复空间细节对边界粗糙的叶片有较好的分割结果。表 4 列出了几种分割方法的优缺点实际项目中我会先用一个轻量语义分割网络做叶片区域提取再把结果区域送入 YOLOv11 做病虫害检测形成两阶段链路。方法优点局限全局阈值分割实现简单、速度快光照变化大时分割不稳定Canny 边缘检测能提取明显叶脉和轮廓对密集叶片会产生大量断裂边缘U-Net 语义分割像素级精度高、边界平滑训练数据要求高小数据集容易过拟合YOLOv11 实例分割端到端输出掩码和框掩码质量取决于模型容量推理成本更高4.2 基于YOLOv11的病虫害识别与分割改进处理病虫害识别时我把 YOLOv11 当作一个强特征提取器在它的检测头之上接入一个轻量分割分支共享骨干网络的权重。这样训练时只需要一份标注数据包含叶片框、分割掩码和病虫害类别。如果你想用 Ultralytics 提供的预训练权重可以加载yolo11-seg.pt直接训练分割模型yolo segment train \ modelyolo11n-seg.pt \ datacrop_leaf_seg.yaml \ epochs80 \ imgsz640 \ batch16训练完成后推理时的输出除了边界框还会多一个分割掩码。我一般会在后处理里把掩码区域提取出来统计病斑面积占叶片面积的比例这个比例可以当作病虫害严重程度的量化指标。from ultralytics import YOLO model YOLO(best.pt) results model.predict(field_image.jpg, conf0.3, saveTrue) for result in results: if result.masks is not None: # masks.data 存储每个目标的二值掩码 for mask in result.masks.data: leaf_area mask.sum().item() # 结合分类结果进一步计算病斑占比 print(fleaf pixel area: {leaf_area})这里的conf0.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, conf0.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 modelbest.pt formatengine device0 halfTrue导出后推理速度提升明显但要注意 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, conf0.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, encodingutf-8) as f: json.dump({detections: output}, f, ensure_asciiFalse, indent2)这份 JSON 既可以直接送进数据库也可以用于后续生成田间病虫害热力图。需要注意如果输出掩码建议把掩码存储为 RLE 编码的字符串而不是原始数组不然 JSON 文件会非常大。针对叶片的实际应用里我更推荐把confidence阈值和分割面积阈值一起写入配置便于不同任务场景下切换。本文还有配套的精品资源点击获取