腰果缺陷检测YOLO数据集详解:目录、标签与训练实战
2026/9/11 20:55:23 网站建设 项目流程

简介:面向目标检测与工业缺陷识别场景的腰果缺陷YOLO数据集,共5类:Broken、Defect、SplitDown、SplitUp、Whole,已按YOLOv5目录结构划分训练集3186张、验证集304张、测试集150张,每张图片均含对应txt标签,采用相对坐标格式,可直接替换至YOLOv5、YOLOv8等主流框架训练。资源包共2000个文件,主要包括1999个YOLO格式标注txt与1个数据可视化Python脚本,脚本可随机读取图片绘制边界框并保存至当前目录,无需改动即可运行,便于快速核验标注效果。压缩包大小约101.94MB,同时附带类别class文件,省略手动配置步骤。已有63人学习使用,适合需要现成腰果缺陷数据集的目标检测学习者、算法工程师及比赛团队,尤其适合专注模型调优与缺陷识别改进的开发者。

1. 腰果缺陷检测数据集:从零标注到可训练,少走三天弯路

做过工业质检的朋友都清楚,缺陷检测项目最耗时的往往不是模型调参,而是数据准备。腰果这种农产品,外形不规则、裂纹方向随机、破损形态多样,标注标准稍不统一,模型训练出来就是一团浆糊。这套腰果缺陷检测数据集直接给出了 5 类标注结果——Broken、Defect、SplitDown、SplitUp、Whole,并且严格按照 YOLOv5 的目录结构存放,训练集 3186 张、验证集 304 张、测试集 150 张,每个子集下 images 和 labels 一一对应,拿过来改个 data.yaml 就能开始训练。

更实用的是,资源里附带了一个show.py可视化脚本,不需要改任何路径配置,直接运行就会随机抽一张图片并绘制边界框,帮你快速核对标签质量。对刚接触 YOLO 的开发者来说,这是理解标注格式和数据结构的最佳样例;对做农产品分选、食品质检的工程师来说,这也是一份可以迁移到其他不规则物体检测任务的参考模板。接下来我从目录结构、标注格式、可视化验证、训练配置和常见坑位几个维度拆开讲。

2. YOLO 数据集目录与 5 类标签格式:先看懂文件再说训练

2.1 目录结构:YOLOv5 约定下的 images/labels 组织方式

拿到资源后,第一件事不是急着跑训练,而是把目录树看清楚。这套数据严格遵循 YOLOv5 的组织约定:训练集和验证集、测试集分开存放,图片和标签文件放在各自的子目录中,且文件名一一对应。常见结构如下:

datasets/ ├── images/ │ ├── train/ # 3186 张图片 │ ├── val/ # 304 张图片 │ └── test/ # 150 张图片 ├── labels/ │ ├── train/ # 3186 个 txt 标签 │ ├── val/ # 304 个 txt 标签 │ └── test/ # 150 个 txt 标签 ├── classes.txt # 类别文件 └── show.py # 可视化脚本

注意一个细节:资源里测试集目录的描述写的是datasets-images-val,实际是 test 数据也沿用了 val 的命名规范,使用前建议先确认一下 test 文件夹的实际名称。如果路径不一致,YOLO 训练时会在data.yaml里通过 test 字段显式指定,不受文件夹名影响。

建议收到数据后先跑一条命令验证图片和标签数量是否严格一致:

for split in train val test; do img_count=$(ls datasets/images/$split/*.jpg 2>/dev/null | wc -l) lbl_count=$(ls datasets/labels/$split/*.txt 2>/dev/null | wc -l) echo "$split: images=$img_count labels=$lbl_count" done

这里的逻辑是分别统计三个子集下的图片和标签文件数量,正常情况下两边数字必须完全相同。如果出现 labels 少于 images 的情况,说明有图片没有对应标注,训练时会被 YOLO 自动跳过,但会影响实际参与训练的样本数,导致类别分布失衡。文件名前缀IMG_0687_png.rf.xxx.txt说明这批数据来自 Roboflow 的导出格式,rf是 Roboflow 的标记,不影响 YOLO 读取。

2.2 YOLO 标签格式:class 与归一化坐标的精确含义

打开任意一个 txt 文件,你会看到类似下面 5 列数字的格式:

0 0.482421875 0.352604167 0.0859375 0.104166667 3 0.721093750 0.572916667 0.152343750 0.133333333

每一行代表一个目标框,共 5 个字段,用空格分隔。第一个字段是类别 ID,从 0 开始计数,对应classes.txt里的行号;后面四个字段分别是x_centrey_centrewh,全部是相对于图片宽高的归一化值。比如0.482421875表示目标框中心点在图片宽度方向的 48.24% 位置,0.0859375表示框宽占整张图片宽度的 8.59%。

这种归一化坐标的好处是与图片分辨率无关。同一张腰果图片缩放成 640x640 还是 1280x1280,标注值都不需要改,YOLO 内部在训练时会自动映射回实际分辨率。这一点和 COCO 的像素坐标标注(x, y, w, h绝对像素值)有本质区别,混用的话会导致边界框偏移。

类别文件classes.txt每行一个类名,顺序必须和标注文件里的 ID 对应。这组数据的顺序是:

Broken Defect SplitDown SplitUp Whole

也就是说 ID 0 是 Broken,ID 4 是 Whole。训练配置文件data.yamlnames列表的顺序必须与此完全一致,否则会出现标签错位的严重问题——模型学到的特征与类别名对不上,评估指标一片混乱。

2.3 批量检查标签坐标合法性

拿到数据集后建议先写一个快速脚本,批量扫描所有标签文件,检查是否有越界坐标、负数宽高或空文件问题。越界坐标通常来自标注工具的精度损失,虽然 YOLO 在训练时会做 clipping,但坐标偏差过大会影响边框回归的收敛速度。

import os label_dir = 'datasets/labels/train' bad_files = [] for fname in os.listdir(label_dir): if not fname.endswith('.txt'): continue path = os.path.join(label_dir, fname) with open(path, 'r') as f: for line in f: parts = line.strip().split() if len(parts) != 5: bad_files.append((fname, '字段数不为5')) continue cls, xc, yc, w, h = parts xc, yc, w, h = map(float, [xc, yc, w, h]) if xc < 0 or xc > 1 or yc < 0 or yc > 1 or w <= 0 or h <= 0: bad_files.append((fname, f'坐标越界: {line.strip()}')) elif xc - w/2 < 0 or xc + w/2 > 1 or yc - h/2 < 0 or yc + h/2 > 1: bad_files.append((fname, f'边界超出: {line.strip()}')) print(f'共检查 {len(os.listdir(label_dir))} 个文件,发现 {len(bad_files)} 个异常') for name, reason in bad_files[:20]: print(f'{name}: {reason}')

这段脚本的两个判断逻辑:第一层是合法性检查,坐标值必须在 0 到 1 之间且宽高为正数;第二层是边界检查,框的左上角(xc - w/2, yc - h/2)和右下角(xc + w/2, yc + h/2)必须落在图片范围内。如果第二条报错,通常说明标注框贴边,训练时 mosaic 增强会把边缘框截断,影响检测精度。

3. show.py 可视化脚本:一张图确认标注质量

3.1 脚本设计逻辑:随机抽样绘制边界框

show.py是这套资源里最省心的工具。它的设计意图很明确:随机从数据集目录中取一张图片,读取对应的 txt 标注文件,将归一化坐标映射回像素坐标后,用 OpenCV 绘制边界框和类别标签,最后保存到当前目录。整个流程不需要任何命令行参数,也不要求手动指定图片路径,做到了开箱即用。

脚本核心逻辑可以还原为以下流程:

import cv2 import random import os img_dir = 'datasets/images/train' label_dir = 'datasets/labels/train' class_names = ['Broken', 'Defect', 'SplitDown', 'SplitUp', 'Whole'] img_files = [f for f in os.listdir(img_dir) if f.endswith(('.jpg', '.png'))] rand_img = random.choice(img_files) img_path = os.path.join(img_dir, rand_img) label_path = os.path.join(label_dir, rand_img.rsplit('.', 1)[0] + '.txt') img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path, 'r') as f: lines = f.readlines() for line in lines: cls_id, xc, yc, bw, bh = map(float, line.strip().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, class_names[int(cls_id)], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imwrite('visual_result.jpg', img) print(f'已保存: visual_result.jpg (图片: {rand_img})')

核心逻辑拆解:第一步用random.choice随机选中一张图片,确保每次运行结果不同,方便多轮抽检;第二步通过文件名替换后缀找到对应的 txt 标签文件;第三步是关键——将归一化坐标乘以图片实际宽高,得到边界框的像素坐标。x1y1是左上角,x2y2是右下角,OpenCV 的rectangle函数接收的正是这两个坐标点。

3.2 动手运行与结果解读

运行方式极其简单,在项目根目录下执行:

python show.py

如果datasets目录路径和脚本中的默认值不匹配,会报FileNotFoundError。常见做法是把脚本中的img_dirlabel_dir改成实际路径,或者把数据集目录软链接到脚本同级目录下:

ln -s /your/actual/path/datasets ./datasets

运行完成后,当前目录会生成一张visual_result.jpg。打开图片重点看三件事:第一,边界框是否紧贴腰果轮廓,如果框大面积超出或明显小于目标,说明标注精度有问题;第二,类别标签是否正确,比如 Whole 类别出现 Broken 的标签就是标注错误;第三,一张图片里是否有多个框,腰果检测经常出现同一张图多个目标的情况,漏标会导致训练时背景误判。

可视化验证的价值在于:训练集的标注质量直接决定模型上限。YOLO 这类单阶段检测器对标签噪声的容忍度有限,尤其是边框偏移超过 10% 时,mAP 会明显下降。用show.py抽检 20 到 30 张图,基本就能对整体标注水平做出判断。

4. 直接训练 YOLOv5/v8:data.yaml 配置与超参选择

4.1 data.yaml 的编写与路径修正

拿到数据集后,训练前需要手动创建data.yaml文件。YOLOv5 和 YOLOv8 的配置格式完全一致,核心是三个路径加一个类别列表:

train: datasets/images/train val: datasets/images/val test: datasets/images/test nc: 5 names: ['Broken', 'Defect', 'SplitDown', 'SplitUp', 'Whole']

这里trainvaltest指向图片目录即可,YOLO 会自动根据文件名前缀去labels目录下找对应的 txt。路径建议使用相对路径,如果训练时从项目根目录执行,这样配置最不容易出错。如果目录结构是datasets/images/train,但实际 labels 在datasets/labels/train,YOLO 内部处理逻辑是把images替换为labels,所以目录名的对应关系必须严格。

训练时如果遇到AssertionError: Label class X exceeds nc=5 in data/yaml,说明类别 ID 超出了取值范围。常见原因是classes.txt里有空行,或者数据集中出现了未定义的类别 ID。检查方法:

awk '{print $1}' datasets/labels/train/*.txt | sort -n | uniq -c

这条命令统计训练集中出现的所有类别 ID 及频次,输出应该只有 0 到 4 五个数字。如果出现 5 或更大值,说明标注文件里有越界类别,需要清洗数据,否则训练直接报错。

4.2 训练参数的选择逻辑

YOLOv5 和 YOLOv8 在训练命令上差异不大,核心参数是imgbatchepochs。以 YOLOv8 为例:

yolo train model=yolov8s.pt data=data.yaml epochs=100 imgsz=640 batch=16 device=0

参数说明:model=yolov8s.pt是预训练权重,s 版本在精度和速度之间最均衡,适合腰果这种类别数少、目标尺度中等的场景;imgsz=640是输入分辨率,腰果缺陷如 SplitDown 和 SplitUp 属于细小裂纹,如果 GPU 显存充足可以提到 800 或 960,小目标检测精度会明显改善;batch=16在 16GB 显存下比较稳妥,显存不够就降到 8。

建议先跑 30 个 epoch 做一次快速验证,观察 loss 曲线是否正常下降,再决定是否跑满 100 轮。如果使用 YOLOv5,命令对应为:

python train.py --data data.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100

YOLOv5 和 YOLOv8 的损失函数结构不同:v5 使用 GIoU Loss 作为回归损失,v8 改为 CIoU 结合 Distribution Focal Loss(DFL)。对腰果这种边界不规则的目标,v8 的边框回归通常更稳定,但 v5 的生态更成熟、部署方案更丰富。如果项目没有特别要求,优先推荐 v8s 起步。

超参数方面有两个重点:mosaichsv增强。YOLOv5 默认开启 mosaic=1.0,在训练后期(最后 10 个 epoch)会自动关闭以稳定收敛;YOLOv8 中可以用mosaic=0.5控制概率。腰果图片背景相对单一,mosaic 增强能有效提升模型对背景变化的鲁棒性,建议保留。训练时观察类别分布,如果 Whole 类别占比过高,考虑在 loss 中加大其他类别的权重,或者通过class_weight参数调节。

4.3 训练产出物的验证方式

训练完成后,runs/detect/train目录下会生成weights/best.ptweights/last.ptbest.pt是验证集上 mAP 最高的权重,last.pt是最后一轮的权重,部署时统一用best.pt。快速验证模型效果:

yolo predict model=runs/detect/train/weights/best.pt source=datasets/images/test/ imgsz=640 save=True

查看runs/detect/predict下的预测结果图,重点看两个指标:一是有没有把 Broken 误检成 Defect,这俩类别在视觉上容易混淆;二是小裂纹 SplitUp 和 SplitDown 有没有漏检。如果漏检严重,下一步优化方向是提升输入分辨率或增加数据增强。

5. tips:图片与标签错位的快速排查与类别失衡处理

5.1 文件名不匹配的隐形坑

YOLO 训练过程中如果出现corrupt imageassert labels are correct的报错,多数情况下是文件名不匹配。资源里的文件名带_png.rf.这种冗长后缀,有些开发者会在处理时用字符串截取改名,结果导致图片和 txt 文件前缀对不上。

排查命令:

cd datasets for split in train val test; do diff <(ls images/$split | sed 's/\.[^.]*$//' | sort) <(ls labels/$split | sed 's/\.[^.]*$//' | sort) > /dev/null && echo "$split OK" || echo "$split MISMATCH" done

这里是逐个子集对比 images 和 labels 下的文件名前缀,sed 's/\.[^.]*$//'删除最后一个点之后的后缀,只保留主文件名,再排序后 diff。如果有不一致输出,说明存在孤儿文件需要删除或补齐。

5.2 类别不均衡的处理策略

这组数据 5 个类别里 Whole 的数量通常远大于其余缺陷类,直接用原始分布训练会导致模型偏向多数类。常见做法是调整data.yaml中的类别权重:YOLOv8 的 loss 支持class_weights参数,YOLOv5 可以在训练命令中加--cls 0.6提高分类损失的权重。另一种更直接的方式是离线过采样少数类,把 SplitDown 和 SplitUp 的图片复制几份混入训练集,注意打乱顺序,避免模型学到数据顺序的偏置。

5.3 标签偏移的精细校准技巧

如果可视化后发现某些框偏移了 2 到 3 个像素,属于标注误差,对训练影响不大。但如果偏移超过 5%,且集中在某个方向,可以写脚本对标签做统一修正——统计所有框中心点的平均偏移量,然后批量平移。这类系统性偏差通常来自标注工具导出时的坐标转换 bug,修正一次能明显提升 mAP。建议训练前先跑一次上面 2.3 节的检查脚本,再配合 show.py 抽检,两步做完再进入训练环节,效率最高。

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

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

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

立即咨询