
简介这份资源面向从事农业图像识别、目标检测算法学习与落地的开发者提供一套可直接用于YOLO训练的植物叶片缺陷病害检测数据集解决自建数据标注耗时、格式不统一的问题。压缩包共2000个文件以1999个txt标注文件和1个Python可视化脚本为主整体约240MB按YOLOv5目录结构组织无需额外转换即可投入训练。数据涵盖格鲁病、早叶斑病、黑斑等10个类别图像为416×416的RGB大分辨率图片标注框完整每张图含多个目标采用YOLO相对坐标格式记录类别与中心点、宽高。训练集含13665张图片及对应标签验证集含1317张图片及对应标签并附10类别文本文件。配套的show.py可随机读取一张图片绘制边界框并保存到当前目录无需修改即可运行便于快速核验标注质量。目前已有245人学习适合作为病害检测模型训练与课程实验的现成数据基础。1. 植物叶片缺陷病害检测数据集10 类别 YOLO 格式开箱即用拿到一份标注好的植物叶片病害数据集最怕的不是模型训不动而是数据本身没整理干净——图片和标签对不上、类别编号从 1 开始、划分比例失衡。这份资源把 10 类植物叶片缺陷病害做成了 YOLO 可直接吃的格式图片、标签、类别 class 文件、数据可视化脚本一次性给全省掉从原始采集到格式转换的大半工作量。它适合正在做农业检测方向、需要快速跑通 baseline 的从业者也适合想验证某个 YOLO 改进点但手头没有干净数据的同学。10 个类别覆盖了常见的叶片病斑、虫蚀、枯黄等缺陷形态划分好的训练/验证/测试集意味着你 clone 下来改个 data.yaml 路径就能开训不用再花两天做清洗。下面按「数据长什么样 → 怎么接进 YOLO → 怎么验证没接错 → 坑在哪」的顺序拆一遍。2. 数据集结构与 YOLO 标签格式先看懂再动手2.1 目录布局与文件对应关系一份能直接训练的 YOLO 数据集核心就三样东西图片、同名 txt 标签、类别定义文件。这份资源的目录结构常见做法是 images 和 labels 平行放置各自再分 train/val/test 三个子目录。判断它是否规范第一眼看图片和标签是否同名同层级——images/train/leaf_001.jpg必须对应labels/train/leaf_001.txt少一个都会在训练时被静默跳过这是最常见的翻车点。类别文件通常叫classes.txt或data.yaml里的names字段。10 个类别的顺序就是标签里数字编号的含义第 0 类对应 names 列表第一个。很多人拿到数据集直接开训结果预测出来的类别名全错位就是因为没核对这个顺序。建议第一步先打印类别文件把编号和名称抄下来贴在代码注释里。可视化脚本是这份资源里容易被忽略但很值钱的部分。它一般做两件事把归一化的 YOLO 坐标还原成像素框画在图上以及统计每个类别的样本数量。前者用来肉眼验证标注质量后者用来判断有没有类别严重不均衡。2.2 YOLO 标签的归一化坐标怎么读YOLO 的标签格式是每行一个目标class_id x_center y_center width height后四个都是相对图片宽高的归一化值范围 0 到 1。新手最容易懵的是「为什么框画出来偏了」——多半是把归一化坐标当成像素坐标用了或者图片被 resize 后没同步换算。下面这段代码用来把标签还原成像素框并画出来是接数据前必跑的一步import cv2 import os def draw_yolo_label(img_path, label_path, class_names, save_path): img cv2.imread(img_path) h, w img.shape[:2] if not os.path.exists(label_path): print(f标签缺失: {label_path}) return with open(label_path, r) as f: lines f.readlines() for line in lines: parts line.strip().split() if len(parts) ! 5: print(f格式异常行: {line}) continue cls_id, xc, yc, bw, bh map(float, parts) # 归一化坐标还原为像素坐标 x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, class_names[int(cls_id)], (x1, max(y1 - 5, 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite(save_path, img) class_names [类别0, 类别1, 类别2, 类别3, 类别4, 类别5, 类别6, 类别7, 类别8, 类别9] draw_yolo_label(images/train/leaf_001.jpg, labels/train/leaf_001.txt, class_names, check_001.jpg)逻辑说明先读图拿真实宽高再把归一化中心点和宽高换算回像素坐标。x1 (xc - bw/2) * w这一步是关键中心点减半宽得到左上角。参数上class_names必须和数据集类别文件严格一致顺序错了框上的名字就错了。跑完随便抽十几张看框贴不贴叶片病斑一眼就能判断标注质量。2.3 划分比例与类别均衡检查划分好的数据集不代表划分合理。常见做法是 train:val:test 按 7:2:1 或 8:1:1但农业病害数据往往某些类别样本极少随机划分后验证集里可能一个该类样本都没有导致验证指标失真。跑一遍类别统计能提前发现这个问题import os from collections import Counter def count_classes(label_dir, num_classes10): counter Counter() for txt in os.listdir(label_dir): if not txt.endswith(.txt): continue with open(os.path.join(label_dir, txt)) as f: for line in f: if line.strip(): counter[int(line.split()[0])] 1 for i in range(num_classes): print(f类别 {i}: {counter.get(i, 0)} 个目标) count_classes(labels/train)逻辑说明遍历标签目录统计每个 class_id 出现的次数。如果某个类别数量是个位数训练时基本学不出来需要考虑过采样或数据增强。参数num_classes按实际类别数改。这一步花不了一分钟但能避免训完发现某类 AP 为 0 却找不到原因的尴尬。3. 接进 YOLOv8 训练data.yaml 配置与首轮跑通3.1 data.yaml 的四个必填字段YOLOv8 靠一个 yaml 文件认识数据集字段不多但每个都不能错。常见写法如下path: /home/user/leaf_dataset train: images/train val: images/val test: images/test nc: 10 names: 0: 病斑 1: 虫蚀 2: 枯黄 3: 霉变 4: 穿孔 5: 卷曲 6: 褪绿 7: 坏死 8: 锈斑 9: 健康path是数据集根目录train/val/test是相对 path 的图片路径YOLO 会自动把images替换成labels去找标签。nc是类别数names是编号到名称的映射。这里最容易踩的坑是path写了相对路径训练脚本在别的目录启动时找不到数据。建议一律写绝对路径或者确认启动目录就是数据集父目录。3.2 首轮训练命令与关键参数配置好 yaml 后一条命令就能起训yolo detect train \ data/home/user/leaf_dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ projectruns/leaf \ namebaseline参数说明modelyolov8n.pt用 nano 版先跑通流程确认数据和环境没问题再换 s/m/l。imgsz640是输入尺寸叶片病斑通常偏小如果显存够可以上到 800 或 1024小目标召回会明显改善。batch16按显存调爆显存就减半。epochs100是起步值看验证集 mAP 曲线是否还在涨再决定加不加。首轮训练重点不是刷高指标而是确认三件事loss 有没有正常下降、验证集能不能跑完、预测结果里类别名对不对。如果 loss 一开始就是 nan八成是标签里有坐标越界或空文件如果 mAP 一直为 0先回去查类别编号和 names 是否对齐。3.3 用可视化脚本反查标注质量训练前用可视化脚本抽检训练后再用同一批图跑推理对比是发现标注问题的有效手段。常见做法是挑每个类别各 5 张把原图标注框和模型预测框并排看。如果模型预测框明显比标注框更贴合病斑说明标注偏松如果标注框里有大量背景被框进去模型会学到噪声。这一步不需要写复杂代码YOLO 推理自带保存功能yolo detect predict \ modelruns/leaf/baseline/weights/best.pt \ sourceimages/val \ saveTrue \ conf0.25conf0.25是置信度阈值调低能看到更多候选框方便判断漏检是阈值问题还是模型没学到。saveTrue会把画框结果存到 runs 目录直接和可视化脚本的输出对比即可。4. 避坑与排查数据接 YOLO 时最容易翻车的五件事4.1 图片和标签不同名导致样本被静默丢弃现象训练日志里train的图片数量比实际文件数少或者某些图从来没出现在增强结果里。原因YOLO 按文件名匹配图片和标签leaf_001.jpg只认leaf_001.txt后缀或编号差一位就配不上配不上的图片会被直接跳过且不报错。解决写个脚本比对两个目录的文件名集合把差集打印出来补齐或删除。4.2 类别编号从 1 开始导致越界现象训练启动时报IndexError或Label class x exceeds nc。原因有些标注工具默认类别从 1 开始而 YOLO 要求从 0 开始。解决全局扫描标签文件把 class_id 统一减 1改之前先备份。改完再跑一遍类别统计确认最大值是 nc-1。4.3 归一化坐标越界或为负现象训练能跑但 mAP 异常低或者增强后的图里框跑到画面外。原因标注时框超出图片边界归一化后坐标小于 0 或大于 1。解决写校验脚本过滤把越界行修正到 [0,1] 区间或直接丢弃该目标。宁可少一个框也别让越界值污染训练。4.4 验证集类别缺失导致指标虚高现象验证集 mAP 看着不错但实际部署时某几类完全检测不到。原因稀有类别在划分时全进了训练集验证集里没有该类样本指标只反映了常见类别。解决划分时按类别分层抽样保证每个类别在验证集里至少有若干实例。已经划分好的可以用统计脚本检查缺的从训练集挪一部分过去。4.5 图片尺寸差异过大拖慢训练现象训练速度比预期慢很多或者显存占用忽高忽低。原因数据集中混有超大分辨率图片YOLO 虽然会 resize 到 imgsz但读图和预处理开销随原图尺寸上升。解决训练前统一把长边缩到 1280 以内既保留病斑细节又控制开销。批量 resize 用 OpenCV 几行就能搞定注意同步处理图片和标签标签是归一化的resize 不影响。5. 进阶技巧用可视化脚本做训练前后的数据体检可视化脚本的价值不止画框。把它改造成一个「数据体检」工具能在训练前拦住大部分低级错误训练后定位模型到底学没学到东西。我一般会固定跑三个检查类别分布直方图、标注框尺寸分布、随机抽样叠加网格。类别分布直方图直接暴露不均衡问题。如果某一类目标数不到总数的 2%训练时要么给它加过采样要么在 loss 里给类别权重。YOLOv8 本身没有直接的类别权重参数常见做法是复制稀有类别的图片和标签多份或者用 mosaic 增强时偏向稀有类。标注框尺寸分布用来判断 imgsz 设得合不合理。统计所有框的宽高像素值如果大量框小于 32 像素640 的输入下经过下采样后特征几乎消失这时候要么提高 imgsz要么换用带 P2 小目标检测层的模型结构。这一步用 numpy 算个分位数就能看出来import os import numpy as np def box_size_stats(label_dir, img_dir): widths, heights [], [] for txt in os.listdir(label_dir): if not txt.endswith(.txt): continue img_path os.path.join(img_dir, txt.replace(.txt, .jpg)) if not os.path.exists(img_path): continue import cv2 h, w cv2.imread(img_path).shape[:2] with open(os.path.join(label_dir, txt)) as f: for line in f: if not line.strip(): continue _, _, _, bw, bh map(float, line.split()) widths.append(bw * w) heights.append(bh * h) widths, heights np.array(widths), np.array(heights) print(f框宽 中位数 {np.median(widths):.1f} 5%分位 {np.percentile(widths, 5):.1f}) print(f框高 中位数 {np.median(heights):.1f} 5%分位 {np.percentile(heights, 5):.1f}) box_size_stats(labels/train, images/train)逻辑说明把归一化宽高乘回图片真实尺寸得到像素级框大小。看 5% 分位而不是最小值避免个别异常值干扰判断。如果 5% 分位的框宽小于 32 像素就该考虑提高输入分辨率了。随机抽样叠加网格是把 16 张带框的图拼成一张大图一眼扫过去就能发现标注风格是否一致、有没有漏标。这个用 OpenCV 的hconcat和vconcat拼就行不用额外依赖。从那以后我每次拿到新数据集都强制先跑一遍类别统计和框尺寸分布再抽 16 张拼图看标注质量三件事做完才允许自己敲训练命令。这套习惯帮我省下的返工时间远比写脚本花的那点功夫多。希望帮到你。本文还有配套的精品资源点击获取