ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

苹果叶病害检测数据集:5类病害21119张VOC+YOLO标签

苹果叶病害检测数据集:5类病害21119张VOC+YOLO标签 简介在农业智能化与深度学习技术深度融合的今天目标检测作为计算机视觉的核心任务已广泛渗透到病害识别、农产品质检等场景。其原理在于通过边界框定位与分类让模型同时回答“目标在哪里”和“目标是什么”这依赖高质量的标注数据作为训练基础。VOC与YOLO两种主流标注格式分别以XML和归一化文本存储目标坐标兼顾了可读性与训练效率。一个规模充足、格式规范的数据集能够显著降低模型训练门槛帮助研究者和工程师将精力聚焦于网络调优与部署落地。本文围绕一份包含21119张真实苹果叶片图像、覆盖5类常见病害的检测数据集详解其双格式标签结构、训练配置技巧及常见问题排查方案。无论是农业遥感、果园巡检机器人还是移动端病害识别应用这套数据都能为迁移学习与模型迭代提供扎实起点助力AI在复杂自然环境中实现高效病害防控。 苹果叶病害检测这事我一直觉得是个特别适合练手又特别有落地价值的场景。农学背景的同学需要它做算法的人也需要它因为植物病害检测和目标检测的通用技术栈完全打通了一套流程跑通换个数据集就能迁移到别的场景。今天要聊的这份《5类苹果叶病害识别检测数据集21119张-vocyolo格式标签》从名字就能看出来它已经把数据标注这个最脏最累的活干完了而且同时给了VOC和YOLO两种主流格式省去了自己做格式转换的麻烦。不管你是刚接触目标检测的新手还是准备做模型迭代的老手这份数据都能让你把精力直接放在模型训练和调优上而不是浪费在整理数据上。1. 内容整体设计与思路拆解1.1 数据集的核心价值在哪里先别急着看文件我建议你先搞清楚这份数据集到底解决了什么问题。苹果叶病害检测本质上是一个典型的目标检测任务模型需要在图像中找出病斑的位置并且判断它属于哪一类病害。和图像分类不同检测任务不仅要回答“这张叶子有没有病”还要回答“病在哪里、是什么病”。这就对数据标注提出了更高的要求不仅要有类别标签还要有精确的边界框。这份数据集包含21119张图片5类病害这个规模在农业病害检测领域算是相当可观的了。很多公开的植物病害数据集要么是分类格式要么只有几千张检测图训练出来的模型泛化能力很有限。两万多张的样本量配合VOC和YOLO双格式标签意味着你拿到手之后不用做任何预处理直接就能喂给模型训练。5类病害的分类方式也符合实际农业场景的需求。果农在田间最常见的问题就是几种叶部病害混发如果只做二分类或者单类检测实际应用时就会很被动。多分类检测模型能够同时输出多个病害类别和位置信息这在植保无人机巡检、智能施药系统、果园病害预警平台这些场景下是刚需。1.2 双格式标签的设计逻辑很多初学者会问为什么一个数据集要同时提供VOC和YOLO两种格式只给一种不就行了吗这里面有历史原因也有实际使用的考量。VOC格式是PASCAL VOC挑战赛确立的标准它以XML文件存储标注信息每个XML文件对应一张图片内容包括图片尺寸、目标类别、边界框坐标等。这种格式的优点是可读性强方便人工检查和修改很多经典检测框架如Faster R-CNN、SSD的早期版本都依赖这种格式。YOLO格式则是随着YOLO系列算法流行起来的它用纯文本文件存储标注每行代表一个目标格式是“类别编号 中心点x 中心点y 宽度 高度”所有坐标都做了归一化处理。这种格式的优点是非常紧凑读取速度快而且和YOLO系列的训练管线无缝衔接。提供双格式的深层意义在于兼容不同开发者的工具链。如果你习惯用LabelImg做标注调整VOC格式更友好如果你直接跑YOLOv8训练YOLO格式可以省去一次转换。这个数据集相当于帮你做了双保险无论是老牌检测框架还是新锐YOLO系列拿过来都能直接用。2. 核心细节解析与实操要点2.1 VOC格式的标注文件结构拿到数据集后第一件事就是把文件结构和标注文件内容搞清楚。VOC格式的XML文件通常长这样annotation folderAppleLeaf/folder filenameimage_00001.jpg/filename size width640/width height640/height depth3/depth /size object nameApple_scab/name bndbox xmin120/xmin ymin85/ymin xmax380/xmax ymax420/ymax /bndbox /object /annotation注意几个关键点一是filename标签里的文件名必须和实际图片文件名完全一致包括扩展名二是size里的宽高必须和图片的真实尺寸一致否则训练时如果做了图像缩放坐标就会错位三是object可以出现多次代表一张图里有多个病斑。我在检查数据的时候有个习惯会先写个脚本统计一下所有XML文件里width和height的分布看看是不是所有图片尺寸都统一。如果不统一训练时虽然YOLO的letterbox会自动处理但标注框的归一化比例可能会有细微偏差微调阶段容易出现边界框抖动的问题。2.2 YOLO格式的标签文件细节YOLO格式的TXT标签文件更简洁每行五个数值分别代表类别编号、归一化中心点x坐标、归一化中心点y坐标、归一化宽度、归一化高度。归一化的意思是所有数值都在0到1之间用真实像素值除以图片宽高得到。举例来说如果一张640x640的图片里有个病斑边界框左上角在(120, 85)右下角在(380, 420)那么中心点就是((120380)/2, (85420)/2) (250, 252.5)宽度是380-120260高度是420-85335。归一化之后类别编号如果是0对应Apple_scab那么TXT文件里的内容就是0 0.390625 0.394531 0.40625 0.523438四舍五入到六位小数是标准做法。这里有个容易踩的坑有些工具生成的坐标是未归一化的绝对值YOLO训练时不会报错但损失函数会直接起飞因为模型预测的是归一化坐标标签却是像素值两者根本不在一个量级。如果你拿到数据后要跑出正常效果务必先随机找几个TXT文件验证一下数值范围。2.3 类别定义与标签映射关系5类病害涉及到的具体类别名直接决定了模型输出的含义。常见苹果叶病害包括苹果黑星病、苹果锈病、苹果灰斑病、苹果褐斑病、苹果花叶病等。这个数据集具体包含哪五类你解压之后需要第一时间查看。在YOLO格式下类别映射关系通常写在classes.txt或data.yaml文件里。类别编号的排序一旦确定训练和推理阶段必须保持一致。比如编号0是黑星病编号1是锈病训练时用这个顺序推理时也要按这个顺序输出否则模型预测的类别和实际病害就对不上了。有个实用技巧是在训练之前先用脚本把训练集和验证集里所有标注的类别编号都统计一遍看有没有某个类别编号出现次数特别少。如果某个类别的样本数量不足其他类别的十分之一这种严重不均衡的情况会导致模型对该类别的召回率极低需要针对性地做数据增强或者类别权重调整。3. 实操过程与核心环节实现3.1 数据准备与环境配置拿到数据集后我建议你先按下面的步骤整理文件结构datasets/apple_leaf/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── classes.txt └── data.yaml如果原始数据集已经是这种结构那能省不少事。如果不是就需要写脚本把VOC格式的XML转成YOLO格式的TXT或者反过来。这里我给出一个常用的VOC转YOLO脚本import os import xml.etree.ElementTree as ET def convert_voc_to_yolo(xml_file, class_names, output_dir): tree ET.parse(xml_file) root tree.getroot() size root.find(size) width int(size.find(width).text) height int(size.find(height).text) txt_path os.path.join(output_dir, os.path.splitext(os.path.basename(xml_file))[0] .txt) with open(txt_path, w) as f: for obj in root.iter(object): cls_name obj.find(name).text if cls_name not in class_names: continue cls_id class_names.index(cls_name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) x_center (xmin xmax) / 2.0 / width y_center (ymin ymax) / 2.0 / height w (xmax - xmin) / width h (ymax - ymin) / height f.write(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\n) class_names [Apple_scab, Apple_rust, Apple_gray_spot, Apple_brown_spot, Apple_mosaic] xml_dir path/to/voc_xmls output_dir path/to/yolo_labels os.makedirs(output_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if xml_file.endswith(.xml): convert_voc_to_yolo(os.path.join(xml_dir, xml_file), class_names, output_dir)这个脚本的核心逻辑其实就三步读取XML里的图片尺寸、遍历所有object节点、把像素坐标换算成归一化中心点加宽高的形式。如果你拿到的数据集已经是YOLO格式这步可以完全跳过。3.2 YOLOv8训练配置详解环境配置方面我直接推荐用YOLOv8它在小规模数据集上的表现很稳定训练和推理的速度都够快。安装方式很简单pip install ultralytics然后新建一个data.yaml文件内容如下path: /path/to/datasets/apple_leaf train: images/train val: images/val test: images/test nc: 5 names: [Apple_scab, Apple_rust, Apple_gray_spot, Apple_brown_spot, Apple_mosaic]path是数据集根目录的绝对路径train和val是相对路径nc是类别数量names是类别名称列表顺序必须和标签文件里的编号一一对应。训练命令也很直接yolo train modelyolov8s.pt datadata.yaml epochs100 imgsz640 batch16 device0我一般会把epochs设成至少100轮因为病害检测的病灶往往比较小特征也不如行人或者车辆那么明显需要更多的迭代次数来收敛。如果显卡显存不够可以把batch调小到8或者把imgsz降到480。这里有个权衡要讲清楚imgsz越大模型能看到越多的细节但训练速度越慢imgsz太小小病斑可能被压缩到几个像素检测效果会大打折扣。3.3 训练过程中的关键参数选择学习率这块我建议保持默认YOLOv8的自动学习率调度已经很成熟了。真正需要关注的是数据增强参数尤其是针对小目标的增强策略。在YOLOv8里可以用hsv_h、hsv_s、hsv_v来控制颜色抖动对植物病害检测来说适当的色彩增强可以提升模型对不同光照条件的鲁棒性因为田间采集的图像光照差异很大。还有一个参数容易忽略就是mosaic。Mosaic增强把四张图拼成一张训练对小目标检测有奇效但它也会引入一些虚假的边界框因为拼接处的目标会被裁剪。我在训练时会把mosaic设成0.8左右给普通增强留一点空间后期如果发现验证集mAP上不去再试着调低。训练过程中的实时监控也很重要。不要只在训练结束后看结果训练过程中就要关注vail_mAP的变化趋势。如果前20轮mAP纹丝不动大概率是数据格式或者类别映射出了问题这时候及时止损排查比等100轮跑完再返工要省时间得多。3.4 模型评估与结果解读训练完成后YOLOv8会在runs/detect/train目录下生成一系列结果文件。重点关注results.png里的曲线图和confusion_matrix.png混淆矩阵。mAP50和mAP50-95这两个指标要结合起来看。mAP50是IoU阈值0.5时的平均精度更宽容主要反映模型能不能大致框住目标mAP50-95是多个IoU阈值下的平均效果更严格能够反映边界框的精确程度。对病害检测来说mAP50达到90以上说明检测基本可用mAP50-95如果能到70以上就算很不错了。混淆矩阵能告诉你每一类病害之间是否存在严重混淆。苹果锈病和褐斑病在视觉上有时候确实像如果混淆矩阵里这两个类别的交叉值偏高说明需要补充更多难以区分的样本或者针对性地做增强。4. 常见问题与排查技巧实录4.1 标签格式不对导致训练异常这类问题在自建数据集里几乎一定会碰到。最常见的情况是打开YOLO格式的TXT文件发现坐标值大于1比如0 320 240 130 90这就是没有归一化。此时模型训练不会报错但loss会居高不下mAP几乎为0。排查方法很简单用一个小Python脚本扫描所有标签文件检查是否存在大于1的数值。另一个常见问题是类别编号超出范围。如果classes.txt里定义了5个类别但某个TXT文件里出现了5 0.5 0.5 0.1 0.1这样的行训练时就会报类别编号越界的错误。这种错误在数据量大的时候不容易发现最好是训练之前做一次全量扫描。4.2 图片和标签文件不对应场景你明明把训练集和标签都放好了训练时却提示找不到某个标签文件或者某个图片没有对应的标签文件。原因可能是解压过程中文件名被截断或者是大小写不一致。我有个习惯是训练前先跑一遍校验脚本检查三件事图片文件是否能被OpenCV正常读取、每个图片帧是否有对应的TXT文件、TXT文件里的坐标是否在合理范围内。这个脚本虽然简单但能避免95%以上的训练中断问题。import os import cv2 img_dir path/to/images/train label_dir path/to/labels/train for img_name in os.listdir(img_dir): img_path os.path.join(img_dir, img_name) img cv2.imread(img_path) if img is None: print(fCannot read: {img_path}) continue label_path os.path.join(label_dir, os.path.splitext(img_name)[0] .txt) if not os.path.exists(label_path): print(fMissing label: {label_path})4.3 小目标检测效果差苹果叶病害有个特点早期病斑非常小可能只占整张图片的千分之几。如果你用默认的YOLOv8模型训练小目标的召回率可能不理想。解决方案有三个方向一是把imgsz从640提高到960甚至1280让小目标在输入图像里占据更多像素二是用YOLOv8的P2层输出它保留了更大分辨率的特征图对小目标更敏感可以通过yolo train modelyolov8s-p2.yaml来启用三是在推理时用TTA测试时增强或者多尺度推理虽然速度慢一点但能提升准确率。4.4 类别不平衡的应对策略假设黑星病样本有12000张花叶病只有1200张模型训练时就会严重倾向于黑星病。这种时候有几个办法。最简单的是调整每个类别的采样权重。在YOLOv8里可以通过数据集中每个类别的样本数量来做一个重采样让模型在每个epoch里看到每个类别的次数差不多。但这样做要注意不能彻底破坏数据的自然分布否则训练出来的模型在真实场景里反而会因为先验概率错位而误判。另一招是离线做数据增强。对样本量少的类别可以额外生成一些图片例如旋转、缩放、色彩抖动、加噪声等把这一类别的样本补充到和多数类别差不多。做的时候要控制增强的幅度别把病害特征增强得面目全非否则模型学到的是增强痕迹而不是病害本身。5. 数据集的实用场景扩展5.1 从检测到分类的迁移方案拿到这个检测数据集之后除了直接做目标检测还可以做一件很实用的事情把检测模型当作特征提取器训练一个病害分类模型。这个思路在计算资源有限时特别有用。具体做法是先用这个数据集训练YOLO检测模型然后把检测模型的骨干网络权重导出再接一个简单的全连接分类头在自己的分类数据上微调。因为检测模型已经在两万多张叶片图像上学到了丰富的纹理和颜色特征这些特征对病害分类同样有效。实测下来这种迁移方式需要的标注数据量能少50%以上。5.2 在农业智能设备上的部署思路检测模型最终要落地常见场景包括手机拍照识别、果园巡检机器人和植保无人机。不同场景对模型的轻量化要求不同。手机端可以尝试YOLOv8n或者YOLOv8n-seg配合NCNN或者TensorRT Lite进行部署。果园巡检机器人可以使用Jetson系列设备跑YOLOv8s或者YOLOv8m都没有压力关键要看推理帧率是否满足机器人的移动速度。植保无人机需要考虑拍摄高度和病斑尺寸的匹配问题如果飞行高度在3米以上病斑在图像中占比会更小这时要考虑用更高分辨率的相机或者调整飞行策略。这个数据集的价值就在这里它把模型训练的基础打牢了你只需要针对具体的部署硬件做模型压缩和推理优化就行。农业场景的环境复杂度高光照变化大背景干扰多想要一个好用的模型数据层面的投入比算法层面的投入更值得花时间。从我个人经验来看用这份数据集跑出来的模型在类似场景的验证集上通常都能达到不错的基线水平。大家拿到手之后不要急着改模型结构先跑一个baseline记录各项指标然后再逐步优化。很多问题在baseline阶段就能暴露出来解决了这些基础问题后面调优才会有的放矢。本文还有配套的精品资源点击获取
返回列表