花生植株与果簇检测数据集:YOLOv5农业小目标实战指南
2026/9/16 18:43:23 网站建设 项目流程

简介:作物目标检测是农业AI落地的核心基础能力,其本质是将田间视觉信息转化为可执行农事决策的结构化输出。在真实场景中,小目标(如花生果簇)、低对比度、遮挡重叠及生育期动态变化构成主要技术挑战。YOLOv5凭借轻量架构与工业级部署成熟度,成为农机视觉模块首选模型,但高度依赖规范的数据集结构与精准标注。本数据集聚焦‘单株花生植株’和‘花生果实簇’两类语义明确、业务强相关的视觉实体,提供207张多生育期实拍图像及严格校验的YOLO格式标签,覆盖苗期、花期、结荚期典型干扰,并预置适配无人机航拍尺度的anchor优化方案。适用于农业AI初创POC验证、高校小目标检测基线研究及农机边缘端部署。

1. 这个花生检测数据集到底解决了什么实际问题?

在农业智能化落地的现场,我见过太多次这样的场景:植保无人机飞过一片花生田,机载摄像头实时回传画面,但后台算法要么把刚出土的嫩叶识别成杂草,要么把密集生长的花生藤蔓当成单株目标漏检——最后人工还得下地复查,智能设备成了“智能摆设”。直到去年帮一家山东花生合作社部署病虫害早期预警系统时,我才真正意识到:不是模型不够强,而是手头根本找不到一个能反映真实田间复杂性的、带明确语义边界的花生目标检测数据集。市面上公开的作物数据集,要么是实验室环境下拍摄的干净样本(比如Peanut-Leaf-Disease),要么是整片田块的遥感影像(如CropSeg),但没有一个数据集专门标注“单株花生植株”和“花生果实簇”这两个对农事决策最关键的视觉实体。这个YOLOv5格式的花生检测数据集,就是为解决这个卡点而生的:它不追求海量图片,而是用207张实拍田间图像,精准标注出“植株”和“果簇”两类目标,每张图都经过光照变化、遮挡、重叠、不同生育期等真实干扰条件的筛选。它不是学术玩具,而是能直接喂进YOLOv5训练管道、跑通端到端推理的生产级最小可行数据集。如果你正在做农机视觉模块开发、农业AI初创公司的POC验证,或者高校课题组需要可复现的农业小目标检测基线,这个数据集的价值在于——它省掉了你从零采集、标注、清洗、格式转换的3周时间,让你能把精力聚焦在模型调优和业务逻辑上。

2. 数据集结构深度拆解:为什么必须严格遵循YOLOv5目录规范?

YOLOv5对数据集目录结构有近乎苛刻的要求,这不是开发者故意设置障碍,而是由其训练脚本的硬编码逻辑决定的。这个花生数据集采用标准的datasets/peanut/根目录结构,但每一层设计都有明确的工程意图,我来逐层拆解:

2.1 根目录与划分逻辑:datasets/peanut/下的生存法则

datasets/ └── peanut/ ├── images/ # 所有原始图像存放处 │ ├── train/ # 训练集图像(155张) │ └── val/ # 验证集图像(52张) ├── labels/ # 对应的YOLO格式标注文件 │ ├── train/ # 训练集标签(.txt,与images/train同名) │ └── val/ # 验证集标签(.txt,与images/val同名) └── data.yaml # 数据集配置元信息

这个结构的关键在于路径绑定:YOLOv5的train.py脚本会硬性读取data.yaml中定义的train:val:路径,这两个路径必须是相对于datasets/peanut/的相对路径,且必须与images/labels/子目录下的实际文件名完全一致(包括大小写和扩展名)。我曾因把val/误写成valid/导致训练脚本报错FileNotFoundError: No such file or directory,排查了2小时才发现是yaml里一个字母的差异。更隐蔽的坑是:YOLOv5默认要求images/labels/下对应子目录的文件数量必须严格相等,哪怕某张图没有目标(即对应label文件为空),也必须存在一个空的.txt文件。这个花生数据集已预处理完成,所有52张验证图都有对应的空或非空label文件,避免了训练中途因文件缺失中断。

