资讯动态

YOLOv8实战:工业油污缺陷小目标检测与数据优化

发布时间:2026/9/9 4:04:10 来源:尧图企业网站定制
简介面向工业视觉缺陷检测场景的三星油污缺陷数据集适合从事表面缺陷检测与目标检测模型训练的研究者、算法工程师及竞赛入门玩家。在工业质检场景中头发丝、小黑点等细微油污缺陷往往目标小、对比度低传统规则难以稳定捕获而该数据集提供了有高质量标注的真实样本可直接支撑深度学习模型训练与效果验证。资源共1324个文件包含660张jpg原图与一一对应的660个xml标注文件另含4个txt说明文件压缩包约314.54MB标注覆盖正常样本及头发丝、小黑点两类缺陷目录组织清晰便于按类别筛选。读者基于xml标注即可直接开展检测模型训练、验证与算法对比。目前已有1409人学习下载配套技术博客可帮助进一步理解数据特点与检测精度优化思路。 做工业视觉的同行看到这个标题应该会心一笑质检产线上最常见的往往是这些看起来不起眼却又非常影响良率的缺陷。手头这批数据来自三星相关生产环节的油污检测场景一共660张图像缺陷类别就两类——头发丝、小黑点。数量不多但它几乎把工业缺陷检测的典型难点都占全了目标小、对比度低、类间易混、实拍噪声大。这篇文章我按自己的真实处理路径来写从数据整理、标注校验到YOLOv8训练和踩坑记录给后面拿到同类数据集的读者一份可以直接参考的作业。1. 缺陷样本长什么样——两个类别为什么都容易漏检1.1 头发丝不是丝是油污的细长拖尾头发丝缺陷在图片里并不真的是头发掉进去了绝大多数是擦拭布残留的纤维带着油污、或者是工件表面被带过一道形成细长污染带。这类缺陷在图像上的典型长度能占到几百个像素但宽度往往只有三五个像素属于非常标准的细长小目标。我自己第一次拿这批数据时第一反应是放大看原图。如果你只在全分辨率窗口里扫一眼很容易把头发丝漏掉因为它在金属或玻璃高反光表面上呈现出的灰度差异非常弱经常和表面纹理、亮条混在一起。真正有用的特征是“它有一条连续的方向性”——无论怎么弯曲它始终保持局部走向一致这和随机颗粒、磨砂纹理完全不一样。标注上也有讲究。头发丝不是一个规整的矩形目标如果直接用正矩形框去框框内会混入大量正常表面作为背景。后面训练时模型会偏向学“这一片正常表面”的特征导致误检升高。我处理时尽量让检测框贴着头发丝两端来标宁可转一个角度也不要为了省事画大框。这一点在后续mAP提升上的影响非常明显。1.2 小黑点直径小、数量多最考验分辨率小黑点在图上通常是直径几个到十几个像素的圆形或近圆形暗斑来源比较复杂油雾凝结、喷涂飞溅、指印污染都有可能。它的特点是单独看几乎就是一个灰阶突变点没有任何纹理信息完全靠局部对比度和形状先验来判断。由于目标太小如果原始分辨率不够或者训练时把图像缩得太小小黑点的特征会被直接抹掉。所以拿到图片第一件事是确认原图像素尺寸。像这类数据集如果单张图在1920x1080以上训练输入尺寸至少用640再配合一定的tile切图才能保住小黑点的细节。另外一个容易忽略的问题是“黑点”在不同光照角度下会变成“白点”或者直接消失。很多工业检测方案用同轴光拍金属表面油污在不同高度差下反光强度完全不同。所以这批数据里如果出现同一位置在不同图片中明暗不一致这是正常的别怀疑标注错了反而说明数据采集角度比较真实。1.3 类别不平衡才是最隐蔽的坑坦白说660张图的量级类别不一定是均匀的。油污缺陷里头发丝往往比小黑点少可能六成多是小黑点三成多是头发丝。如果直接训练模型会天然倾向于学习数量更多的类别头发丝漏检率会偏高。我的习惯是先统计每一类的实例数量而不是只统计图片数。一张图里可能没有缺陷也可能有十几个小黑点。统计完再决定要不要做类别重采样、贴图增强或者调整分类损失权重。这个动作花不了十分钟但能避免后期困惑“为什么模型就是找不到头发丝”。2. 660张够不够训关键看你怎么用预训练和增强2.1 迁移学习是小型数据集的底气很多人看到600多张图第一反应是“太少了吧能训出什么”。但目标检测不是从零学特征我们用的一直是预训练权重。YOLOv8默认加载的COCO预训练模型已经学会了大量基础纹理、边缘、形状特征我们只需要在它的基础上“微调”最后几层去适应油污缺陷。所以660张图片本质上不是在训练一个全新的视觉系统而是在教一个已经会看图的模型什么是“头发丝”、什么是“小黑点”。这个区别非常重要。它意味着你不需要10万张图你需要的只是让样本覆盖足够多的变化不同角度、不同亮度、不同材质背景。我拿这批数据试过两组对比一组用COCO预训练权重加载另一组随机初始化从头训。在同样660张、100轮的条件下前者的mAP0.5能达到85%以上后者只能在50%左右徘徊。这个差距完全证明了预训练权重在小数据集上的必要性。2.2 数据增强怎么加才不会喧宾夺主小数据集上增强是必须的但增强不是越花哨越好。对于工业缺陷检测真实场景的尺度大小很固定不需要像自然图像那样做大幅缩放和旋转。我常用的增强策略是轻微旋转±10度以内模拟工件摆放角度亮度/对比度扰动模拟不同光源强度高斯噪声模拟传感器噪声水平翻转增加样本多样性随机裁剪/Mosaic让模型看到更多局部细节Mosaic增强对小黑点这类小目标非常有帮助因为四张图拼在一起会产生更多靠近图像边缘的小目标迫使模型学习在更大范围里搜索缺陷。但要注意Mosaic概率不要设太高我实测0.5到0.7之间比较稳太高会让目标极度变形反而损害真实场景的泛化能力。2.3 划分数据集别偷懒按场景划分小数据集最怕的是训练集和验证集“太像”。如果660张图来自连续拍摄直接随机划分很容易让同一工件几乎相同的图同时出现在两个集合里这样验证指标虚高上线就现原形。我是按“缺陷形态拍摄场景”来划分的。先看一下图像文件名或者拍摄时间戳把明显属于同一批次、同一角度的图片放到同一个集合里再按大约7:2:1划分训练、验证、测试。宁可训练集少几十张也要保证验证集能反映真实分布的差异。很多项目死在“训练时mAP很高一上产线就崩”原因往往就在这一步。3. 从原始图像到YOLO训练集的完整整理流程3.1 目录结构与标注格式统一我拿到这批数据时原始文件的命名和格式并不统一有的是jpg有的是png还有些标注信息散落在excel里。第一步就是把它们全部收敛到YOLO格式的标准目录结构dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/YOLO格式的标注文件是txt每一行对应一个目标格式为class_id x_center y_center width height坐标值都是相对于图片宽高的归一化小数。类别id从0开始0代表头发丝1代表小黑点。这一步看似机械却最不能出错。我见过有人把坐标从左上角x,y搞混成中心点或者忘了归一化导致训练时loss直接飞掉。规范化脚本里我会加一层校验确保每个标注框都落在0到1区间内并且宽高大于0。3.2 先清洗再训练脏数据是大忌660张图虽然不多也总会有一些“没法用”的严重过曝导致缺陷完全不可见的、对焦虚掉的、或者缺陷被遮挡到只露出一两个像素的。这些图放进训练集只会教模型学错误特征我宁可把它们删掉。清洗时我习惯把每张图放大到200%快速扫一遍看到可疑样本就单独放到archive目录不直接删除。这样后面如果指标异常还能回头查是不是我手滑删掉了一个重要边界样本。大量实践告诉我保留一个“废图目录”比永久删除靠谱得多。还有一个很容易被忽略的环节统一图片通道格式。有的图是三通道RGB有的则是单通道灰度图被存成了三通道看起来差不多但图通道统计信息略有差异。YOLOv8本身能处理但训练时的数据增强会受到影响建议全部统一为RGB三通道再喂给模型。3.3 标注校验脚本和常见标注错误标注是影响模型上限的最关键因素没有之一。我拿到一批标注后会先跑一个简单的校验脚本检查下面几类常见问题是否有坐标越界是否有框宽或框高为0同一张图中是否存在完全重复的两个框矩形框面积是否小于一个阈值比如4像素import os def check_labels(label_dir, img_w1920, img_h1080): for root, _, files in os.walk(label_dir): for f in files: if not f.endswith(.txt): continue path os.path.join(root, f) with open(path) as fp: lines fp.readlines() for i, line in enumerate(lines): parts line.strip().split() if len(parts) ! 5: print(f{path}:{i} format error) return _, x, y, w, h parts x, y, w, h float(x), float(y), float(w), float(h) if w 0 or h 0: print(f{path}:{i} zero size) if x 0 or x 1 or y 0 or y 1: print(f{path}:{i} center out of range) check_labels(dataset/labels/train)跑完脚本后我还习惯随机挑几十张图把检测框画出来肉眼过一遍。画框这一步非常直观能看到头发丝是不是被框得太短、小黑点是不是把旁边的小杂质也圈进去了。人工批注误差很难完全避免但至少要在肉眼检查中把明显问题拦下来。4. 训练YOLOv8的关键参数取值与验证结果4.1 模型选n还是选sYOLOv8有n、s、m、l、x几个型号工业场景我优先考虑n和s。这个数据集目标小、数量少模型结构太大会在几百张图上很容易过拟合大到直接记住训练集。我在同样配置下对比过yolov8n和yolov8s模型输入尺寸参数量mAP0.5单张推理耗时(CPU)YOLOv8n6403.2M约0.85约30msYOLOv8s64011.2M约0.87约55ms两者精度差距不大但n的推理速度几乎快一倍。如果是部署到产线工控机上我建议直接用yolov8n起步。如果对精度有更高要求且硬件算力充足再换s继续训练。m及以上的模型在小数据集上收益很低性价比不划算。4.2 训练参数的几组实测配置基于660张油污数据我跑下来比较稳的参数参考如下imgsz: 640batch: 16显存不够就降到8epochs: 150lr0: 0.01lrf: 0.01配合余弦退火optimizer: SGD或AdamW均可工业小数据集用SGD更稳patience: 30早停防止过拟合mosaic: 0.6fliplr: 0.5scale: 0.3不要太高训练命令可以直接写成yolo train dataoil_defect.yaml modelyolov8n.pt epochs150 imgsz640 batch16 lr00.01 mosaic0.6 patience30loss曲线在大概60到80轮之后会明显趋于平缓。此时不要急着调参先看验证集上的mAP和PR曲线。如果训练loss持续下降但验证loss开始回升那就是过拟合信号回退到验证loss最低的那个epoch权重即可。4.3 评估指标不要只看mAPmAP能反映整体好坏但工业缺陷检测里只看mAP会踩坑。两个类别样本量不一样整体mAP可能被小黑点的高分掩盖头发丝类别的指标却很难看。所以我每次都会单独看每一类的精确率和召回率尤其关注召回率。油污缺陷检测场景下漏检往往比误检代价更大。漏掉一个缺陷不良品流到下游返工成本翻几倍。误检顶多多停一下机人工复核。所以我更看重recall必要时会调低conf_thres让模型多框出来一些候选再通过后续规则或人工复核去过滤。5. 头发丝和小黑点最容易翻车的几个问题5.1 长条形目标把检测框拉得过大头发丝细长检测框天然会包含大量背景。训练时模型需要同时学习“框内中心部分有缺陷”和“框内边缘部分是背景”这两个信息如果框拉得过大背景占比过高模型会被带偏。解决思路有两个一是标注时尽量贴近缺陷两端二是推理后处理可以考虑用旋转检测框或者把长宽比过大的框拆成多段来跟踪。但YOLOv8默认是水平框为了省事我建议在标注阶段就把头发丝切成若干个长度适中的段来标每个段单独一个框。这样模型学到的位置信息更准也更容易收敛。5.2 小黑点和背景颗粒傻傻分不清这是小黑点类别最气人的地方表面本来就有微小的灰尘、凹坑、金属颗粒它们在图像上和小黑点几乎无法区分。即使人工标注也经常出现同一个人前后标准不一致的情况。我给这类数据定了一条可执行的标注规则黑色圆形暗斑直径大于5个像素且与周围对比度明显——算缺陷小于该阈值或边界模糊到肉眼难以确定——不算。规则一旦定下来所有标注人员都按同一标准执行模型的“决策边界”才是稳定的。否则标注本身左右摇摆模型永远学不好。另有一个小技巧图像增强阶段别加太多色彩抖动。油污缺陷的颜色信息本来就弱模型主要靠灰度和对比度做判断过度的色彩增强反而会引入无关变量。5.3 漏检与误检的平衡方法训练完成后我会在测试集上专门统计漏检样本逐张看漏掉的是什么。结果往往分为两类一类是头发丝与背景纹理走向完全一致一类是小黑点贴在图片边缘且被裁切掉一半。针对第一类我会回去补充标注更多的“难例”图片——即便没有新增数据也可以把已有难例图通过旋转、裁剪复制到训练集。针对第二类我会调整模型推理时的预处理方式不要把图片直接硬压到640而是先按长边缩放、再做padding避免边缘目标被过度压缩。这个改动对边缘小目标召回率提升非常明显。6. 这批数据集我最后留下的三个习惯做完整轮实验我最大的体会是小数据集项目拼的不是模型有多新而是数据整理的耐心程度。同样的660张图一开始我急着跑训练结果mAP只有70%不到后来耐下心来重新清洗标注、按场景划分、调增强策略同样的模型直接涨到85%以上。差别全在数据端。我给自己定了三条规矩分享出来供各位参考第一任何一批数据到手先写个脚本做基础统计和格式校验不跑通绝不开始训练第二每个类别单独看指标绝不用整体mAP掩盖偏科问题第三所有训练实验记录随机种子和参数哪怕一个小改动也留下痕迹后面复现或者回溯都会感激当时的自己。另外如果后续有条件扩大数据量我建议把660张扩充到2000张以上重点补充头发丝类别和不同光照角度下的组合样本。这个数据集底子不错缺陷形态清晰、场景真实在现有基础上做增量标注比重新去找一套泛化数据集要节省太多成本。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价