简介:棉花叶部病害检测专用标注数据集,面向计算机视觉与智慧农业方向的研究者、学生及开发者,可用于目标检测模型的训练与评测。资源内含977张640×640分辨率的棉花叶片jpg图像,并为每张图片配备Pascal VOC格式xml标注文件与YOLO格式txt标注文件,覆盖22类病害,满足多种深度学习框架的数据输入要求,省去采集图像与人工标注的繁琐流程。压缩包共2000个文件,以979个txt标签文件、977个xml标注文件为主,另有44张jpg图像,整体大小47.86MB,体积适中便于下载与管理。文件命名统一有序,易于进行训练集与验证集的划分。目前已有313人学习浏览该资源。获取这份数据集后,可直接衔接YOLOv5、YOLOv8、SSD、Faster R-CNN等主流检测模型的训练流程,帮助使用者在棉花病害识别任务上快速搭建实验环境,集中精力进行模型调优与精度验证,尤其适合需要标准数据集开展课题研究或项目开发的中高级开发者。
1. 棉花叶子病害检测数据集是什么:977张22类别的VOC+YOLO双格式包
做农业视觉的人经常卡在数据上:棉花叶子病害类别多、相似度高,病斑大小差异也大,很多公开数据集要么贴一张照片给一个标签,要么标注框画得随意,训练出来的模型一换地块就崩。这份“棉花叶子病害检测数据集VOC+YOLO格式977张22类别”恰好是目标检测任务可以直接用的形态。977张图不算多,但22个类别覆盖了常见叶部病害和生理性损伤,而且同时提供VOC XML和YOLO TXT两种标注,意味着你既可以用YOLOv5/YOLOv8按原样训练,也可以把标注导进LabelImg、CVAT等工具继续修,不用自己写一轮转换。下面从解压、格式校验、转换脚本、训练配置到数据增强,给出一套能落地的处理流程。
2. 先解压7z再验货:VOC与YOLO目录结构及标签对应关系
拿到这个.7z文件,第一件事不是急着训练,而是把目录拆开看结构、确认标注格式、抽查边界框是否和图像对得上。很多模型的“低分”不是模型问题,而是数据目录和标签格式被破坏。7z 压缩率比 zip 高,适合打包图像和 XML 混合的小文件,但解压工具链在 Linux 和 Windows 上不一样。
2.1 Linux 和 Windows 下解压7z的最小操作
Linux 上常见的解压命令是:
sudo apt install p7zip-full 7z x 棉花叶子病害检测数据集VOC+YOLO格式977张22类别.7z -o./cotton_diseasex表示保留完整路径,-o指定输出目录,注意-o后面不能有空格。如果你只是想看看里面有什么,用7z l 文件名.7z列目录。Windows 上可以用 7-Zip 图形界面,右键解压即可;也可以用命令行7z.exe x 文件名.7z -oc:\cotton_disease。解压后建议检查文件数量:
find . -type f | wc -l977 张图像如果每张配套 XML 和 TXT,那么文件总数大约在 2900 以上,除非某些文件缺失。这里“大约”是因为有些数据集可能只给其中一种格式,或者额外附带classes.txt、train.txt等索引文件,所以先用文件数量做初步判断。
2.2 VOC与YOLO两种标注格式的字段差异
VOC 格式用 XML 描述每个目标的类别名和边界框,框是xmin, ymin, xmax, ymax的绝对像素坐标;YOLO 格式用 TXT 描述,每行是class_id x_center y_center width height,其中中心点和宽高都是除以图像宽高后的浮点数。以一张棉花叶片图像为例,VOC XML 片段如下:
<annotation> <filename>leaf_001.jpg</filename> <size> <width>1280</width> <height>720</height> <depth>3</depth> </size> <object> <name>leaf_curl</name> <bndbox> <xmin>126</xmin> <ymin>98</ymin> <xmax>342</xmax> <ymax>287</ymax> </bndbox> </object> </annotation>对应的 YOLO TXT 内容应该是:
3 0.182812 0.267361 0.168750 0.262500这里的class_id=3取决于你定义的类别顺序。如果数据集自带classes.txt,顺序以它为准;如果只有 XML,你需要自己固定顺序。转换时最容易犯的错误是忘了框必须完全位于图像内部,或者某些 XML 的 width/height 与真实图片尺寸不一致,转出来的归一化坐标全是错的。
2.3 用脚本抽查标签框是否对齐
手动看几百张图不现实,但可以写一个快速脚本,把 YOLO 标签画回图像上,肉眼检查十张就够发现问题。常见做法是加载图像和对应 txt,然后绘制矩形:
import cv2 img_path = "images/leaf_001.jpg" txt_path = "labels/leaf_001.txt" img = cv2.imread(img_path) h, w = img.shape[:2] with open(txt_path) as f: for line in f: cls, 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(cls)), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imwrite("check_leaf_001.jpg", img)这段脚本把每个框的中心点坐标换算回像素,并画出类别 ID。如果框跑到图像边缘之外,说明要么标签错误,要么图像被 resize 过而没有同步更新标注。建议对每个类别至少抽查一张,写一个循环批量输出预览图。
提示:如果图像名和标签名不一致,先做一次批量改名,确保
leaf_001.jpg对应leaf_001.txt。这是本地训练最常踩的坑。
3. 从VOC到YOLO:转换脚本、类别映射与常见坑
虽然这个数据集标题写了“VOC+YOLO格式”,但实际收到的压缩包有时只有其中一种,或者 YOLO 标签的类别顺序和classes.txt不一致。自己掌握转换脚本是一个必要技能,将来你在 CVAT 上标注完导出 VOC,也要用它转 YOLO。
3.1 基于xml的转换脚本写法
下面是一个把 VOC XML 转成 YOLO TXT 的 Python 脚本,假设所有 XML 在一个目录下:
import os import xml.etree.ElementTree as ET from glob import glob class_names = ["bacterial_blight", "leaf_curl", "whitefly", "spider_mite", ...] # 按你的类别顺序 def convert(xml_file, out_dir): tree = ET.parse(xml_file) root = tree.getroot() img_w = int(root.find("size/width").text) img_h = int(root.find("size/height").text) base = os.path.splitext(os.path.basename(xml_file))[0] with open(os.path.join(out_dir, base + ".txt"), "w") as f: for obj in root.iter("object"): name = obj.find("name").text if name not in class_names: continue cls_id = class_names.index(name) box = obj.find("bndbox") xmin = float(box.find("xmin").text) ymin = float(box.find("ymin").text) xmax = float(box.find("xmax").text) ymax = float(box.find("ymax").text) xc = ((xmin + xmax) / 2) / img_w yc = ((ymin + ymax) / 2) / img_h bw = (xmax - xmin) / img_w bh = (ymax - ymin) / img_h f.write(f"{cls_id} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}\n") os.makedirs("yolo_labels", exist_ok=True) for xml_file in glob("voc_annotations/*.xml"): convert(xml_file, "yolo_labels")参数说明:class_names列表顺序决定类别 ID,必须和后续训练时data.yaml里的names保持一致;size/width和size/height是原始图像像素尺寸,不能使用压缩后的图像尺寸;写入 txt 时保留 6 位小数足够,不需要过度精确。
3.2 类别文件写错导致训练loss异常
训练 YOLO 时,data.yaml中的类别顺序必须和 TXT 里的 class_id 一一对应。例如你的class_names是["bacterial_blight", "leaf_curl", "whitefly", ...],但data.yaml里写成了["leaf_curl", "bacterial_blight", ...],那么模型训练的监督信号会整体错位,表现为训练初期 loss 下降很慢,验证集 mAP 始终在低水平震荡。
验证方法很简单,随机挑一张训练图,打印cls_id对应的类别名,再用模型推理同一张图,对比预测的类别名。脚本思路如下:
with open("labels/leaf_001.txt") as f: line = f.readline() cls_id = int(line.split()[0]) print("gt:", class_names[cls_id])同时把 yaml 里的 names 也打印出来,人工核对。这种错位不会导致报错,但会让你的 22 类模型实际在学 22 个错误标签,属于最隐蔽的数据问题之一。
3.3 边界框归一化与图像尺寸
YOLO 的 txt 坐标要求以图像宽高为分母。如果某些 XML 里的width是 1280,但实际图像被缩放到 640,那么转出来的坐标会整体放大,导致训练时计算 loss 的边界框错位。建议在转换前统一检查图像实际尺寸,用 OpenCV 读一次:
import cv2 img = cv2.imread("images/leaf_001.jpg") print(img.shape) # (height, width, depth)如果你的输入图像尺寸不统一,YOLO 训练时会自动做 letterbox resize,但标签坐标是在原始尺寸上归一化的,所以只要保证 XML 里的 size 与原始图像一致即可。不要先手动 resize 图像再导入标注,除非你同步重新计算每个框的坐标。
提示:对于 22 类别的细粒度病害识别,边界框不能画太大——把整个叶片框住虽然能训练,但会让模型学到“叶片=病害”,无法区分病斑位置。检查标注时留意框是否紧贴病斑区域。
4. 用YOLOv8在棉花病害数据上训练自己的检测模型
拿到双格式数据集后,常见做法是直接用 YOLO 格式开始训练。目前 YOLOv8 仍是社区里兼容性最好、上手成本最低的目标检测框架,官方 weights 对中小数据集也能快速收敛。下面按 YOLOv8 的目录约定来组织棉花病害数据。
4.1 数据集目录安排与yaml配置
YOLOv8 要求图像和标签分开放,但在同一个根目录下。推荐结构:
cotton_disease/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml把 977 张图按 7:2:1 或 8:2 划分到 train 和 val。注意划分时要保证同一张图的 image 和 label 同时移动,否则训练时会报 “Can't find label for image” 的错误。data.yaml内容如下:
path: /absolute/path/to/cotton_disease train: images/train val: images/val names: 0: bacterial_blight 1: leaf_curl 2: whitefly ...path建议写绝对路径,避免相对路径在不同终端下解析不一致。names的索引顺序就是训练时类别 logits 的映射。如果某个类别在 val 中没有样本,训练不会报错但 mAP 会少一个类别,所以划分时最好用分层抽样,保证每个类别在 val 里至少有几张。
4.2 训练命令与关键参数
训练命令一句话就能跑起来:
yolo detect train data=cotton_disease/data.yaml model=yolov8s.pt epochs=200 imgsz=640 batch=8 patience=30 project=runs name=cotton_disease参数说明:yolov8s.pt表示使用 small 版本预训练权重,比 n 略大,比 m 轻量,适合 977 张的中等数据集;imgsz=640是 YOLOv8 默认推理尺寸,如果你的病斑很小,可以改成 832 或 1024,但注意显存占用会平方级上升;patience=30表示验证指标连续 30 个 epoch 没有提升就早停。显存不够时优先调batch而不是imgsz,比如batch=4。
如果你在用 AMD 显卡跑 YOLO,需要先确认安装了 ROCm 版 PyTorch,YOLOv8 本身没有对 NVIDIA 硬编码,但部分算子在 ROCm 下的兼容性与 CUDA 版本有差异,实测中batch=8可能比 NVIDIA 下更容易出现显存不足。遇到这种情况就把 batch 减半,同时用workers=4加速数据加载。
4.3 损失函数与mAP的联动观察
训练时控制台会打印box_loss,cls_loss,dfl_loss三项损失。棉花病害检测中cls_loss收敛趋势尤其重要,因为 22 个类别的相似度高,类别误判是主要错误来源。如果cls_loss下降明显但box_loss波动大,说明病斑大小差异导致定位不稳定,可以上调box_loss_gain的权重,但 YOLOv8 默认参数一般不需要动。
更直观的做法是每 10 个 epoch 用验证集跑一次:
yolo detect val model=runs/cotton_disease/weights/best.pt data=data.yaml观察每个类别的 mAP50,找到表现最差的三类,大概率是样本数最少或标注框过大的类别。不要只盯着总 mAP,22 类中某类可能是 0.9,另一类只有 0.2,平均下来 0.55 并没有反应真实短板。
5. 训练前的数据质量检查:标注一致性、类别平衡与增强策略
977 张图、22 个类别,平均每类只有 44 张,但真实分布往往不均。训练前花一小时做数据体检,比训练时反复调参更有效。最后一章具体说说怎么用脚本发现标注问题,以及怎么在数据层面纠偏。
5.1 可视化标注覆盖
把每张验证集图像的预测框或 GT 框画出来做成拼图,快速看整个数据集的标注风格。你可以随机挑 100 张图,把 GT 框画出来存成grid_*.jpg。如果发现大量框只框住了叶片中心而漏掉边缘病斑,说明标注标准不统一。模型学到的是“叶片+病斑”,而不是“病斑本身”,这会影响实际场景下的精准定位。
5.2 类别不均衡的快速计算
统计每类目标数量的脚本:
import glob from collections import Counter counter = Counter() for txt in glob.glob("labels/train/*.txt"): with open(txt) as f: for line in f: cls = line.split()[0] counter[cls] += 1 for cls in sorted(counter.keys()): print(f"{cls}: {counter[cls]}")如果某个类别框数量低于 50,在 YOLOv8 中通常会欠拟合。这时候不要盲目增加总 epoch,优先做针对性增强。对于棉花叶子病害,常见的增强手段是 HSV 扰动(因为叶片颜色受光照影响大)、马赛克增强和随机旋转,但要注意病斑纹理不能被过度旋转破坏,所以degrees=5左右即可。
5.3 小样本类别怎么增强
YOLOv8 训练参数里可以单独开启增强的强度,比如hsv_h=0.015、hsv_s=0.7、hsv_v=0.4是默认值,对于棉花叶片颜色可以适度加大hsv_h到 0.02,让模型适应不同生长期的叶色。如果某类病斑只有 30 个框,先尝试复制粘贴增强,或者使用mosaic=0.9让模型在混合图中看到更多小目标。注意:这些参数在train.py里需要显式传递,如果用 CLI,写在命令末尾即可。
最后送你一个实用技巧:在训练完成后,用yolo predict跑一遍自己拍摄的、不在数据集里的棉花叶片照片,而不是只用测试集评估。如果真实照片上漏检率明显高于验证集,请检查你的增强配置是否过强,导致模型学了太多噪声;如果图片尺寸过大导致小病斑被压缩,把推理时imgsz调大一级,往往比换模型更有效。
本文还有配套的精品资源,点击获取