2.2data.yaml配置文件:被低估的元数据中枢

datasets/peanut/data.yaml的内容看似简单,却是整个训练流程的“宪法”:

train: ../peanut/images/train # 注意:这里是相对于yolov5主目录的路径! val: ../peanut/images/val nc: 2 # number of classes names: ['plant', 'pod_cluster'] # class names, must match label indices

这里有两个极易踩的深坑:第一,trainval路径的写法。YOLOv5官方代码默认在yolov5/目录下运行,所以../peanut/images/train意味着从yolov5/向上一级进入datasets/,再进入peanut/。如果你把数据集放在其他位置(比如/home/user/agri-data/peanut/),就必须修改这里的路径,否则脚本会去yolov5/../peanut/找,必然失败。第二,names列表的顺序直接决定了模型输出的类别索引:'plant'永远是索引0,'pod_cluster'永远是索引1。这意味着你在后处理时,如果用pred[0]代表植株,pred[1]代表果簇,这个映射关系是硬编码在训练过程中的,绝不能颠倒。我在调试一个喷药机器人控制逻辑时,就因在data.yaml里把names写成['pod_cluster', 'plant'],导致模型输出的类别ID和下游控制指令完全错位,喷头对着空地狂喷。

2.3 YOLO格式标签文件:坐标系与数值精度的实战约束

每个.txt标签文件(如images/train/IMG_20230415_102345.jpg对应labels/train/IMG_20230415_102345.txt)的格式是:

0 0.423 0.618 0.215 0.389 1 0.782 0.291 0.142 0.227

这行数字的含义是:class_id center_x center_y width height,全部归一化到[0,1]区间。关键细节在于:

  • 坐标系原点:左上角(0,0),x向右,y向下,这是OpenCV和PyTorch的通用约定;
  • 归一化基准center_x = (bbox_x_min + bbox_width/2) / image_width,必须用原始图像的宽高计算,而非缩放后的尺寸;
  • 数值精度:YOLOv5官方推荐保留6位小数,但实测中4位(如0.4230)已足够稳定。我测试过用round(x, 4)round(x, 6)训练同一模型,mAP@0.5差异小于0.1%,但4位小数能显著减小label文件体积,加快I/O速度。

这个花生数据集的标签文件全部通过labelImg工具人工校验,并用Python脚本批量检查了所有坐标是否在[0,1]范围内、宽高是否为正数。曾发现3张图的果簇标注因操作失误导致width=0.000,这种无效标注会让YOLOv5在计算loss时产生NaN值,训练几轮后梯度爆炸。数据集已修复这些边缘错误,确保开箱即用。

3. 图像与标注质量分析:207张图如何撑起一个可靠基线?

数据集规模(207张)远小于COCO(>20万张),但农业场景的特殊性决定了“少而精”才是王道。我用一套自研的质检流程对这批图像做了深度分析,结论颠覆了很多人的直觉:

3.1 图像来源与场景覆盖:田间真实性的硬指标

所有207张图像均来自山东临沂、河南驻马店、河北邢台三地的规模化花生种植基地,拍摄时间覆盖**苗期(3-5叶)、花期(始花至盛花)、结荚期(初荚至饱果)**三个关键生育阶段。相机为大疆Mavic 3 Enterprise(4800万像素),飞行高度15-30米,地面采样距离(GSD)在1.2-2.5cm/pixel之间。这意味着:

  • 苗期图像:能清晰分辨单株幼苗的子叶和真叶形态,但植株间距小、易重叠;
  • 花期图像:黄色小花在绿叶背景中形成高对比度目标,但花量大、分布密,易造成密集小目标漏检;
  • 结荚期图像:地下果簇在土壤表面形成浅褐色凸起,与枯叶、土块颜色接近,是典型的低对比度目标。

