
简介这份数据集面向计算机视觉与深度学习目标检测开发者聚焦马铃薯表面缺陷识别可直接用于YOLO系列模型训练。素材整合了常见的马铃薯发芽、真菌病害、机械损伤等缺陷样本并划分训练集与验证集类别文件定义了Sprouted potato、Diseased-fungal potato、Damaged potato等五类缺陷。压缩包总计两千个文件其中一千九百九十九个txt为YOLO格式标注文件每个文件对应一张图像的检测框坐标与类别另有1个show.py脚本可快速将框体绘制在图像上完成可视化验证。数据处理参考Labelme标注规范整体样本规模超过八千张图像背景真实、干扰多样适合评估模型鲁棒性。资源包大小约409.72MB目前已有429人学习与使用适合中高级算法工程师在农业质检、智能分拣等场景中直接微调或迁移使用。1. 马铃薯缺陷检测数据集不只是把土豆拍清楚那么简单做工业质检或农业智能分选的人迟早会撞上同一个问题手里有相机、有产线、有检测需求但就是没有一套能直接喂给 YOLO 的数据集。马铃薯这种外观差异极大的目标恰恰是目标检测里最典型的“看起来简单、做起来头疼”的场景——表皮颜色从浅黄到深褐形状从椭圆到歪扭缺陷又分表面、内部和形状三类每一类对标注的要求都不一样。本文围绕马铃薯图像缺陷检测数据集讲清楚从采集、标注、格式转换到训练评估的完整链路重点解决“缺陷怎么定义、标注怎么打、模型怎么收敛”这三个核心问题适合正在自建数据集的算法工程师也适合刚接手农业视觉项目、需要快速理解数据坑的后端与测试同学。2. 马铃薯缺陷检测数据集的构成与缺陷类别体系2.1 缺陷检测任务的本质是分类加定位不是像素分割目标检测里的“缺陷检测”输出的是每个缺陷的边界框和类别。马铃薯缺陷检测数据集里的标注对象不是整颗土豆而是土豆表面或内部的缺陷区域。这意味着采集图像时一张图里可能同时出现多个缺陷也可能一颗土豆同时有几种缺陷。数据集的维度因此比普通物体检测更多既要保证单类目标的多样性也要保证多缺陷共现的样本比例。常见做法是把缺陷分为三类表面类黑斑、溃烂、绿皮、机械损伤、形状类畸形、二次生长、裂口、内部类空心、褐变。内部缺陷常规光学相机拍不到需要借助近红外或多光谱设备或者干脆把土豆切开后拍切面。所以马铃薯缺陷检测数据集按拍摄方式又可拆分为“整薯表面数据集”和“切面数据集”两者在模型部署时的用途完全不同——产线分级用前者抽检质检用后者。2.2 一个可落地的类别标签清单与判定规则定义类别时类别数量要跟后续的人工审核成本挂钩。我不建议一开始就把“病斑”细分成晚疫病、早疫病、疮痂病因为农业病理学分类需要专业植保人员参与标注成本高而且很多病斑在产线图像上肉眼无法可靠区分。更稳的做法是先按“是否需要剔除”二分类再细分到 46 个形态学可判定的类别。下表是一个经过实际项目验证的类别体系字段含义依次是类别 ID、名称、典型外观、判定要点ID类别名典型外观判定要点标注员用0black_spot表皮黑色或深褐色斑点直径 2mm边界清晰与擦伤无黑化区分1rot溃烂、软化、凹陷表面湿润色泽异常常有渗出2green绿皮面积超过薯表 10% 即标注注意阴影误判3crack裂口、机械损伤表皮开裂长度大于薯长 1/44malformed畸形整体形状异常框住整个土豆不框局部5hollow空心仅切面切面内部空腔或褐变标注在空腔区域类别 ID 的排序和后续模型训练时的类别名保持一致避免中途改名导致标签重映射。malformed 这种整颗级别的缺陷建议用整颗土豆的外接框而不是单独框某个凸起否则会让模型学到“畸形 局部凸起”的错误关联。2.3 采集方案的三个关键参数分辨率、角度、光源马铃薯缺陷检测数据集的采集质量直接决定模型能否收敛。分辨率上单颗土豆在图像里至少要有 200×200 像素缺陷区域至少 20×20 像素不然即使是 YOLOv8 这种对中小目标相对友好的模型也很难在小缺陷上获得稳定置信度。按照普通工业相机 500 万像素、视野覆盖 58 颗土豆估算实际部署时土豆单颗像素能做到 300×300 以上这个量级对于黑斑和溃烂检测基本够用。拍摄角度分两类俯拍摄像头垂直对准输送带和侧面拍摄透明挡板后水平拍摄。俯拍最容易布置但会把大裂口拍成细线侧面拍摄需要解决反光和景深问题。产线上常见方案是俯拍 两个对角侧光源既能打亮凹陷和裂口又能避免顶部大块高光。拍切面时用俯拍加环形无影光源避免刀痕造成的伪缺陷。3. 马铃薯缺陷数据集的标注与格式转换3.1 用 LabelImg 还是 X-AnyLabeling标注工具的选择逻辑标注工具的选择取决于两个因素团队规模和你需不需做预标注。如果只是几百张图、两三个人LabelImg 足够它的优点是轻量、免训练、点开就能用缺点是没有自动追踪和半自动辅助遇到大量重复产线图会非常累。X-AnyLabeling 这类基于 SAM 的工具可以做预标注先用一个初步模型自动标一版人工再改效率能提升 35 倍。我一般会建议先手工标注 200 张图让模型跑一个初版再用这个初版对剩余图像做推理把置信度高的结果直接转成标注人工只修低置信度的框。这个流程下YOLO 格式的标注文件每一行对应一个缺陷实例格式为class_id x_center y_center width height其中坐标值都是归一化到 [0,1] 的浮点数x_center 和 y_center 是边界框中心点坐标width 和 height 是框的宽和高。以下是一颗土豆同时有黑斑和绿皮时的标签文件内容0 0.5234 0.6121 0.0823 0.0711 2 0.7810 0.4377 0.1523 0.0988格式转换时要注意很多标注工具默认输出 Pascal VOC 格式XML需要转成 YOLO。转换逻辑是读 XML 里的 xmin、ymin、xmax、ymax再除以图像宽高得到归一化坐标。如果原标注里是 COCO 的 JSON 格式则要额外处理分割掩码这里只贴 XML 转 YOLO 的核心代码import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, out_dir, class_map): tree ET.parse(xml_path) root tree.getroot() img_w float(root.find(size/width).text) img_h float(root.find(size/height).text) lines [] for obj in root.findall(object): cls obj.find(name).text if cls not in class_map: continue 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) x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{class_map[cls]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) out_path os.path.join(out_dir, os.path.splitext(os.path.basename(xml_path))[0] .txt) with open(out_path, w) as f: f.write(\n.join(lines))这段代码把每个目标的类别名映射成 class_map 里的数字 ID并完成坐标归一化。关键点是w和h也做了归一化如果漏掉这一步训练时模型会依据错误的宽高比去匹配锚框导致收敛极慢。还有一个容易踩的坑XML 里可能包含 difficult1 的对象这类目标极不清晰训练时应该跳过否则会引入大量噪声标签。3.2 数据划分的坑按批次划分而不是按图像随机划分马铃薯产线图像往往来自同一批次的连续拍摄同一颗土豆会被拍到多张相邻图像极其相似。如果按图像随机划分训练集和验证集验证集里会出现大量跟训练图像高度重叠的样本把模型的记忆能力误当成泛化能力。这种情况下验证集 mAP 能到 0.95但换到新批次土豆立刻掉到 0.7。正确的做法是按拍摄批次或时间序列划分。采集时给每个批次一个目录名比如batch_20240910_001划分脚本直接按目录取前 80% 作为训练、后 20% 作为验证。如果土豆是在旋转台上按角度拍摄那同一颗土豆的多个角度的图像必须全部落在同一个集合里。这也是马铃薯这类农产品数据集和通用目标检测数据集的最大区别——样本时间相关性强不能粗暴 shuffle。划分完再统计每个类别在训练集和验证集中的实例数量确保每个类别都至少出现 50 个实例。如果某个类别实例太少就要回采集阶段补数据不要用复制粘贴来凑数否则会让模型学到重复纹理特征。4. 用 YOLOv8 训练马铃薯缺陷检测模型的最小流程4.1 数据组织与配置文件选定 YOLOv8 是因为它对小数据集和中等算力比较友好训练脚本、验证指标和导出工具链都统一不需要自己写 NMS 后处理。把数据集组织成以下目录结构potato_defect/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── potato_defect.yamlYAML 配置文件里指定路径、类别数和类别名path: /data/potato_defect train: images/train val: images/val test: images/test nc: 6 names: [black_spot, rot, green, crack, malformed, hollow]注意 yaml 里的val路径不能指向空目录YOLOv8 在训练过程中会使用 val 集计算 mAP 并保存最佳权重。如果 val 集为空训练不会报错但模型会从最后一个 epoch 保存权重失去早停与选优能力。4.2 训练命令、关键超参与显存估算最小训练命令如下yolo detect train \ data/data/potato_defect/potato_defect.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch16 \ device0 \ patience30 \ projectruns/potato \ nameexp1参数说明modelyolov8n.pt表示加载 COCO 预训练权重马铃薯检测属于特殊目标检测预训练权重能显著加速收敛并提高小样本下的精度imgsz640是输入图像短边缩放值如果原图是 1280×960训练时会按比例缩放到长边不超过 640缺陷细节会丢失很多所以务必备注原图分辨率当原图缺陷小于 30×30 像素时imgsz至少提到 960patience30表示验证集 mAP 连续 30 个 epoch 不上升就提前终止避免过拟合和无效计算。显存方面yolov8n 在 640 分辨率下 batch16 大约占用 8GB 显存batch32 需要 14GB 左右。如果你只有一块 6GB 显存的卡建议把 batch 降到 8并把perspective增强关闭以减少 CPU 数据增强压力。训练日志里重点观察Box(P)、Cls(P)和mAP50-95三个指标前两个关注定位和分类精度第三个是综合指标。马铃薯缺陷检测中 mAP50 比 mAP50-95 更有参考价值因为缺陷框的边界在标注时本身就有主观性IOU 阈值过高会低估模型真实表现。4.3 类别不平衡与损失权重调整缺陷检测数据集最常见的失衡场景是『黑斑』样本上千个『hollow』空心只有 50 个。YOLOv8 默认按类别频率自动调整损失权重但当少数类占比低于 5% 时自动权重效果有限。手动干预的做法是在训练配置里修改cls系数或对少数类样本做离线复制增强。经验值是少数类样本量低于多数类 1/20 时先做 35 次复制再配合 mosaic、旋转增强。复制时不能只复制原始图要把少数类缺陷贴到背景马铃薯图上做合成数据这样能保留上下文信息。合成粘贴使用下面这段逻辑import cv2 import numpy as np def paste_defect(bg_img, fg_img, fg_bbox, output_path): # bg_img: 没有该缺陷的马铃薯背景图 # fg_img: 从另一张图里裁剪出的缺陷区域 x1, y1, x2, y2 fg_bbox patch fg_img[y1:y2, x1:x2] h, w patch.shape[:2] scale np.random.uniform(0.8, 1.2) patch cv2.resize(patch, (int(w * scale), int(h * scale))) ph, pw patch.shape[:2] bx1 np.random.randint(0, bg_img.shape[1] - pw) by1 np.random.randint(0, bg_img.shape[0] - ph) # 简单 alpha 融合直接把 patch 贴到背景 bg_img[by1:by1ph, bx1:bx1pw] patch cv2.imwrite(output_path, bg_img)这段逻辑把裁剪出的缺陷区域随机缩放后粘贴到新的背景上并生成新标签。核心坑在于缩放范围不能过大否则缺陷纹理失真模型会把“模糊”当成特征。粘贴位置要尽量避开土豆边缘和薯皮高光区域否则模型会学习到“缺陷只出现在图像边缘”的错误空间位置先验。5. 数据增强策略对马铃薯小缺陷检测的影响5.1 关闭会让缺陷消失的几何增强YOLO 训练默认开启大量数据增强但对马铃薯缺陷检测有两类增强必须谨慎一是强透视变换二是随机裁剪加缩放。透视变换会把椭圆形的土豆拉成奇怪的四边形导致缺陷的纹理被拉伸随机裁剪后缩放会让小缺陷变成马赛克模型在验证集上看不清缺陷被迫用猜测输出。多数情况下缺陷检测的验证集 mAP 低不是因为模型没学好而是增强把标签对应的视觉特征破坏掉了。一个比较稳妥的增强配方如下# augment.yaml scale: 0.2 # 缩放幅度 fliplr: 0.5 # 水平翻转 mosaic: 0.5 # mosaic 概率调低 hsv_h: 0.01 # 色相变化调小避免绿色类误判 hsv_s: 0.3 hsv_v: 0.4mosaic 在聚划算场景中很有用但马铃薯表面颜色均匀四张不同光照的土豆拼在一起会让模型误把光照差异当成缺陷纹理所以概率降低到 0.5。色相变化从默认的 0.015 降到 0.01是因为绿皮和黑斑在 HSV 空间比较接近色相扰动过大容易让模型产生混淆。5.2 验证增强效果的三个标准混淆矩阵、特征图、坏例分析训练完一轮后除了看 PR 曲线还必须打开confusion_matrix.png。马铃薯缺陷检测里最常看到的是 black_spot 和 rot 互相混淆以及 green 被预测为背景。前者是因为早期腐败表面也会出现黑褐色斑点单靠 RGB 确实无法区分这时候要么增加近红外通道要么把两类合并成“表面可见缺陷”。后者是因为绿皮面积较小时模型将它与光泽阴影合并此时要把 green 的最小外接框标注补到位并在增强里减少阴影区域的像素权重。特征图可视化用于定位缺陷使用 YOLOv8 的 Grad-CAM 扩展或者直接输出中间层的特征响应。如果看到高危特征集中在土豆边缘说明标注时把边缘伪影标进去太多需要回查标注质量。最后把验证集预测结果导出成带标签的图像yolo predict modelruns/potato/exp1/weights/best.pt \ source/data/potato_defect/images/val \ save_txtTrue \ save_confTrue \ conf0.25生成的 txt 文件里每一行是类别 ID、置信度和归一化坐标拿它和 ground truth 做逐图比对筛选出漏检和误检的图像重点看漏检图里缺陷的尺寸、位置和遮挡情况。这一步比看 mAP 数字更有价值因为目标检测数据集的质量问题往往隐藏在坏例里而不是平均指标里。5.3 部署时的图像预处理要和训练保持一致很多项目训练时用 640 分辨率部署时为了跑实时视频流降到 416导致精度滑坡。马铃薯产线是静态成像帧率压力没那么大不建议随意降低推理分辨率。以 20ms 处理一张图的需求为例yolov8n 在 640 分辨率下用 RTX 3060 大约 8msCPU 上可能需要 80ms 以上但工业现场大多可以用 GPU 盒子或者编解码卡。推理前注意做同样的归一化操作YOLOv8 的 predict 接口默认做了 letterbox 和归一化但如果自己写 C 推理或 ONNX Runtime 部署需要把(img / 255.0)和减均值除方差的操作按训练时的参数复制过来。若训练时没改hyp.scale和hsv_h推理端不需要额外处理但图像输入的 BGR 与 RGB 顺序必须一致否则缺陷的颜色特征会完全错位黑斑可能被识别成绿皮。最后建议在项目收尾时把所有错误预测的置信度分数分布拉出来看一眼。如果模型在低置信度区间大量输出 0.30.5 的框说明训练数据里的缺陷样本不够“极端”可以针对性地补充低对比度、阴影遮挡、表面有水渍的样本。目标检测数据集的质量提升从来不是一劳永逸而是一个围绕坏例反复迭代的过程——马铃薯这种缺陷表观差异极大的对象尤其吃这一套。本文还有配套的精品资源点击获取