☰
农作物多类别目标检测数据集:16类1041张YOLO格式实战指南
2026/10/19 5:17:40 网站建设 项目流程

简介:这份农作物多类别目标检测数据集面向农业AI开发者、农机视觉算法工程师及农业院校科研人员,用于解决农田场景下作物种类识别与定位的模型训练需求。数据集覆盖香蕉、豆类、茄子、辣椒、黄瓜、大蒜、生姜、玉米、洋葱、豌豆、菠萝、马铃薯、水稻、高粱、番茄、小麦等16类主要经济作物,涵盖谷物、蔬菜与经济作物三大类别,并特别包含豆类与豌豆、不同茄科作物等易混淆样本,有助于训练高精度农业检测模型。资源包共2000个文件,以957张jpg图像和1041个txt标注文件为主,另含1个yaml配置文件与1份docx说明文档,压缩包约73.86MB,标注严格遵循YOLO格式,可直接用于YOLOv5/v7/v8等主流框架的迁移学习与微调。目前已有107人学习下载,适合用于农田巡检机器人、智能除草与自动化收割设备的视觉感知模块开发,也可支撑作物分布分析与产量预测等精准农业应用。

1. 农作物多类别目标检测数据集:16 类作物、1041 张图,农业视觉项目能直接开跑

如果你正在做农业 AI 相关的目标检测,大概率卡在同一个地方:模型结构抄得飞快,数据却凑不齐。网上能找到的农田图片要么类别单一,要么标注格式五花八门,光是把 XML 转成 YOLO 的 txt 就得折腾半天。这份农作物多类别目标检测数据集就是冲着这个痛点来的——1041 张实拍农田图片,覆盖香蕉、豆类、茄子、辣椒、黄瓜、大蒜、生姜、玉米、洋葱、豌豆、菠萝、马铃薯、水稻、高粱、番茄、小麦共 16 类主要农作物,全部按 YOLO 格式标注好,训练集 726 张、验证集 212 张、测试集 103 张,目录结构直接对齐主流检测框架。适合谁?做农业巡检机器人视觉模块的、搞精准农业管理平台的、带学生做 AI+农业交叉课题的,以及想拿一个真实行业数据集练手 YOLO 微调的开发者。下面我从数据组织、训练跑通、踩坑排查到二次开发,把这份资源拆开讲清楚。

2. 数据集结构与标注格式:从文件名到 YOLO txt 的完整链路

2.1 目录组织与文件命名规律

拿到压缩包解压后,你会看到图片和标注文件成对出现,命名规则是类别名_序号_jpg.rf.哈希值.jpg这种形式。比如chilli_8_jpg.rf.71b9cb5407d240f706c0e72e817a39fb.jpg、pineapple_51_jpg.rf.1c2090a6c9f8a1c0cbba2bc17bbf9bfa.jpg、potato_50_jpg.rf.f8be569fdccf89a48956827ed931a8a1.jpg。文件名前缀直接暴露了主类别,后面的rf.加一长串哈希是数据增强或导出流程留下的痕迹,不影响使用,但批量处理时要注意别把它当成类别的一部分去解析。

常见的目录组织方式是这样:

crop_dataset/ ├── images/ │ ├── train/ # 726 张 │ ├── val/ # 212 张 │ └── test/ # 103 张 ├── labels/ │ ├── train/ # 与图片同名的 .txt │ ├── val/ │ └── test/ └── data.yaml # 类别名与路径配置

图片和标注文件必须同名同目录层级,这是 YOLO 系列框架的硬性约定。如果你拿到的包是平铺的,建议先按 7:2:1 的比例重新划分,别直接用原始顺序切,否则同一块田、同一批光照条件下的图可能全挤进训练集,验证集指标会虚高。

2.2 YOLO 标注格式逐字段拆解

每个.txt文件里一行代表一个目标框,格式是:

<class_id> <x_center> <y_center> <width> <height>

五个字段全部归一化到 0~1 之间。class_id从 0 开始编号,对应data.yaml里names列表的顺序。x_center、y_center是边界框中心点相对整图宽高的比例,width、height是框的宽高比例。举个实际例子,一张 640×480 的图里有个辣椒框在左上区域,标注可能长这样:

3 0.312500 0.416667 0.187500 0.250000

换算回像素就是:中心点 (200, 200),框宽 120、框高 120。这里有个新手常翻车的点——归一化用的是整图尺寸,不是裁剪后尺寸。如果你在预处理阶段做了 resize 却没同步更新标注,框会整体偏移,训练 loss 降不下去还找不到原因。

2.3 data.yaml 配置与类别映射

data.yaml是训练入口的配置文件,结构不复杂但每个字段都不能错:

path: ./crop_dataset train: images/train val: images/val test: images/test nc: 16 names: 0: banana 1: bean 2: eggplant 3: chilli 4: cucumber 5: garlic 6: ginger 7: corn 8: onion 9: pea 10: pineapple 11: potato 12: rice 13: sorghum 14: tomato 15: wheat

nc必须和names的条目数严格一致,names的顺序必须和标注文件里的class_id一一对应。我见过有人把names按字母序重排了一遍,结果模型把番茄认成小麦,mAP 直接掉到个位数。改类别名可以,改顺序不行,除非你同步重写所有标注文件。

提示:验证集和测试集的data.yaml路径如果指向同一份文件,评估时记得用split=test显式指定,别让框架默认拿 val 去跑测试。

3. 训练环境搭建与 YOLO 微调实战:从零跑通第一个 epoch

3.1 环境依赖与版本选择

这份数据集标注格式兼容 YOLOv5/v7/v8 等主流框架,选哪个看你的部署目标。如果只是快速验证数据可用性,YOLOv8 的 CLI 最省事;如果要往边缘设备上部署,YOLOv5 的生态和量化工具链更成熟。基础环境建议:

conda create -n crop_det python=3.10 -y conda activate crop_det pip install ultralytics torch torchvision opencv-python pyyaml

ultralytics包自带 YOLOv8 的训练和推理接口,装完就能用。GPU 环境记得确认 CUDA 版本和 torch 匹配,不然训练会静默回退到 CPU,一个 epoch 跑半小时你还以为是数据量大。

3.2 启动训练与关键参数含义

用 YOLOv8 跑这份数据集的命令很直接:

yolo detect train \ data=./crop_dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=20 \ project=runs/crop \ name=exp1

逐项说下参数:model=yolov8n.pt用预训练权重做迁移学习,1041 张图从零训容易过拟合;imgsz=640是输入分辨率,农田图片里小目标多,降到 416 会丢不少豆类、豌豆的框;batch=16看显存调,8G 显存跑 640 分辨率大概能到 16;lr0=0.01是初始学习率,微调场景可以降到 0.001 更稳;patience=20表示 20 个 epoch 指标不涨就早停,省得白跑。

训练启动后重点盯三个输出:box_loss是否稳定下降、mAP50是否在 30 个 epoch 后开始爬升、cls_loss有没有剧烈震荡。如果box_loss降但mAP不涨,大概率是标注框和实际目标对不齐,回去抽查几张图的标注可视化。

3.3 标注可视化与数据校验

训练前强烈建议做一次标注可视化,把框画回原图上看一眼:

import cv2 import os img_path = "crop_dataset/images/train/chilli_8_jpg.rf.71b9cb5407d240f706c0e72e817a39fb.jpg" label_path = img_path.replace("images", "labels").replace(".jpg", ".txt") img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path) as f: for line in f: cid, xc, yc, bw, bh = map(float, line.split()) 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, str(int(cid)), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite("check_vis.jpg", img)

这段代码把归一化坐标还原成像素坐标画框,cid是类别编号。跑完打开check_vis.jpg,重点看三类问题:框有没有整体偏移(归一化基准错了)、框有没有框到背景(标注质量问题)、同一目标有没有重复框(漏删或合并问题)。这一步花十分钟,能省掉后面几小时的无效训练。

3.4 推理验证与指标解读

训练完拿测试集跑推理:

yolo detect predict \ model=runs/crop/exp1/weights/best.pt \ source=crop_dataset/images/test \ conf=0.25 \ save=True

conf=0.25是置信度阈值,农业场景里漏检比误检代价高,可以降到 0.15 多召回一些。结果图会存到runs/detect/predict下。看指标时别只盯mAP50,mAP50-95更能反映框的定位精度。16 类里豆类和豌豆、不同茄科作物容易混,如果这两类的 AP 明显低于平均,说明特征区分度不够,后面二次开发部分会讲怎么针对性优化。

4. 避坑与常见问题排查:标注、路径、显存的三类翻车现场

4.1 训练 loss 不降,mAP 卡在 0.01

现象:训练启动后box_loss在 1.0 附近震荡,mAP50始终接近 0。原因通常是data.yaml里的names顺序和标注文件里的class_id对不上,或者nc写成了实际类别数以外的值。解决:用脚本统计所有标注文件里出现过的class_id最大值,确认它等于nc - 1;再抽查几个标注文件,把class_id和names里的类别名对照一遍。我一般会写个三行脚本做这个校验,比肉眼翻文件靠谱。

4.2 图片路径报 FileNotFoundError

现象:训练能启动但一加载数据就报找不到图片。原因多半是data.yaml里的path用了相对路径,而训练命令的工作目录和 yaml 所在目录不一致。解决:把path改成绝对路径,或者确保在data.yaml所在目录下执行训练命令。另一个隐蔽原因是图片扩展名大小写不一致,.JPG和.jpg在 Linux 下是两个文件,批量重命名统一成小写。