这种按生育期分层采样的策略,比随机抓拍更能暴露模型在不同生长阶段的泛化短板。我在用YOLOv5s训练时发现,模型在结荚期图像上的Recall(召回率)比苗期低12.3%,这直接指向了模型对低对比度目标的特征提取能力不足,成为后续改进的明确方向。

3.2 标注粒度与一致性:两类目标的定义边界

“植株”和“果簇”的定义在农业实践中存在模糊地带,数据集制定了严格的标注规范:

  • 植株(plant):以第一对真叶的基部为中心,框选包含主茎、所有分枝及叶片的整体轮廓。不标注子叶(因易脱落),不框选根系(不可见)。
  • 果簇(pod_cluster):仅标注露出土壤表面的、肉眼可见的花生荚果集合体,单个荚果不单独标注;若多个荚果紧密粘连成团,则视为一个果簇;若被落叶完全覆盖,则不标注。

这个定义规避了“是否包含根系”“单个荚果是否算目标”等学术争议,直接服务于喷药、收获等农事决策——喷药需覆盖整株,收获需定位果簇群。我抽样检查了50张图的标注一致性,发现人工标注员对“果簇”的判定Kappa系数达0.89(>0.8表示极好一致性),远高于对“病斑”等细粒度目标的标注水平。这得益于前期对标注员进行了3小时田间实物对照培训,而非仅看PPT规则。

3.3 目标尺度分布:小目标检测的残酷现实

用统计脚本分析所有标注框的宽高像素值(基于原始图像尺寸),结果令人警醒:

类别平均宽度(像素)平均高度(像素)最小宽度(像素)最小高度(像素)
plant1862424258
pod_cluster63411812

这意味着,在30米航拍下,一个果簇目标在图像中可能只有18×12像素,远低于YOLOv5默认输入尺寸640×640的1%(64×64)。传统上认为“小目标”指<32×32像素,而这里近35%的果簇标注框小于这个阈值。这解释了为什么直接用YOLOv5s训练时,果簇的AP@0.5只有0.41,而植株达到0.78。数据集的价值之一,就是逼你直面这个现实:不做针对性优化,小目标检测在农业场景中注定失败。后续我通过在YOLOv5中启用--multi-scale(多尺度训练)和调整anchor尺寸(将最小anchor从32×32改为16×16),使果簇AP提升至0.63。

4. 实战训练全流程:从数据加载到mAP评估的避坑指南

拿到数据集后,真正的挑战才开始。我用YOLOv5 v6.2版本(PyTorch 1.12)完整跑通了训练-验证-推理闭环,以下是血泪总结的实操步骤与陷阱:

4.1 环境准备:版本锁死与依赖兼容性

YOLOv5对PyTorch和CUDA版本极其敏感。这个数据集在以下环境验证通过:

  • Python 3.8.10
  • PyTorch 1.12.1+cu113(CUDA 11.3)
  • torchvision 0.13.1+cu113
  • numpy 1.21.6, opencv-python 4.5.5.64

致命陷阱:不要用pip install torch安装最新版PyTorch。YOLOv5 v6.2的models/common.py中使用了torch.nn.functional.interpolate的旧参数签名,新版PyTorch已弃用align_corners=False的默认行为,会导致训练时出现RuntimeError: Input and output sizes do not match。我因此浪费了1天时间,最终解决方案是严格按官方requirements.txt安装:

pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 -f https://download.pytorch.org/whl/torch_stable.html

4.2 数据加载调试:验证管道是否通畅

在运行train.py前,务必先执行数据加载检查,避免训练到一半才发现路径错误:

python detect.py --weights yolov5s.pt --source datasets/peanut/images/val/ --conf 0.25 --save-txt

这个命令会用预训练模型在验证集上跑一次推理,并保存结果。重点观察:

  • 控制台是否输出Found 52 images(验证集图像数);
  • runs/detect/exp/目录下是否生成52个.txt文件;
  • 任意一张图的预测框是否合理(如IMG_20230415_102345.jpg上是否有明显误检)。

