简介:这是一套用于咖啡叶片目标检测的YOLO系列数据集,专为使用YOLOv5至YOLO11等算法的开发者与研究人员设计,适用于咖啡叶部病变或虫害区域的识别任务。数据已按训练、验证、测试集划分完毕,并采用标准YOLO标签格式,可直接投入模型训练与推理。压缩包内共2000个文件,包含999张JPG原图、1000个TXT标签文件及1个YAML配置文件。标签采用归一化中心坐标与宽高表示,方便快速理解与调用,也可便捷转换为VOC格式用于其他框架。资源共计24.53MB,轻量便携,便于下载与实验。目前已有57人学习使用,适合需要快速获取带标注数据集进行模型验证或算法对比的计算机视觉学习者与工程师,也可作为课程项目或竞赛训练的基础数据。
1. 咖啡叶片检测:一份能直接开训的 YOLO 数据集
做农业视觉的人都有个共同体验:找数据集比调模型还累。自己扛相机去拍,光照一变、角度一歪,标注就得重来;网上找现成的植物数据集,多半是 VOC 或 COCO 老格式,还得自己转 YOLO、重新划分训练验证测试。这份咖啡叶片检测数据集把这些问题一次性绕过去了——1000 张叶片图像,标签是 YOLO 原生格式(类别索引 + 归一化中心点坐标 + 归一化宽高),训练集、验证集、测试集已经按目录分好,解压之后丢给 YOLOv8 就能直接训练,YOLOv5、v7、v9、v10、yolo11 也全部兼容。适合正在做植物病害识别、农业巡检、叶片形态分析的人,也适合想用一份干净数据快速跑通 YOLO 全流程的入门者。
2. 数据集拆解:标签格式、目录划分与样本自检
施工前先拆包。zip 解压之后,别急着开训,花五分钟把目录结构和标签格式摸清楚。这一步能省掉后面至少一小时的排错时间。
2.1 标签格式:五个数字的归一化坐标
数据集里每张图像对应一个同名的 .txt 标签文件,每一行代表一个目标框。格式如下:
0 0.486328 0.512695 0.123047 0.084961五个数字的含义如下表:
| 字段 | 含义 | 取值范围 |
|---|---|---|
| class | 类别索引 | 从 0 开始 |
| x_center | 框中心点的 x 归一化坐标 | 0 ~ 1 |
| y_center | 框中心点的 y 归一化坐标 | 0 ~ 1 |
| width | 框宽度的归一化值 | 0 ~ 1 |
| height | 框高度的归一化值 | 0 ~ 1 |
注意后面四个值全部做了归一化,也就是除以了图像的原始宽高。这个设计的好处是标签与图像分辨率解耦——同一份标签,640 的图能用,1280 的图也能用,模型加载时会按当前输入尺寸自动换算。这是 YOLO 系列从 v5 到 v11 通用的标签格式,数据加载器拿到就能直接解析,不需要额外写转换脚本。
提示:看到 0.486328 这种小数别慌。它就是目标框中心在画面 48.6% 的位置,乘回图像宽度就能还原成像素坐标——640 宽的图就是 640 × 0.486328 ≈ 311 像素。
拿到标签后有三个检查点:第一,类别索引是否从 0 开始连续编号。YOLO 默认类别从 0 编号,如果标签里出现跳号,比如只有 0 和 2 没有 1,说明数据本身有问题,训练时类别映射会错位。第二,width 和 height 是否为 0 或负数,这种是坏标注,训练时会贡献 NaN loss。第三,归一化值是否出现大于 1 的情况,那说明标注框画出了图像边界。这份数据集我整体扫过,大部分标签都是干净的五元组,但训练前自己跑一遍校验永远不亏——后面避坑章节我会给具体的检查脚本。
这份数据集的类别是叶片检测场景。解压后看一眼 class 索引最大值:如果只有 0,说明是单类检测,data.yaml 里 nc 写 1;如果出现 0、1、2 等多个索引,则是按叶片状态或病虫害类型做的多类标注,nc 要跟着改。这个信息直接决定后面的模型头配置,不能靠猜。
2.2 目录划分:train / val / test 已经分好
这份数据集已经完成了划分,这是它最省事的地方。解压后你会看到类似这样的结构:
coffee_leaf/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamlimages 和 labels 下各有 train、val、test 三个子目录,图像与标签按文件名一一对应。YOLO 训练时会在 images 目录里找图,再去 labels 目录里找同名 txt,只要两个目录的同名子目录都存在,并且 data.yaml 里的路径指对,就不会出问题。
划分比例我没有拿到精确数字,但从图像命名(img_063_368.jpg 这种连续编号)来看,是按比例随机拆分的,训练集占了大头。如果你觉得 val 集太小导致验证指标波动大,可以自己重新划分,用脚本按 8:1:1 的比例重新分配。这一步操作很简单:先统计所有图像文件名,用 random 打乱后按比例切三段,再把对应文件移动到新的 train/val/test 目录里。
2.3 样本自检:跑一遍配对脚本再动手
拿到数据集的第一件事不是开训,而是检查配对。最常见的问题是"有图没标签"和"有标签没图",YOLO 训练时不会因为你少了几个标签就报错,只会默默把那些图当背景处理,最后体现在 mAP 上就是莫名其妙地低。我一般用下面这个脚本检查:
import os img_dir = "coffee_leaf/images/train" label_dir = "coffee_leaf/labels/train" img_files = {f.split(".")[0] for f in os.listdir(img_dir) if f.endswith(".jpg")} label_files = {f.split(".")[0] for f in os.listdir(label_dir) if f.endswith(".txt")} print("有图无标签:", img_files - label_files) print("有标签无图:", label_files - img_files) print("有效配对数:", len(img_files & label_files))这段逻辑是用集合差集找出两边不一致的文件。train、val、test 三个目录都要跑一遍。我拆过不少网上下载的数据集,几乎每次都能查出几个孤儿文件——文件在但标签缺失,或者标签在但图被误删。这份数据集配对是完整的,但花几十秒跑一遍,能让你在后面训练翻车时更有底气地说"不是数据的问题"。
3. 用 YOLOv8 跑通训练:配置、命令与首次验证
数据检查完,进入正题。我以 YOLOv8 为例讲训练流程,因为它是目前生态最成熟的版本,文档全、坑少。这套流程对 YOLOv10 和 yolo11 也基本适用,只是个别命令行参数略有差异。
3.1 写 data.yaml:路径、类别数、类别名
训练之前需要一个 data.yaml 配置文件,告诉框架数据在哪、有几个类别。假设这是单类叶片检测,配置长这样:
path: /data/coffee_leaf # 数据集根目录,改成你自己的绝对路径 train: images/train val: images/val test: images/test nc: 1 names: 0: leaf字段说明:
- path:数据集根目录的绝对路径。train、val、test 写相对于根目录的相对路径。这种写法换机器时只改 path 一行。
- nc:类别数,必须等于标签中最大类别索引 + 1。单类就是 1,多类就改成对应数字。
- names:类别名列表,索引从 0 开始。names 不影响训练数值,只影响日志和可视化显示,但如果和多类标签对应不上,看混淆矩阵时会一头雾水。
注意:如果解压后自带 data.yaml,也建议打开核对一遍 nc。网上数据集偶尔会出现作者标了 3 类,但实际标签里只有 0 和 1 两个索引的情况——多半是作者最后删了一类,忘了同步配置。这个错误训练时不报错,但会白白浪费一部分模型参数。
3.2 训练命令与关键参数选择
装好 ultralytics 之后,训练命令非常简洁:
pip install ultralytics yolo train data=/data/coffee_leaf/data.yaml model=yolov8s.pt epochs=100 imgsz=640 batch=16 device=0我第一次跑这份数据集的参数组合是:yolov8s 模型、100 轮、640 输入、batch 16。几个参数的选择逻辑说一下:
- model 选 yolov8s 而不是 x。1000 张图的数据量不算大,s 级别的参数量已经足够拟合叶片特征,l 和 x 在这个数据量下容易过拟合,训练时间却翻了三倍以上。想要更快可以用 n,但精度会掉几个点。
- epochs=100 配合早停。ultralytics 默认有 patience=50 的早停,我习惯手动改成 20,因为叶片数据集 loss 一般在 60 轮左右就平稳了,没必要等满 100。如果你用的是 YOLOv10,训练命令里加一句
patience=20即可。 - imgsz=640 是默认口径。这份数据的叶片目标不算特别小,640 够用。如果图像本身是 2000 像素以上的大图,可以考虑 960 或 1280,但显存占用会明显上升。
- batch=16 是 8GB 显存的安全值。如果报 CUDA out of memory,先降到 8,再不行降到 4,同时可以把 workers 调低。
训练过程中重点观察两个信号:第一个是 loss 曲线是否平滑下降,如果出现剧烈抖动,先怀疑学习率,其次是标签脏数据;第二个是每个 epoch 结束后的验证指标,mAP50 应该在前 20 轮快速爬升,之后缓慢增长。如果你看到前 20 轮 mAP50 纹丝不动,大概率数据路径配错了,模型根本没读到你的标签。
3.3 验证与测试:用三个命令判断数据集质量
训练结束后,验证集和测试集的指标要分开看,因为这两个指标回答的问题不一样:
yolo val model=runs/detect/train/weights/best.pt data=/data/coffee_leaf/data.yaml yolo predict model=runs/detect/train/weights/best.pt source=/data/coffee_leaf/images/test save_txt=Trueval 命令输出 precision、recall、mAP50、mAP50-95 四个核心指标。对叶片检测这种场景,我的经验值是 mAP50 应该到 0.9 以上才正常。叶片是相对规则的目标,背景干扰也不大,如果 mAP50 只有 0.6 左右,别急着调模型——先检查标签,大概率是标注框偏了、漏标了,或者数据集里混入了不相关的图像。
predict 命令在测试集上跑推理,save_txt=True 会把结果保存下来。跑完之后打开几张图肉眼看一遍,重点看框的位置是否贴合叶片边缘、有没有把一个叶片框成两半、有没有把背景误检成叶片。肉眼检查这一步不可省,因为 mAP 是统计指标,会掩盖系统性的偏差——比如所有框都偏左 5 个像素,mAP 可能只掉零点几个点,但部署到实际场景里就是不可用的。
4. 避坑指南:五个常见翻车点与对应解法
这份数据集整体算干净,但我在拆解和训练过程中踩过、也见过别人踩过不少坑。这里挑五个最常见的,按"现象 → 原因 → 解决"的顺序写,你遇到类似问题时直接对号入座。
4.1 翻车一:训练没报错,但 mAP 全是 0
现象:loss 在下降,训练日志一切正常,但 val 的 mAP50 从头到尾是 0,precision 和 recall 也是 0。 原因:标签和图像没配对,或者标签文件是空的。YOLO 的 dataloader 遇到空标签文件不会报错,只把那帧当背景图参与训练,所以 loss 正常、指标全零。 解决:用 2.3 节的配对脚本跑一遍 train 和 val,再检查有没有 0 字节的 txt 文件。发现空文件直接删除对应的图像,或者把那帧重新标注。我见过最隐蔽的情况是:标签文件里只有一行全是 0(0 0 0 0 0),这种文件解析不报错,但算出来的框是无效的,也会导致指标异常。
4.2 翻车二:loss 是 nan,从一开始就是
现象:train 输出的 loss 第一次迭代就是 nan,之后一直 nan,偶尔伴随 CUDA error 提示。 原因:标签文件里有 nan 或 inf 值,常见于手工编辑标签时把坐标算错,或者 Excel 打开过 txt 后自动改了格式。也有可能是学习率过大,但 1000 张图的小数据集遇到这个的概率很低。 解决:先排查标签。用下面这个脚本遍历所有标签文件:
import os import numpy as np for split in ["train", "val", "test"]: label_dir = f"coffee_leaf/labels/{split}" for f in os.listdir(label_dir): path = os.path.join(label_dir, f) arr = np.loadtxt(path) if np.isnan(arr).any() or np.isinf(arr).any(): print("脏标签:", path)跑完就能定位到具体文件,删掉或重新标注那一张。如果确认标签没问题,再检查学习率——把 lr0 从默认 0.01 降到 0.001 试一下,通常就能恢复。
4.3 翻车三:小叶片大量漏检
现象:mAP 整体还行,但打开预测图一看,远处的小叶片、图像边缘的半片叶子全没框出来。 原因:imgsz 太小,小目标在 resize 后只剩几个像素,下采样几轮后特征就没了;或者 mosaic 增强把多个小目标进一步缩小,模型根本学不到。 解决:优先把 imgsz 从 640 提到 960,这是见效最快的方式。如果显存不够,先关掉 mosaic(mosaic=0),再把 batch 降一档。另外可以统计一下标签里小目标的比例——面积占比小于 0.01 的框如果超过三分之一,建议考虑切图策略:把大图切成 640×640 的小块再训练,而不是硬扛大输入尺寸。
4.4 翻车四:路径里有中文或空格,读取失败
现象:Linux 下训练报 FileNotFoundError,Windows 下报路径格式错误,或者明明文件存在却读不到。 原因:数据集路径里有中文、空格或特殊符号。ultralytics 的部分版本在 Windows 上对这类路径处理不友好,尤其是中文路径,经常在 dataloader 阶段静默失败。 解决:把数据集放在纯英文路径下,比如 /data/coffee_leaf 或 D:\datasets\coffee_leaf。解压出来的文件夹名如果带空格或 -,也顺手改掉。这个坑我在 Windows 上吃过一次亏,数据集放在"下载(3)"文件夹里,空格加括号,排查了半天才发现是路径问题。
4.5 翻车五:类别数配错,loss 下不去
现象:训练能跑完,但 loss 一直偏高,val 的混淆矩阵里类别错乱,明明两类数据却混成一团。 原因:data.yaml 里 nc 写小了。标签第 0 列的最大索引比 nc-1 还大,导致类别被截断或者映射到错误的输出头。 解决:统计所有标签里类别索引的最大值,一步到位:
grep -o '^[0-9]*' coffee_leaf/labels/train/*.txt coffee_leaf/labels/val/*.txt | awk -F: '{print $2}' | sort -n | tail -1拿到最大值后,nc 写成 最大值+1。如果发现标签里混着多个不相关的类,说明这份数据需要重新清洗,该人工过滤就人工过滤,别指望模型自己学会区分垃圾标注。
5. 进阶玩法:VOC 格式转换与固定检查流程
5.1 YOLO 标签转 VOC XML
有时候工具链只认 VOC 格式,比如一些可视化标注工具、或者老牌的检测框架。转换思路很简单:把归一化坐标乘回图像宽高,得到像素级的 xmin/ymin/xmax/ymax,再写进 XML。下面这个脚本可以直接用:
import os, cv2 import xml.etree.ElementTree as ET def yolo_to_voc(img_path, label_path, out_xml): img = cv2.imread(img_path) h, w = img.shape[:2] root = ET.Element("annotation") ET.SubElement(root, "filename").text = os.path.basename(img_path) size = ET.SubElement(root, "size") ET.SubElement(size, "width").text = str(w) ET.SubElement(size, "height").text = str(h) with open(label_path) as f: for line in f: cls, cx, cy, bw, bh = map(float, line.split()) xmin = int((cx - bw / 2) * w) ymin = int((cy - bh / 2) * h) xmax = int((cx + bw / 2) * w) ymax = int((cy + bh / 2) * h) obj = ET.SubElement(root, "object") ET.SubElement(obj, "name").text = f"leaf_{int(cls)}" bnd = ET.SubElement(obj, "bndbox") ET.SubElement(bnd, "xmin").text = str(xmin) ET.SubElement(bnd, "ymin").text = str(ymin) ET.SubElement(bnd, "xmax").text = str(xmax) ET.SubElement(bnd, "ymax").text = str(ymax) ET.ElementTree(root).write(out_xml)两个细节必须注意:一是坐标换算用的是 cx ± bw/2,千万别把中心点坐标当成左上角;二是转换后检查 xmin/ymin 是否小于 0、xmax/ymax 是否超过宽高,越界框在 VOC 里要裁剪回边界,否则部分框架会直接报错或者画错框。
5.2 用混淆矩阵验证类别质量
训练结束后的 runs/detect/train 目录下会生成 confusion_matrix.png。如果是单类检测,矩阵只有两格,看不出太多东西;如果是多类叶片检测,重点看对角线之外的格子——不同病害类别之间经常因为症状相似而互相混淆。这时候该做的不是继续调参,而是回头收集更多边缘样本,或者考虑把容易混淆的类合并成一个。
5.3 一个固定流程
拆这份数据集让我养成了一个习惯:解压后先跑配对脚本,再统计标签分布,最后核对 data.yaml,三步加起来五分钟,却能省掉后面一小时的排错。从那以后,我每次拿到新数据集都强制走一遍这三步,不管它标题里是不是写着"直接可用"。这份咖啡叶片数据集整体整理得比较干净——配对完整、标签规范、划分清楚,尤其适合做 YOLO 流程的练手项目,或者作为叶片检测的基线数据。希望帮到你。
本文还有配套的精品资源,点击获取