
简介面向目标检测与工业质检场景的腰果缺陷检测YOLO数据集覆盖Broken、Defect、SplitDown、SplitUp、Whole五类缺陷标注采用YOLO相对坐标格式类别、中心点x/y、宽高并已按训练集3186张、验证集304张、测试集150张完成划分可直接投入YOLOv5等模型训练或迁移学习。压缩包内共2000个文件主体为1999个标签txt文件与配套的类别class文件另附1个Python可视化脚本随机传入一张图片即可自动绘制并保存检测框脚本无需改动即可运行极大方便抽查标注质量。包体约101.94MB目录沿用datasets-images标准结构可无缝替换默认数据集路径减少预处理成本。目前已有63人学习下载适合刚接触YOLO或需要快速搭建腰果外观缺陷检测实验的研究者与工程师使用。1. 腰果缺陷检测数据集为什么这份YOLO格式的5类标注能直接开训做工业质检部署的同行应该都懂缺陷检测项目里最耗时间的从来不是模型结构而是数据集。腰果这种农产品外观不规则裂纹、碎断、表面瑕疵长得又像人工标注一千张图就要一天标完还得检查坐标框是不是贴着缺陷边缘。这套 YOLO 数据集把这块最脏的活干完了5 个类别、3640 张图、标注格式是 YOLOv5 原生相对坐标图片和标签一一对应还附了一个不用改参数就能跑的可视化脚本。适合谁一类是刚接触 YOLO 检测、想拿一个五脏俱全的小数据集跑通训练到部署全流程的新手另一类是已经在做食品或农产品缺陷检测、想先拿现成标注数据验证思路的老手。我个人更看重它数据划分得干净——训练、验证、测试三份互不重叠这在网上很多数据集里反而是稀缺品。2. 数据集结构与标注格式YOLO 相对坐标、5 个类别与三份划分怎么读2.1 目录结构images 与 labels 按 train/val/test 镜像存放这份资源拿到手解压之后先别急着开训把目录结构认清楚。它完全按照 YOLOv5 的工程约定存放图片和标签分家但目录层级镜像对齐datasets/ ├── images/ │ ├── train/ 3186 张腰果图片 │ ├── val/ 304 张腰果图片 │ └── test/ 150 张腰果图片 └── labels/ ├── train/ 3186 个 txt 标签文件 ├── val/ 304 个 txt 标签文件 └── test/ 150 个 txt 标签文件每个图片文件对应一个同名 txt。比如IMG_0687_png.rf.d6290aa844e7f0c2b48ad9deed8f4c9f.jpg对应同目录下IMG_0687_png.rf.d6290aa844e7f0c2b48ad9deed8f4c9f.txt一一对应不多不少。这种png.rf.前缀的命名风格是 Roboflow 导出数据集的惯例说明这份数据大概率是从标注平台导出的格式规范程度比个人手工标注的要高一个档次。提示labels 目录里如果出现没有对应图片的孤儿 txt或者图片没有对应 txt训练时 YOLOv5 会跳过或报警。后面避坑章会专门讲怎么排查。由于是标准的 YOLO 目录布局使用 YOLOv5 时只需要在 data.yaml 里把三个路径指过去就行不用写任何自定义的数据加载逻辑。这也是这份资源「拿来就能训」的核心原因——目录结构本身就是 YOLO 项目约定不是二次加工过的私有格式。2.2 标注格式一行 txt 如何变成像素坐标打开任意一个 label 文件每一行代表一个目标框。以摘要描述里的说明为准classesx_centre、y_centre、w、h四项全部是相对坐标也就是已经除过图片宽高的归一化数值。拿一张 1280×720 的图举例如果某个腰果缺陷框的中心点落在 (640, 360)宽 100px高 50px那么 txt 里存的这一行是2 0.500000 0.500000 0.078125 0.069444其中第一个数字 2 是类别编号对应 class 文件里第 3 行那个类别编号从 0 开始。后四个数字的计算方式x_centre 640 / 1280 0.500000 y_centre 360 / 720 0.500000 w 100 / 1280 0.078125 h 50 / 720 0.069444反推像素坐标时把归一化数值乘回原图宽高即可。这个格式最大的好处是图像 Resize 之后标签不需要跟着改——YOLOv5 训练时会把输入统一缩放到 640×640因为标签是相对坐标缩放后框的位置依旧准确。如果你之前接触过 COCO 的 JSON 格式或 VOC 的 XML 格式转过来可能会不适应但其实原理是一样的VOC 存像素坐标YOLO 存相对坐标只是表达方式不同。2.3 类别划分Broken、Defect、SplitDown、SplitUp、Whole 的判定边界class 文件内容决定了类别编号顺序YOLO 标签里的数字 0-4 就是按这个顺序映射的绝对不能错位。5 个类别如下表编号类别名语义常见标注口径0Broken碎断腰果断裂成多块或主体明显缺损1Defect表面缺陷斑点、变色、凹陷等非结构性瑕疵2SplitDown纵向裂开沿腰果纵向开裂裂口走向偏向一端3SplitUp纵向裂开同样含裂口但与 SplitDown 的起始端/走向相反4Whole完好无缺陷的完整腰果从命名习惯看Broken 和 SplitDown/SplitUp 的区别在于「碎」和「裂」Broken 是整体结构断裂Split 系列是沿裂纹方向裂开但主体还在。SplitDown 与 SplitUp 视觉上非常容易混淆我推测标注规范里应该以裂口从哪一端开始作为区分依据。Defect 则是排除掉裂开与碎断之外的一切表面问题属于兜底类。这个类别设计很贴近真实产线质检逻辑——产线上不是只分「好/坏」而是要把坏的原因分出来方便后续追溯是烘干工艺问题还是运输碰撞问题。训练时容易混的也就是 SplitDown、SplitUp、Broken 这三类后面避坑章我会给一套排查方法。2.4 数据划分3186 / 304 / 150 三份数据各自的用途总数 3640 张其中训练集 3186 张、验证集 304 张、测试集 150 张占比大约是 87.5%、8.4%、4.1%。训练集负责拟合权重验证集在每一轮 epoch 结束后评估当前模型用于调学习率、早停和选最佳权重测试集从头到尾不参与训练只在最终评估时用一次。这个划分比例里测试集偏小但放在 3640 张的规模上 150 张够用了——每张图上平均有多个标注框实际参与评估的检测框数量远大于图片数。要注意的是自己用这份数据做实验时不要再去动划分直接用现成的三份目录。如果因为要做 K 折交叉验证而重新划分务必保证同一张图片不会同时出现在训练集和测试集里否则指标会虚高得离谱。这套数据结构不仅 YOLOv5 能用换到 YOLOv8、YOLO11 同样能吃。yolov8 训练自己的数据集时只需要把 data.yaml 里的路径和类别名指对模型结构变化不改变数据加载层对 YOLO 格式的依赖。3. show.py 可视化脚本不改参数把样本和标签在同一张图上核对3.1 show.py 做了什么从 txt 解析到绘制框的流程数据质量是训练效果的底线而最快验证数据质量的方法就是把图片和标注框叠在一起看。这个资源里附带的 show.py 干的就是这件事——随机传入一张图片读取同名 txt解析每一行的类别与归一化坐标换算成像素坐标后用 OpenCV 画矩形框最后保存到当前目录。核心流程拆开看就是三步import cv2 def draw_yolo_boxes(image_path, label_path, class_names): # 第一步读图拿到真实宽高用于反归一化 img cv2.imread(image_path) h, w img.shape[:2] # 第二步逐行解析 txt 标签 with open(label_path, r, encodingutf-8) as f: for line in f.readlines(): parts line.strip().split() cls_id int(parts[0]) x_c, y_c, box_w, box_h map(float, parts[1:5]) # 第三步归一化坐标乘回原图尺寸得到左上角和右下角 x1 int((x_c - box_w / 2) * w) y1 int((y_c - box_h / 2) * h) x2 int((x_c box_w / 2) * w) y2 int((y_c box_h / 2) * h) color (0, 255, 0) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, class_names[cls_id], (x1, max(0, y1 - 6)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 1) return img几个关键点坐标换算必须用原图尺寸画框线宽 2字号 0.6这些属于可视化美观参数类别的 class_names 列表必须与 class 文件顺序一致否则框上标签会张冠李戴。OpenCV 的rectangle坐标参数是左上角和右下角两个点而 YOLO 格式给的是中心点加宽高所以先减后加算出 x1/y1/x2/y2。这个换算是最容易算错的地方少除以 2 或者忘记乘回去画出来的框就会整体偏移。show.py 之所以能做到拿来就跑就是因为它把文件匹配、图片读取、坐标换算这些脏活都封装好了。3.2 运行方式一条命令得到带标签的样本图使用方式很粗暴直接传图片路径python show.py IMG_0687_png.rf.d6290aa844e7f0c2b48ad9deed8f4c9f.jpg脚本会自动在相同目录下找同名 txt画完框保存为一张新的图片文件输出到当前工作目录。全程不需要改任何参数也不需要装额外的标注工具。我习惯的做法是先抽训练集一张、验证集一张、测试集一张分别跑确认三份数据的标注风格一致再决定要不要直接开训。如果真的把图片路径传错了脚本会怎样两种常见情况一是提示找不到图片文件二是找到图片但找不到同名 txt。第二种情况更隐蔽——如果图片本身没问题只是 label 目录路径被移动过那么可视化输出会是一张没有框的原图这时候很容易误判为这张图没有目标。正确的检查方式是确认 images 和 labels 目录是镜像关系同名文件一一对应。3.3 魔改参数颜色、线宽、保存路径改哪里数据可视化不只是看一眼就完事。我拿到任何数据集都会先改几个参数把可视化输出做成「一眼能发现问题」的形式。show.py 这类脚本一般预留三个可调位置类别颜色映射、框线宽度、输出文件名。默认全部框都是绿色当不同类别的框混在一起时很难分辨边界。改一行配置给五个类别分配不同颜色检查效率立刻不一样colors { 0: (0, 0, 255), # Broken红色 1: (0, 255, 255), # Defect黄色 2: (0, 165, 255), # SplitDown橙色 3: (255, 0, 255), # SplitUp紫色 4: (0, 255, 0), # Whole绿色 }改完颜色再看图SplitDown 和 SplitUp 的框颜色不同一眼就能看出标注边界是否混乱。线宽参数在cv2.rectangle的最后一个参数屏幕看图可以设 2导出论文配图时可以设 3。保存路径一般就是cv2.imwrite(output.jpg, img)这一行改成cv2.imwrite(check/val_001.jpg, img)就能把抽检结果统一收集到一个目录批量检查不污染工作目录。这些改动对脚本本身零侵入改动后也不会影响数据集的原始文件。3.4 批量可视化我要检查全部测试集怎么办show.py 每次传入一张图片检查 150 张测试集要手动敲 150 次命令这不现实。这里分享一个我自己常用的批量抽检方式写一个三行的 shell 循环把测试集里每张图片都跑一遍可视化输出到 check 目录mkdir -p check for img in datasets/images/test/*.jpg; do python show.py $img mv output.jpg check/$(basename $img .jpg)_out.jpg done跑完之后在 check 目录里快速翻一遍缩略图重点看三件事框有没有明显偏离目标位置有没有一张图上某些目标漏标框里装的目标类别与标签文字是否吻合。这个批量抽检的耗时取决于图片数量和机器性能但比一张张手工点开 labelImg 快得多而且不需要交互式操作。如果这一步发现问题基本不需要怀疑模型直接回炉数据集标注。4. 训练前必做的检查与避坑路径、类别顺序、标签异常的四个排查点4.1 现象训练集路径写错Loss 不动也找不到图片这个坑几乎每个换机器跑 YOLO 的人都会踩一次。data.yaml 里路径写法不对训练启动时只给一个0 images found警告然后训练过程照样跑loss 一路不降mAP 全程为 0看起来像模型问题实际是数据压根没加载进来。常见原因有两个第一相对路径的基准目录不对YOLOv5 的 data.yaml 里train: datasets/images/train是相对你执行train.py命令的那一层目录解析的而不是相对 data.yaml 文件本身所在目录第二Windows 路径反斜杠和 Linux 正斜杠混用导致解析失败。解决方式在 data.yaml 里直接写绝对路径或者先手动确认路径存在再启动训练ls datasets/images/train | head -5 # 或直接写死绝对路径一劳永逸# data.yaml train: /home/user/cashew/datasets/images/train val: /home/user/cashew/datasets/images/val test: /home/user/cashew/datasets/images/test nc: 5 names: [Broken, Defect, SplitDown, SplitUp, Whole]4.2 现象类别编号与 class 文件错位训练不报错但全检错数据集里 class 文件规定了五个类别的顺序标签 txt 第一列的数字就是按这个顺序编码的。如果你在训练时自己想当然改了 names 顺序——比如把 Whole 放第一位但标签里原本的 4 还是 Whole——模型训练完全不报错精度曲线也正常但推理结果会全部错位Broken 被识别成 WholeSplitDown 被识别成 Defect看似有精度实则全错。这种错位比网络结构写错还恶心因为它不产生任何显式报错。排查方法很简单训练前统计所有标签文件里第一个数字的分布然后和 class 文件逐行比对# 统计每个类别编号出现的次数 cat datasets/labels/train/*.txt | awk {print $1} | sort | uniq -c输出应该是五个数字各有一坨计数说明 0-4 都有样本。如果发现某个编号完全没出现比如始终没有 3要么是该类别样本太少要么是标注类别号写错。统计完再用 show.py 抽查几张图确认图片上显示的类别名和视觉效果一致再进训练。4.3 现象空标签或坐标越界Loss 直接炸成 NaNYOLO 训练中 BN 层崩溃、Loss 变成 NaN大家第一反应都是学习率太大但在数据集这边还有一个隐藏诱因标签数据里有非法值。空标签文件、坐标出现负数、w 或 h 超过 1都会在计算 loss 时产生异常梯度。尤其 w/h 大于 1 这种错误某些数据增强策略下会生成超出边界的建议框回传梯度时数值直接爆炸。在跑训练之前花一分钟跑一个全局扫描最稳# 找出所有为空的标签文件 find datasets -name *.txt -empty | wc -l # 找出所有坐标异常的标签行 cat datasets/labels/train/*.txt | awk {if ($30 || $40 || $51 || $61) print $0} | head坐标合法的取值范围是x_centre 和 y_centre 必须在 [0, 1] 之间w 和 h 也必须在 (0, 1] 之间。任何一条超出这个范围都应该先修标签再训练而不是靠调学习率把 NaN 压回去。注意 x/y 中心点可以接近 0 或 1但 w/h 必须严格小于等于 1否则框已经超出图片范围。4.4 现象重新划分数据后混淆矩阵总合对不上如果你打算 K 折交叉验证或者扩充自己的数据集后重新划分最容易犯的一个错误是把同一张图片既放进训练集又放进测试集。这种数据泄露不会导致训练失败但会让最终评估指标虚高。一个很典型的信号是混淆矩阵每一行的加总不是该类别的实际样本数而是明显偏大——YOLO 训练完输出的混淆矩阵行和列都是按类别聚合的如果某类训练集和测试集存在同一张图片评估时等于用训练过的图片测了一遍矩阵数值自然对不上。解决方式重新划分前做一次图片级去重用文件哈希或文件名 MD5 做集合比对# 找出 train 和 test 中重复出现的文件名 comm -12 \ (ls datasets/images/train | sort) \ (ls datasets/images/test | sort) | head -20文件名相同但内容不同的情况不常见但稳妥起见可以用md5sum对所有图片算哈希再比对。确保交集为空再开始训练。数据集里这三份是官方划分好的直接信任它没有重复但如果你自己动手扩充分类这个检查就不该跳过。4.5 现象数据增强后标签越界训练 mAP 诡异波动YOLOv5 训练时会做马赛克增强和随机仿射变换这些操作会改变框的位置和尺寸。默认的增强逻辑会自动裁剪越界的标签如果你的数据集里有标签刚好贴在图片边缘增强后抖动一下就可能被裁掉一半导致这个框的类别没参与训练。这个问题在腰果这种密集小目标场景里更常见——腰果在传送带上拍摄时往往挤在画面边界附近。排查思路训练时开启--cache缓存数据后用tqdm的进度条观察是否有大量图片被跳过或者对比增强前后同一张图的标签数量。如果发现边界框丢失严重在数据增强配置里适当减小hsv_h、translate等随机扰动强度给缺陷检测场景留更大的安全余量。这个坑不是数据集的锅是训练配置和边界样本相互作用的结果但提前知道能省不少排查时间。5. 用混淆矩阵反推数据质量类别边界修正与增强策略5.1 先看类别统计再谈训练拿到数据集的第一件事不是训练而是统计每个类别的目标框数量。缺陷检测场景里类别不平衡比通用目标检测更致命因为缺陷类别本来就少。拉一下 train 和 val 的标签统计for split in train val test; do echo $split cat datasets/labels/$split/*.txt | awk {print $1} | sort | uniq -c done哪一类框的数量断崖式少心里就有数了。正常训练时补齐这部分的方案按优先级排序先试试增强旋转、平移、HSV 扰动再看是否复用训练集中该类别的高置信度预测框做伪标注最后才考虑补采数据。常用技巧是给数量少的类提高采样权重——自定义 Dataset 里按类别分布重新采样比直接复制样本效果更稳定。5.2 混淆矩阵里读出的标注问题训练完第一轮看混淆矩阵的注意力放在对角线之外。对角线某格偏低说明对应类别之间边界模糊。腰果数据集里最容易出问题的组合是 Broken 与 SplitDown/SplitUp 互相混因为从视觉语义上三者都是「破」的如果标注规范只写了类别名没贴参考图标注员极容易凭感觉打标。另一个隐蔽信号是 SplitDown 与 SplitUp 被系统性搞反——如果混淆矩阵显示这两类有固定的双向误判大概率是标注规范里走向定义不清晰。处理方式把混淆矩阵里误判最严重的样本图抽出来用 show.py 逐个看标注框。如果发现某个框确实介于两个类别之间标注规范需要补示意图和边界的明确定义。修正标注后用同样的训练参数重跑一版对比混淆矩阵该区域的数值变化。数据增强对边界模糊的改善有限——增强能提升同类样本的鲁棒性但解决不了语义定义冲突。这是我在实际项目里反复验证过的结论所以我会先修标注定义再谈增强策略。我第一次拿这份腰果数据集跑实验时跳过可视化检查直接训练val 精度看起来还像回事但测试集的 Broken 类全混成了 SplitDown。后来强制自己把「跑 show.py 类别统计」作为拿到任何数据集的第一步才在后续项目里避开了大多数数据坑。从那以后我每次换数据集都强制走一遍这套检查先看图再训练发现问题就修标签宁可多花半天也要在这一步把所有隐患排干净。希望帮到你。本文还有配套的精品资源点击获取