我第一次运行时发现detect.py报错KeyError: 'names',根源是data.yamlnames字段写成了classes,而YOLOv5 v6.2只认names。这个检查步骤能帮你提前48小时发现90%的配置错误。

4.3 训练超参调优:针对花生场景的定制化选择

YOLOv5默认超参(data/hyp.scratch.yaml)是为通用场景设计的,对花生数据集需针对性调整:

  • lr0: 0.01lr0: 0.005:农业图像背景复杂,学习率过高易震荡;
  • mosaic: 1.0mosaic: 0.5:马赛克增强对重叠植株有益,但过度使用会破坏果簇的局部纹理;
  • scale: 0.5scale: 0.3:缩放增强幅度减小,避免果簇目标被缩得太小而丢失;
  • 新增fliplr: 0.5:左右翻转增强,模拟无人机不同航向拍摄视角。

最关键的是anchor调整。原YOLOv5s的anchor尺寸(基于COCO统计)为:

[[10,13, 16,30, 33,23], [30,61, 62,45, 59,119], [116,90, 156,198, 373,326]]

而花生数据集中,果簇目标平均尺寸为63×41像素,远小于最小anchor(10×13)。我用utils/autoanchor.py脚本重新聚类,得到新anchor:

[[8,10, 12,22, 25,18], [22,48, 45,36, 48,95], [92,72, 124,158, 292,258]]

models/yolov5s.yamlanchors字段替换后,果簇检测AP提升8.2个百分点。

4.4 评估指标解读:mAP不是唯一真理

YOLOv5训练日志中的mAP@0.5(IoU阈值0.5时的平均精度)常被当作金标准,但在农业场景中需结合业务逻辑看:

  • mAP@0.5= 0.68:整体合格,但拆解看plant=0.79,pod_cluster=-0.63;
  • Recall= 0.71:意味着约29%的果簇被漏检,对收获机器人可能是致命缺陷;
  • Precision= 0.82:误检率18%,对喷药系统意味着18%的药量浪费。

我因此增加了--task val --data datasets/peanut/data.yaml --weights runs/train/exp/weights/best.pt --name eval_pods专项评估,强制只计算果簇类别的指标。结果显示,单纯提升mAP会掩盖小目标性能短板,必须用--iou 0.3(降低IoU阈值)和--conf 0.1(降低置信度阈值)来评估模型对微弱信号的敏感度。

5. 模型部署与业务集成:让检测结果真正驱动农事动作

训练出高mAP模型只是起点,如何让结果在田间地头产生价值?我以喷药机器人控制为例,说明从检测输出到物理动作的全链路:

5.1 输出解析:从tensor到可执行指令

YOLOv5的detect.py默认输出.txt文件,格式为class_id center_x center_y width height conf。但机器人控制系统需要的是地理坐标而非图像坐标。这就需要建立图像像素到GPS坐标的映射:

  • 步骤1:获取无人机POS数据(经纬度、高度、姿态角);
  • 步骤2:用相机内参(焦距、主点)和外参(旋转矩阵、平移向量)构建投影方程;
  • 步骤3:对每个检测框中心点(center_x, center_y),反解其在地面的经纬度。

这个花生数据集配套提供了10张图像的POS元数据(CSV格式),包含timestamp,lat,lon,alt,yaw,pitch,roll,focal_length。我用OpenCV的cv2.projectPoints函数实现了逆向投影,误差在±0.15米内(满足喷药作业要求)。没有POS数据?那就得用RTK-GNSS+IMU组合导航,成本增加3倍。

5.2 决策逻辑:检测结果如何转化为农事策略

检测结果本身不等于决策。例如,当模型输出plant: 0.85 confidence, pod_cluster: 0.62 confidence时,机器人该做什么?

  • 喷药场景:置信度>0.8才触发喷雾,避免对健康植株误喷;若pod_cluster置信度<0.5,则标记该区域为“疑似结荚不良”,生成巡检任务;
  • 收获场景:只响应pod_cluster,且要求连续3帧检测到同一位置,滤除运动伪影;再结合土壤湿度传感器数据,判断是否达到最佳收获期。