4.3 显存溢出 CUDA out of memory

现象:跑到第几个 batch 突然 OOM。原因可能是batch设太大,或者imgsz用了 1280 这种高分辨率。解决:先把batch降到 8 或 4,再考虑用--amp混合精度训练。如果还不行,检查是不是workers开太多导致内存泄漏,设成 4 或 8 试试。农田图片普遍不大,640 分辨率够用,没必要硬上高分辨率。

4.4 验证集指标虚高,测试集拉胯

现象:验证集mAP50到 0.85,测试集只有 0.5。原因通常是数据划分时同一场景的图片被分到了训练和验证两边,模型记住了背景而不是目标。解决:按拍摄批次或地块重新划分,确保验证集和测试集的图片来自训练集没见过的场景。这份数据集已经分好了 train/val/test,但如果你自己重新切分,务必按场景切而不是随机切。

4.5 类别不平衡导致小类漏检

现象:香蕉、番茄这些样本多的类 AP 很高,豌豆、高粱这些样本少的类几乎检不出来。原因就是类别样本数差异大。解决:训练时加cls权重,或者用copy_paste这类增强给小类扩样本。YOLOv8 支持在data.yaml里配augment参数,也可以自己写个过采样脚本,把小类图片复制多份进训练集。

5. 二次开发与模型优化:把 16 类检测器改成你的农业专用模型

5.1 增删类别与标注迁移

实际项目里你未必需要全部 16 类。比如只做辣椒和番茄的采摘机器人,可以把其他类的标注过滤掉,重映射class_id:

import os keep = {"chilli": 0, "tomato": 1} label_dir = "crop_dataset/labels/train" out_dir = "crop_dataset/labels_bin/train" os.makedirs(out_dir, exist_ok=True) for fname in os.listdir(label_dir): src = os.path.join(label_dir, fname) dst = os.path.join(out_dir, fname) with open(src) as f, open(dst, "w") as g: for line in f: cid = int(line.split()[0]) # 原始类别名映射,这里假设已知原始顺序 name = list(keep.keys())[cid] if cid < len(keep) else None if name in keep: new_line = line.replace(str(cid), str(keep[name]), 1) g.write(new_line)

这段逻辑的核心是「过滤 + 重编号」,keep字典定义你要保留的类别和新编号。注意line.replace只替换第一个匹配,避免把坐标里的数字也改掉。改完记得同步更新data.yaml的nc和names。

5.2 针对易混淆类别的特征增强

豆类和豌豆、茄子和番茄在幼苗期形态接近,模型容易混。除了加数据,可以在模型层面做文章:在 YOLOv8 的 neck 部分加一个轻量注意力模块,让网络更关注纹理和叶形差异。具体做法是继承ultralytics的模型定义,在C2f模块后插入一个通道注意力:

import torch import torch.nn as nn class ChannelAttention(nn.Module): def __init__(self, channels, reduction=16): super().__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Sequential( nn.Linear(channels, channels // reduction), nn.ReLU(), nn.Linear(channels // reduction, channels), nn.Sigmoid() ) def forward(self, x): b, c, _, _ = x.size() y = self.avg_pool(x).view(b, c) y = self.fc(y).view(b, c, 1, 1) return x * y

reduction=16控制压缩比,通道数少的时候可以调到 8。这个模块加在 backbone 输出后,能让模型对颜色和纹理差异更敏感。加完重新训练,重点看豆类/豌豆、茄子/番茄这两组的混淆矩阵有没有改善。

5.3 导出与边缘部署验证

训练完的模型要落到设备上,先导出 ONNX 或 TensorRT:

yolo export model=runs/crop/exp1/weights/best.pt format=onnx opset=12 simplify=True

opset=12兼容性较好,simplify=True会做图优化。导出后拿几张测试图跑一遍 ONNX Runtime 推理,对比 PyTorch 和 ONNX 的输出差异,如果 mAP 掉超过 2 个点,检查是不是有算子不支持。边缘设备上还要测推理耗时,YOLOv8n 在主流边缘芯片上 640 分辨率大概能到 30~50 FPS,具体看芯片算力。

5.4 一个我踩过的坑

有次我把这份数据集和另一份田间数据混在一起训,忘了统一类别顺序,结果模型把生姜认成了马铃薯。从那以后我每次合并数据集都强制走一遍类别映射校验脚本,先打印两边的names列表,确认没有重名和顺序冲突再开始训练。这个习惯帮我省了好几次返工。希望这份拆解能帮你把农业检测项目顺利跑起来,少走点我走过的弯路。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询