荔枝成熟度检测数据集:基于YOLO与VOC格式的农业目标检测实践

荔枝成熟度检测数据集:基于YOLO与VOC格式的农业目标检测实践
简介本资源是面向农业AI与计算机视觉初学者的目标检测专用数据集聚焦荔枝果实成熟度智能识别这一典型应用场景适用于模型训练、算法验证及课程实验。数据集共1739个文件包含579张高质量实景荔枝图像JPG、579份Pascal VOC格式XML标注文件含边界框与三类标签及579份YOLO格式TXT标注文件适配主流框架总容量29.5MB结构规整、开箱即用。已有291人学习下载反映出该细分农业视觉任务日益增长的实践需求。用户可直接用于YOLOv5/v8、Faster R-CNN等模型训练三类标签green/half/red覆盖完整成熟梯度总标注框达2911个且全部由labelImg人工精标图像命名规范、无路径依赖便于快速构建训练流水线与评估基准。 判断一颗荔枝是不是熟了人眼一秒就能出结果但让机器自动干这件事却远比想象中复杂。树下光线忽明忽暗果实一簇挨着一簇绿叶和红果交叠遮挡反光、远近、阴影……这些在日常采摘中完全不是问题的情况落到目标检测模型里全成了拦路虎。整理这份荔枝成熟检测数据集时我最大的感受是真正有价值的不只是579张图和3个类别而是这套数据背后一整套关于农业视觉落地的思考——采集什么场景、怎么定义成熟度边界、VOC和YOLO格式怎么组织才能让模型训练少踩坑。这份数据集面向的是一类非常典型的需求用目标检测算法对自然生长状态下的荔枝进行成熟度识别类别划分为绿果、半红果、红果三种状态同时提供VOC和YOLO两种主流标注格式拿到手就能直接训练YOLOv5、YOLOv8、SSD、Faster R-CNN这些常见检测模型。无论你是正在做毕业设计的学生、刚入门目标检测的开发者还是准备做采摘机器人或果园智能化改造的从业者这套数据都能帮你跳过最耗时耗力的标注环节把精力放到模型调优和场景适配上去。1. 为什么单独做一个荔枝成熟度检测数据集1.1 成熟度分级是荔枝产业里绕不开的环节荔枝和大多数水果不太一样它在采摘之后并不会继续明显转色采下来的果子是什么成熟度卖出去就是什么状态。这就意味着分拣、定价、储运决策都必须在上游完成。人工判断是目前的主流方式果农靠经验看果皮颜色、摸刺感、掂重量但人工分拣的问题非常现实效率低、标准不统一、连续工作久了眼睛容易疲劳不同的人对半红的理解可能完全不一样。从技术角度讲荔枝成熟度检测是一个典型的细粒度目标识别任务。它不像猫狗分类那样类别间差异极大绿果、半红果、红果之间是一个连续变化的成熟过程类别边界存在大量过渡状态。一个果皮上带着几块红斑的荔枝究竟算半红还是算红不同标注员可能给出不同答案这种标注不确定性会直接影响模型训练效果。所以这个数据集的第一个价值就是帮你把成熟度这个模糊概念固化成可训练的视觉标注规范。我在整理标注规范时采用的是比较通用的划分方式果皮整体呈绿色或仅微带黄绿判定为绿果果皮红色面积超过50%且仍有明显绿色区域判定为半红果果皮基本全红允许少量绿色残留在果蒂附近判定为红果。这个标准参考了农产品分级中常见的转色率思路执行起来相对客观模型学起来也更容易收敛。1.2 目标检测比图像分类更适合果园真实场景做农业视觉初期容易掉进一个误区我只需要知道这片果园里的荔枝熟没熟是不是做个图像分类就够了真实情况远没有这么简单。果园里的荔枝是成串生长的同一串果子上可能同时存在绿果、半红果、红果甚至同一颗果子的向阳面和背阴面成熟度都不同。如果只用图像分类模型只能给出这张图整体偏熟或这张图整体偏生的结论这对实际决策几乎没有参考价值。目标检测则完全不同它输出的是每个果实的位置和类别也就是图片里哪里有荔枝、这个荔枝是什么成熟度。采摘机器人需要知道机械臂往哪个坐标抓分拣流水线需要知道传送带上的每一颗果子该分到哪个通道果园巡检无人机需要统计不同成熟度的果实数量来预估产量这些任务全都依赖位置信息。相比图像分类目标检测天然更适合农业场景这也是我一直推荐做这类项目时优先考虑检测方案而不是分类方案的原因。另外检测模型还能顺便输出果实数量。传统做法是农业专家通过人工抽样估算产量一棵树摘几串算平均误差往往不小。检测模型直接输出果实的bounding box数一数框的数量配合成熟度信息就能同时得到这棵树有多少果和其中多少熟的多少没熟两个关键数据这个组合能力是分类模型完全给不了的。1.3 哪些人需要这份数据高校学生作为目标检测课程设计或毕业论文的数据支撑3类别、579张的规模足够跑通完整训练和评估流程VOC和YOLO双格式也方便直接套用主流开源代码。算法工程师做农业AI或智慧农业项目预研时用这套数据先验证模型选型和参数配置的可行性再决定是否投入资源标注更大规模的数据。竞赛选手目标检测类比赛或农业场景算法挑战赛这套数据可以作为类别定义和数据格式的参考模板。农业科技创业者做采摘机器人、果园巡检无人机、采后分拣设备的原型验证阶段需要一批高质量的真实场景数据来跑demo吸引投资或申报项目。2. 579张3类别数据集的规格拆解与标注边界2.1 数据规模579张到底够不够用第一次看到579张这个数字很多人第一反应是这么少能训练出模型吗我的回答是看你的目标是什么。如果是为了跑通整个目标检测流程、验证算法在荔枝成熟度识别上的可行性、完成课程设计或原型demo579张完全够用。COCO数据集里有12万张图但那是为了让模型学会检测全世界的物体。你的任务只有一个——检测荔枝并区分三个成熟度场景高度聚焦类别间差异相对明确这种单一目标的小规模数据训练出来的模型实际效果往往超出预期。但如果要部署到真实果园环境应对不同品种荔枝、不同光照条件、不同拍摄距离和角度579张就远远不够了。农业场景的特殊性在于环境变量极其复杂早中晚的光线不同晴天阴天的色温不同喷灌后叶面上的水珠会带来大量反光这些在实验室环境里根本预想不到的干扰都会让模型泛化能力断崖式下降。这种情况下我的建议是把这份数据当作基座用它完成初步训练后再针对目标果园采集视频抽帧扩充数据或者用训练好的模型做半自动标注把人工成本降到最低。2.2 三个类别的视觉特征与标注边界三个类别的划分是整个数据集的核心也是标注时最容易产生分歧的地方。整理一下我在标注时界定的标注规范类别视觉特征判定要点Green绿果果皮整体为绿色或黄绿色表面无红斑或仅针尖大小零星红点红色面积小于5%Semi-Red半红果果皮红绿相间红色区域与绿色区域交错分布红色面积5%-80%Red红果果皮基本为红色允许果蒂连接处有少量绿色残留红色面积大于80%标注半红果时最容易出现争议。同一颗果子从不同角度看红色面积比例差异很大向阳面一片红转到背面却有一大半还是绿的。我们的处理原则是按图像中实际可见的区域做判断不去脑补果实背面的状态。模型训练的也是从图像可见特征中学习规律这个原则能让标注一致性大幅提升。另外要注意的是标注框中果实被遮挡的情况。荔枝是簇生水果经常出现好几颗果子挤在一起、互相遮挡。对于遮挡严重的果实如果可见面积过小比如只有不到30%的果皮露出来我们选择不标如果大部分果皮可见只被枝干或叶子挡住一部分就正常标注。这个细节看似不起眼实际对训练效果影响很大——模型会从标注框学习特征的完整性把一个被叶子挡住一大半的果子标成完整框模型就会困惑被挡住的荔枝到底算什么。2.3 图片内容的多样性构成579张图片如果全部来自同一棵树的同一个角度那训练出来的模型基本没有迁移价值。所以数据构成的多样性非常关键。我在整理这份数据集时对图片多样性做了比较严格的控制不同成熟阶段的荔枝都有覆盖从全绿到半红到全红的比例大约为1:1:1避免类别不平衡问题。拍摄角度覆盖平视、俯视、仰视有单颗果实的特写也有整串多果的中景。包含部分复杂背景如叶子遮挡、枝干穿插、多果重叠、果实与背景颜色相近等情况。图片分辨率多样有高分辨率特写也有部分包含果园整体环境的广角画面提升模型对不同尺度的适应能力。这种多样性不是随意凑出来的而是根据真实果园场景的需求倒推的。你最终部署时面对的相机角度、环境光照、果树形态往往千差万别如果训练数据太干净模型一到真实环境就会严重掉点。3. VOC和YOLO两种标注格式的来龙去脉3.1 VOC格式人类可读的XML标注VOC格式源自PASCAL VOC挑战赛是老牌目标检测数据集的标准格式也是工业界和学术界通用性最强的标注格式之一。它的核心是每张图片对应一个同名的XML文件标注信息以XML标签形式存储结构清晰直接用文本编辑器就能打开查看。一个典型的VOC标注文件关键字段如下annotation folderJPEGImages/folder filenameIMG_001.jpg/filename size width1280/width height720/height depth3/depth /size object nameSemi-Red/name bndbox xmin214/xmin ymin156/ymin xmax386/xmax ymax329/ymax /bndbox /object /annotation其中size字段记录图片的宽、高和通道数object表示一个标注目标name是类别名称bndbox里的xmin、ymin、xmax、ymax是该目标bounding box的左上角和右下角坐标单位是像素。一张图里有多个果实就有几个object节点。VOC格式最大的优点是直观任何标注工具LabelImg、LabelStudio、CVAT等都原生支持修改和检查都很方便。缺点是文件体积相对较大包含大量冗余信息读取速度不如纯文本格式快。3.2 YOLO格式模型训练的极简格式YOLO格式是Ultralytics等框架默认使用的标注格式每个目标对应一行文本五个数值依次是类别编号、中心点x坐标、中心点y坐标、框宽度、框高度。最关键的一点是后四个数值全部进行了归一化处理除以图片的实际宽和高范围在0到1之间。以一张1280x720的图片为例某个红果bounding box的左上角坐标为(416, 156)右下角为(768, 518)对应YOLO格式的计算过程如下x_center (416 768) / 2 / 1280 592 / 1280 0.4625 y_center (156 518) / 2 / 720 337 / 720 0.4681 width (768 - 416) / 1280 352 / 1280 0.275 height (518 - 156) / 720 362 / 720 0.5028对应的YOLO标注行就是2 0.4625 0.4681 0.2750 0.5028YOLO格式的优点极其突出每行都是纯数字的归一化坐标不受图片分辨率变化影响读取效率高训练框架解析起来非常快。缺点是可读性差肉眼直接看txt文件很难判断标注是否合理必须借助可视化工具。而且不同版本YOLO的类别编号映射规则可能不同切换框架时需要通过names配置文件保证类别顺序一致。3.3 两种格式的转换逻辑VOC和YOLO之间的转换并不复杂核心就是把XML里的像素坐标换算成归一化的中心点坐标。这里给出一个最简转换公式VOC转YOLO时x_center (xmin xmax) / 2 / width y_center (ymin ymax) / 2 / height w (xmax - xmin) / width h (ymax - ymin) / height反向转换YOLO到VOC时xmin (x_center - w/2) * width ymin (y_center - h/2) * height xmax (x_center w/2) * width ymax (y_center h/2) * height实际操作时有两个非常容易踩的坑。第一个是坐标边界问题归一化坐标经过四舍五入或者浮点计算后还原出来的像素坐标可能超出图片范围比如xmin小于0或者xmax大于width转换脚本里要做clip操作。第二个是类别编号映射问题VOC里存的是类别名称字符串Green、Semi-Red、RedYOLO里存的是整数编号0、1、2转换时必须建立一份统一的类别映射表否则训练时类别会全部错乱。4. 用YOLOv8把数据集真正跑起来4.1 项目目录结构拿到数据集后第一件事不是急着训练而是把目录整理成YOLO框架认识的格式。YOLOv8的目录结构要求比较简单我这里以一份经典的划分方式为例litchi_dataset/ ├── images/ │ ├── train/ # 训练集图片 │ ├── val/ # 验证集图片 │ └── test/ # 测试集图片 ├── labels/ │ ├── train/ # 训练集标注txt │ ├── val/ # 验证集标注txt │ └── test/ # 测试集标注txt └── data.yaml # 数据集配置文件需要注意的关键点是images目录下train里的某张图片必须在labels目录下train里存在同名的txt文件图片和标注文件通过文件名一一对应。这种图片和标注分离、通过文件名对应的组织方式是YOLO系列框架约定俗成的习惯修改任何一张图片名称时都要同步修改对应的标注文件名。4.2 标注文件可视化检查训练前强烈建议做一次标注可视化检查。用LabelImg或labelme打开几张训练图片把标注框叠加显示出来逐个确认框的位置是否贴合果实边界、类别是否标错、有没有漏标。这一步看起来费时实际上非常值——我遇到过不少次数据整理完直接训练结果发现某张图的标注框整体偏移了几十像素模型训练出来mAP惨不忍睹回头排查了半天才发现是标注文件被批量处理搞坏了。对于YOLO格式的txt文件也可以用Python脚本快速检查是否存在非法数值import os label_dir litchi_dataset/labels/train for f in os.listdir(label_dir): if not f.endswith(.txt): continue with open(os.path.join(label_dir, f), r) as fp: for line in fp: parts line.strip().split() if len(parts) ! 5: print(f格式错误: {f}) cls_id int(parts[0]) values [float(x) for x in parts[1:]] if cls_id not in [0, 1, 2]: print(f类别编号越界: {f}) if any(v 0 or v 1 for v in values): print(f坐标未归一化: {f})这段脚本能把最常见的标注文件问题都扫出来训练前跑一遍能省掉大量排查时间。4.3 配置data.yaml和训练参数data.yaml是整个训练过程的枢纽文件它告诉YOLOv8数据集在哪里、有几个类别、类别名称是什么。标准的data.yaml内容如下path: /path/to/litchi_dataset train: images/train val: images/val test: images/test nc: 3 names: [Green, Semi-Red, Red]这里特别强调names列表的顺序必须和标注txt中的类别编号一一对应。如果txt文件里类别0是Greennames就必须把Green放在第0位顺序一旦错位模型训练出来所有框的类别就全错了而且这种错还特别隐蔽不仔细看可视化结果根本发现不了。训练命令可以直接用ultralytics框架完成推荐从YOLOv8s模型开始pip install ultralytics yolo detect train \ datalitchi_dataset/data.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ project./runs \ namelitchi_yolov8s几个关键参数的设置思路modelyolov8s.pt表示加载COCO预训练权重开始迁移学习。虽然COCO数据集里并没有荔枝这个类别但模型已经学会的底层特征——边缘、纹理、颜色、形状——对于任何视觉任务都是通用的。这比从零训练效果好得多收敛速度也快得多。epochs设置100轮是一个相对保守的默认值在模型验证集上效果不再提升时YOLOv8会自动早停所以多设一点也不会浪费时间。imgsz640是速度和精度的折中选择。如果果实偏小可以尝试896或1280等更高分辨率但显存占用会成倍增加。batch大小取决于显卡显存8GB显存设置16相对安全显存不够就回退到8。4.4 训练结果的评估指标怎么看训练结束后程序会输出一组评估指标最核心的是mAP50和mAP50-95分别代表IoU阈值为0.5时的平均精度均值以及从0.5到0.95多个IoU阈值下的平均精度均值。mAP50相对宽容只要预测框和真实框的重叠面积超过一半就算预测正确mAP50-95严格得多要求框的位置非常精准才能得高分。在579张这样的小规模数据集上跑出一个mAP50在0.75到0.9之间的模型是完全可能的。如果结果远低于这个水平多半是数据或配置出了问题建议优先检查类别编号是否错乱、标注框是否有大量偏移、不同类别图片数量是否严重不均衡。另外一个容易被忽视的问题是验证集的划分方式。做随机划分时同一种光照条件下拍摄的相似图片可能同时出现在训练集和验证集里导致验证集分数虚高。如果你的应用场景是部署到另一个完全不同的果园更合理的方式是按拍摄地点或拍摄时间划分数据保证验证集的图片分布和训练集有明显差异这样得到的评估指标才能真实反映模型的泛化能力。5. 农业目标检测落地时的关键坑与应对方案5.1 果实重叠和遮挡的标注策略荔枝成串生长的特性决定了重叠遮挡无法避免。一串荔枝上可能有七八颗果子挤在一起相互遮挡面积超过一半这种情况在标注时是最需要拿捏分寸的。我的处理经验是如果一颗果实的可见面积超过50%就标注完整框也就是包含被遮挡部分的完整外接矩形如果可见面积低于50%直接放弃标注。模型学的是从可见像素预测果实位置的能力一个被挡住大半的果实强行标一个完整框反而会让模型学到错误的特征关联。这里还涉及一个目标检测中常见的遮挡导致的正样本缺失问题物体的大部分区域被遮挡时即使人眼能通过少量边缘推断出完整果实模型也往往会漏检。为了解决这个问题训练数据里需要刻意保留一部分轻中度遮挡的样本让模型学会从局部特征推断完整目标而不是只认识完整露出的果实。5.2 光照、反光和背景干扰农业场景里光照完全不受控制。太阳直射时荔枝表面会形成高光反射区红色果皮上的高光会让模型误以为是浅色区域多云天气的散射光下同一个果子颜色看起来完全不同逆光拍摄时果实变成剪影颜色信息完全丢失。数据增强是应对光照变化的主要手段HSV色域变换、亮度调整、对比度调整都能模拟不同光照条件YOLOv8训练时默认开启了部分增强但为了提升在真实天气下的稳定性还可以额外增加亮度扰动范围。背景干扰是最让我头疼的问题。荔枝树的叶子颜色和绿果颜色非常接近果实边缘和叶片边缘经常融合在一起检测模型容易把圆形的叶子误判为绿果或者把绿果漏掉。在标注数据时可以适当加入一些负样本图片也就是不包含任何荔枝的纯树叶、树干、天空图片让模型学会区分没有目标的情况。这种方法在降低误检率上非常有效。5.3 小目标检测与模型轻量化579张图片中包含不少远景画面果实只占几十个像素属于典型的小目标检测场景。YOLOv8的检测头对8x8到32x32的小目标响应本身就偏弱训练时可以通过Tiling策略把大图切成多个有重叠的patch分别检测或者使用SAHI这类切片推理工具做推理增强。如果部署端显存和算力允许适当调大imgsz也是一条路。另一个方向上如果模型要部署到Jetson Nano、树莓派这类边缘设备上就需要做模型轻量化。可以在训练阶段直接选择YOLOv8nnano版本或者在训练完成后用TensorRT对模型进行INT8量化推理速度能提升数倍精度损失通常在2到5个百分点以内部署价值很高。6. 数据集之外的延展思路6.1 从成熟度检测到产量预估拿到检测结果之后你可以往两个最有价值的方向延展。第一个是产量预估统计每棵果树上红果、半红果、绿果的数量结合单果平均重量就能估算出整棵树的产量。如果配合无人机定期巡检建立时间序列数据还可以绘制整个果园的成熟度随时间变化曲线指导采摘计划安排——哪片果园先采、哪片再等几天决策依据一目了然。6.2 从静态检测到实时采摘辅助第二个方向是结合机械臂或移动端设备做实时检测。以采摘机器人为例视觉系统实时识别画面中果实的位置和成熟度把成熟红果的坐标传给机械臂控制模块。这种情况下还需要额外考虑相机标定和坐标转换问题——模型输出的框坐标是基于图像的要换算成机械臂基座坐标系里的三维位置标定误差过大时抓取精度会大打折扣。如果只做移动端辅助识别比如帮助果农用手机快速判断一簇荔枝的成熟状态那就可以直接用NCNN或TensorRT Lite做端侧部署YOLOv8n量化后模型体积不到10MB手机上推理延迟能控制在100毫秒以内。6.3 数据增强和主动学习如果决定在这份数据集基础上扩充更大规模数据我的建议是不要盲目采集大量图片然后纯人工标注效率太低了。先用这份579张数据训练一个初步模型然后把它部署到你想覆盖的新场景中用模型自动预测一大批未标注图片人工只需要修正那些置信度较低或模型明显误检的样本再把修正结果回填训练集。这就是主动学习思路我能切身体会它的价值——用这个方案我整理1000张新场景数据的标注时间比传统全人工标注至少节省了一半以上。7. 一点个人经验总结做农业视觉项目越久我越认同一个道理数据集的质量直接决定了模型效果的天花板而模型训练只是在不断逼近这个天花板。拿到这份579张的数据集时我建议不要急着一股脑跑训练先花一点时间把图片和标注仔细看一遍用可视化工具逐个检查标注框的位置和类别这份功夫永远不会白费。有一个小技巧值得分享训练过程中把每轮的验证集预测结果图片保存下来隔一段时间翻看一次。你会发现模型先学会的是找荔枝然后学会区分绿色和红色最后才慢慢学会识别半红果这种中间态。这种先粗后细的学习过程其实是数据分布最直观的反馈——如果训练到50轮后模型还是很稳定地把半红果标成红果很有可能是半红果的训练样本太少或者标注边界有问题这时候不是继续调参而是应该回到数据本身去找原因。这套流程走通之后框架是可以迁移的。柑橘、芒果、苹果、番茄这些有着明显成熟度色差的水果几乎都可以用同样的思路建数据、做训练、做部署。希望这份数据集能帮你少走一些弯路把精力留到更有价值的地方。本文还有配套的精品资源点击获取

最新新闻

日新闻

周新闻

月新闻