这个花生数据集的价值,正在于它提供了两类目标的联合检测能力,让决策系统能基于植株健康状态(通过植株检测密度推断)果实成熟度(通过果簇检测密度与大小分布)做复合判断,而非单一目标的简单计数。

5.3 边缘部署实测:在Jetson Orin上跑通实时推理

最终模型需部署到农机边缘设备。我在Jetson Orin(16GB RAM)上测试了YOLOv5s量化版:

  • FP16精度:28 FPS,功耗12W;
  • INT8精度:41 FPS,功耗9W,mAP@0.5下降1.3个百分点;
  • 关键优化:关闭--agnostic-nms(类别无关NMS),启用--max-det 100限制输出框数,减少后处理开销。

实测发现,Orin的GPU对YOLOv5的Focus层(切片操作)支持不佳,导致FP16推理延迟波动大。解决方案是将models/common.py中的Focus类替换为Conv+nn.PixelUnshuffle,虽增加少量参数,但FPS提升15%。这个修改已集成到数据集配套的yolov5_orin_patch.py中。

6. 数据集局限性与升级路线:它不是终点,而是起点

必须坦诚地说,这个花生检测数据集有明确的边界,理解它的局限性比盲目使用更重要:

6.1 当前版本的三大硬约束

  1. 光照条件单一:所有图像摄于上午9-11点、下午2-4点,未覆盖晨雾、傍晚低照度、阴雨天场景。实测表明,模型在阴天图像上的果簇Recall下降22%;
  2. 品种覆盖有限:仅包含鲁花9号、豫花15号两个主流品种,对珍珠豆型(如汕油71)的泛化能力未知;
  3. 无遮挡鲁棒性:未刻意采集被杂草、秸秆严重遮挡的样本,模型在遮挡率>40%时性能断崖式下跌。

这些不是缺陷,而是产品化过程中的优先级选择——先解决“有没有”,再解决“好不好”。就像手机第一代只能打电话,但它是移动互联网的基石。

6.2 社区共建路线图:你的贡献如何让它更强大?

这个数据集采用CC BY-NC-SA 4.0协议(署名-非商业性使用-相同方式共享),鼓励社区协作升级:

  • 短期(3个月内):开放datasets/peanut/extra/目录,接收用户提交的阴天、雨后、不同品种图像,经审核后合并入主数据集;
  • 中期(6个月):启动“花生病害子集”计划,用同一套图像,新增leaf_spotroot_rot等病害类别标注;
  • 长期(1年):构建跨模态数据集,同步采集RGB图像、热红外图像(用于水分胁迫检测)、多光谱图像(用于氮素含量反演)。

我已在GitHub仓库中创建了CONTRIBUTING.md文档,详细说明图像拍摄规范(ISO≤400、快门≥1/500s、白平衡手动锁定)、标注工具(LabelImg配置文件)、提交PR流程。每一次有效提交,都会在CHANGELOG.md中记录贡献者ID——因为农业AI的进步,从来不是一个人的战斗。

6.3 从花生到作物:方法论的迁移价值

这个数据集最珍贵的不是207张图,而是背后沉淀的农业视觉数据集构建方法论

  • 场景驱动标注:不追求学术上的“完美分割”,而是定义对农事动作有直接指导意义的目标(如“果簇”而非“单个荚果”);
  • 生育期分层采样:把作物生长周期作为核心维度,而非随机抓拍;
  • 硬件协同设计:标注规范与无人机参数(GSD、镜头畸变)深度耦合,确保数据可直接用于产线。

这套方法论已成功迁移到我们正在构建的“玉米螟虫检测数据集”中:同样按玉米的拔节期、抽雄期、灌浆期分层采样,标注目标定义为“虫孔群”(而非单个虫孔),因为防治决策依据是虫口密度而非个体数量。当你下次面对一个新作物、新病虫害时,这套方法论比任何具体数据集都更有生命力。

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

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

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

立即咨询