news 2026/9/9 23:39:16

布匹瑕疵检测实战:从数据预处理到YOLOv5训练全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
布匹瑕疵检测实战:从数据预处理到YOLOv5训练全流程

简介:这份数据集源自2019年天池布匹瑕疵检测赛题,覆盖32种布匹表面缺陷类别,面向计算机视觉学习者、算法工程师及工业质检相关团队,可用于目标检测、图像分类等模型的训练与验证。压缩包共935个文件,包含689张JPG原图、245个XML标注文件及1个TXT说明文件;XML中保存了缺陷边界框,便于直接接入VOC格式检测流程。整个资源包约927MB,图片以缺陷类别和拍摄时间命名组织,便于按需筛选。目前已有2914人浏览学习。客观来看,各缺陷类别样本数量不均,部分类别图片较少,标注质量也非完美,建议使用前进行数据清洗或扩展增强。该数据集仍有助于初学者理解工业布料瑕疵的视觉特征与标注方式,也可作为算法效果对比的基准资料。 2019年天池上有一个后来被很多人拿来练手的工业视觉赛题:广东工业智造大数据创新大赛·布匹瑕疵检测。这个比赛配套开放的布匹瑕疵数据集,几乎成了缺陷检测方向绕不开的入门资料。我一直想把这套数据上踩过的坑和跑通的经验完整梳理一遍,包括数据格式、模型思路、训练细节和各类排查技巧。如果你正准备复现这个比赛、做毕业设计,或者公司里正好有布料、纺织类的质检项目需求,这套方法论基本可以无缝迁移过去。

1. 布匹瑕疵数据集到底长什么样

1.1 来自真实生产线的图像数据

先说背景。这个比赛聚焦的是纺织行业的质检环节,数据来自真实生产线上的工业相机拍摄,不是实验室里摆拍出来的“干净样本”。所以图像里有大量现实世界的复杂情况:布料褶皱、纹理差异、光照不均、飞絮灰尘等等。这一点非常关键,因为真实数据和学术数据集最大的区别就是噪声无处不在,你的模型最终要面对的也是这种脏数据。

公开的布匹瑕疵数据集一般会分成训练集、验证集和测试集。训练集量级大概在五千到九千张不等,不同比赛阶段会有调整。单张图片的分辨率特别高,常见尺寸接近4000×1696甚至更高。为什么这么高?因为工业相机视野要尽量覆盖整匹布的宽度,为了看清细微瑕疵就必须保留高分辨率。但这对算法工程师来说就是个麻烦,后面我会专门讲怎么处理。

1.2 标注格式与六类瑕疵

这个数据集里标注格式在不同版本里略有差异,但社区里流传的版本大多是PASCAL VOC风格的XML,或者是JSON转成的VOC格式。每一张图对应一个标注文件,里面用矩形框标出瑕疵的位置和类别。

瑕疵类别主流是六类,下面我用表格直接列出:

瑕疵类型直观表现检测难点
破洞布料出现孔洞边缘不规则,容易和深色纹理混淆
水渍水痕浸染区域边界模糊,对比度极低
油渍反光的油污区域颜色与布匹底色接近,反光不稳定
三丝细线状异物目标极细、长条形、长宽比夸张
结头纱线接头或小坨尺寸小,还可能密集出现
网纹编织异常形成网纹状缺陷面积大但轮廓模糊,视觉上很不“框”

记得我刚开始做的时候,以为瑕疵检测就是普通目标检测,拿过来就跑YOLO,结果被“三丝”这类目标折磨得不轻。一条丝可能只有几个像素宽,横跨大半张图,普通anchor根本框不准。

1.3 和常见缺陷检测数据集有什么区别

很多人之前可能接触过NEU-DET,那是热轧钢带表面缺陷数据集,六类缺陷,共1800张图,目标相对居中且大小适中。但布匹瑕疵数据集完全不是这个难度,它的核心区别有三个。

第一,图像尺寸大了一个数量级,切片几乎是必须的。第二,瑕疵目标尺度极不均匀,既有大范围的网纹,也有几个像素的三丝。第三,类别分布严重不均衡,破洞、水渍这类样本很多,网纹、结头这类样本可能只有几十个。这些特性决定了你不能把一个常规目标检测pipeline原封不动搬过来,必须做针对性调整。

2. 为什么这批数据这么难搞

2.1 小目标、低对比度与长尾分布

很多人第一次跑这个数据集都会困惑:明明在COCO或者VOC上效果很好的模型,为什么到这里mAP直接崩盘?答案就藏在这三个难点里。

小目标问题最直接。以4000×1696的图为例,一个50×50像素的破洞,占整张图面积的比例不到万分之四。常规检测网络下采样32倍后,这个目标在特征图里只有不到2个像素,基本不可能被检测到。

低对比度问题更隐蔽。水渍这种瑕疵在布面上只是一块颜色稍微深一点的区域,人眼都得凑近了才看得清,模型提取特征就更是难上加难。处理这类目标时,光照归一化和对比度增强往往是提升效果的关键。

长尾分布则是数据层面的坑。我自己统计过一次,六类瑕疵里样本数最多的一类和最少的可能差几十倍。模型训练时会被多数类主导,少数类几乎学不到有效特征,推理时自然漏检严重。

2.2 检测框架选型的思路

框架选择没必要盲目追新。我在这个数据集上试过Faster R-CNN、YOLOv5和mmdetection系列,最后稳定使用的还是YOLOv5,原因有三个。

第一,YOLOv5对滑窗切片训练的兼容性非常好。切片之后每张小图相当于普通的自然图像,完全可以直接喂进去,不需要额外改网络结构。第二,社区生态成熟,遇到问题随便一搜就有答案,放工业项目里意味着迭代效率高。第三,YOLOv5的推理速度足够快,高分辨率图切片后虽然数量多,但整体吞吐量还是能满足产线需求。

如果你更习惯mmdetection,也可以用它跑通,只是配置和调参成本会高一些。Transformer系列检测器如DINO或CO-DETR我也试过,精度确实能涨一点,但对显存和训练时间要求更高,想要快速出结果的话还是先别碰。

2.3 不要直接拿整图训练

这是新手最容易犯的错误。把4000×1696的整图resize到640×640再去训练,结果就是所有目标都被压缩成了几个像素,模型能学到的东西非常有限。

直接拿整图训练还有三个实际问题:显存压力大,单张图可能就要占据几个G的显存,batch size根本提不上去;小目标经过多次下采样后完全丢失;正负样本比例极端失衡,背景占比太大,模型偏向于把所有区域都预测成背景。

所以业界通用的做法是“切块训练,切块推理”。简单说就是把大图切成若干个小块,比如1280×1280或者1024×1024,切成的小图作为训练样本。推理的时候也用同样的方式切分,最后把检测框映射回大图坐标再做去重合并。这个思路我下面会展开讲细节。

3. 从数据到模型:完整实操流程

3.1 先把标注转成模型能吃的格式

我习惯把数据集先整理成YOLO格式,也就是每张图对应一个txt文件,每一行是“类别 cx cy w h”,其中cx、cy是归一化后的中心点坐标,w、h是归一化后的宽高。

下面是VOC XML转YOLO txt的参考代码:

import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, out_txt_path, img_w, img_h): tree = ET.parse(xml_path) root = tree.getroot() lines = [] class_map = { 'hole': 0, 'water_stain': 1, 'oil_stain': 2, 'three_silk': 3, 'knot': 4, 'mesh': 5 } for obj in root.iter('object'): name = obj.find('name').text if name not in class_map: continue box = obj.find('bndbox') x1 = float(box.find('xmin').text) y1 = float(box.find('ymin').text) x2 = float(box.find('xmax').text) y2 = float(box.find('ymax').text) # 注意:有些版本的标注坐标从1开始,建议统一减1 x1, y1 = max(x1 - 1, 0), max(y1 - 1, 0) x2, y2 = min(x2 - 1, img_w - 1), min(y2 - 1, img_h - 1) cx = (x1 + x2) / 2 / img_w cy = (y1 + y2) / 2 / img_h w = (x2 - x1) / img_w h = (y2 - y1) / img_h lines.append(f"{class_map[name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") with open(out_txt_path, 'w') as f: f.write('\n'.join(lines))

这里有两个坑必须提醒。

一个是坐标偏移问题。PASCAL VOC的坐标是从1开始的,而像素坐标通常从0开始,如果不统一减1,所有框会系统性偏移一个像素。虽然单个框偏移一像素看起来不严重,但在细长目标上可能直接影响IoU计算。

另一个是类别映射表一定要固定。训练和推理阶段必须使用完全相同的类别ID顺序,否则模型输出和真实标签对不上,结果全部作废。

3.2 滑窗切片与坐标映射

切块这件事听起来简单,做起来有不少细节。我常用的参数是切片大小1280×1280,重叠率0.25。为什么不直接用640×640?因为切片尺寸越小,目标被切断的概率越高,而且每个切块里包含的上下文信息越少,模型识别大范围瑕疵时会吃亏。但切片尺寸太大又会增加显存压力,所以1280和三倍下采样后的中间特征图尺寸相对平衡。

重叠率的选择也很关键。重叠率太低,目标被切成两半的概率增加;重叠率太高,训练样本膨胀严重。0.2到0.3之间是比较常见的区间,我习惯用0.25,也就是步长取切片尺寸的75%。

切片后必须做一件事:把原始标注的绝对坐标转换成切块内部的相对坐标。这里最容易出错,因为一张大图切成多个切片后,如果坐标转换的偏移量算错,模型训练出来的框就会整体偏移。建议在代码里写一个调试函数,把切块图片和转换后的标注框画在一起,人工抽样检查几轮,确认无误再开始训练。

推理阶段同样用滑窗切块,得到所有检测框后映射回原图坐标,然后做NMS合并。跨切片重复检测是必然的,因为重叠区域的同一个目标可能被两个相邻切片都检测到,NMS可以很好地解决这个问题。如果你用了不同切片尺寸得到的多组结果,还可以尝试WBF(加权框融合),效果往往比单纯NMS更好。

3.3 训练配置、数据增强与评估

基础配置方面,我建议先用YOLOv5s跑通整个流程,确认没有数据格式问题后再换YOLOv5m或YOLOv5l提升精度。输入分辨率设成640×640起步,如果显存允许再调到1280×1280。一开始就上大分辨率的话,训练速度和调试成本都会高很多,不利于快速定位问题。

数据增强方面,YOLOv5自带的mosaic增强我建议保留,它对提升小目标的鲁棒性很有帮助。HSV颜色增强也建议开,但强度不要拉满,因为工业场景下颜色变化没有那么多,过度增强反而会让模型学到错误的颜色不变性。我还额外加了随机光照扰动,模拟生产线上不同时段的光照变化,这个操作在真实场景下涨点明显。

评估指标主要看mAP@0.5和mAP@0.5:0.95。但我要特别强调一句:工业项目里mAP@0.5通常更重要。瑕疵检测不需要非常精确的像素级框,框的位置差不多命中就够用了,mAP@0.5反而更贴近实际业务需求。另外每训练完一个阶段,一定要把badcase可视化图保存下来,盯着看一遍,比只看数字有用得多。

3.4 尾部类别的处理

针对网纹、结头这类样本数特别少的类别,我试过几种方法,效果排序大概是:复制粘贴增强大于重采样大于单纯调整损失权重。

复制粘贴增强的做法很简单:从训练集里找出包含目标类别的区域,把它们裁剪下来,粘贴到其他正常布匹图像的随机位置,同时生成对应的新标注。这个操作对“三丝”这类细长目标尤其有效,因为三丝本身占的面积小,粘贴进去不会太违和。但要注意粘贴位置尽量落在纹理均匀的区域,不要贴在已有的明显瑕疵上,否则标注会混乱。

重采样就是让模型每个batch里都能看到足够多的尾部类别样本,实现上可以在自定义Dataset里对样本数少的类别做上采样。这个方法逻辑最简单,但对训练速度有一定影响。损失权重调整我放在最后尝试,因为这需要比较多轮的实验来确定权重系数,投入产出比一般。

4. 训练和推理阶段的常见问题排查

4.1 mAP不涨,先怀疑标签而不是模型

我在这个数据集上最大的教训就是:模型效果差,大概率不是模型的问题,而是标签和预处理流程出了问题。

最常见的情况是坐标转换错误。XML转YOLO的时候,如果你忘了把坐标从1改为0,或者切片时偏移量算错,模型训练出来的框就会全部偏移。这类问题在loss曲线上往往看不出来,loss可能正常下降,但mAP就是上不去。

我自己的排查流程是:训练前随机抽取200张带标注的图片,把标签画回去,一张一张过目。不要嫌麻烦,这一步能省掉后面无数个小时的无效训练。只要看到框的位置和实际瑕疵对不上,立刻停下修代码,千万不要带着错误标签继续跑。

还有一个隐蔽问题是类别ID顺序。YOLO格式的txt文件里类别是用数字表示的,如果你训练和验证阶段用的类别映射表不一致,验证结果会乱成一锅粥。建议把class_map写成一个固定文件,所有脚本都从同一份文件读取,避免手动复制粘贴导致不一致。

4.2 漏检、误检和跨切片重复框

漏检的主要原因有两个:目标太小和训练样本不足。

目标太小靠提高输入分辨率解决。我测试过640和1280两种输入下的小目标AP,后者的mAP@0.5有明显提升。如果你的服务器显存不够,可以先在切块层面降低切片尺寸,比如从1280降到1024,这样至少能在batch size上保持可用。

样本不足靠增强和重采样,上一节已经提过,这里不重复。

误检则往往是因为背景太复杂。布料上的纹理、褶皱很容易被模型当成瑕疵。我的做法是增加一个后处理步骤:对每个检测框计算“瑕疵区域内部对比度”之类的特征,如果特征值太低就认为是背景误检。这个方法比较粗暴,但在某些类别上效果显著。

跨切片重复框是切块推理特有的问题,解决思路是在NMS之前把所有检测框统一映射到原图坐标,再做一次全局NMS。阈值可以适当调高,比如0.45到0.5左右,否则重叠区域的目标可能被保留多个框。

4.3 显存不足与训练时间失控

这套数据下显存不足太常见了。一块16G的V100,如果用1280×1280输入,batch size可能只能设到4甚至2,训练速度非常感人。

三个可行办法:开启AMP混合精度训练,显存能省接近一半;使用梯度累积,相当于用时间换显存;实在不行就降低输入分辨率,先跑通流程再优化精度。

另外提一句,如果训练时间实在不可控,优先检查数据加载是不是成了瓶颈。滑窗切片之后样本数量会膨胀很多,我的建议是提前把所有切片结果缓存成离线文件,而不是每次训练时实时切图。这样GUP利用率能明显提高,训练时间可以缩短一半以上。

我整理了一个高频问题速查表,方便你排查时参考:

现象检查方向解决办法
loss不降或震荡学习率、标签调低学习率,检查坐标转换是否正确
mAP@0.5低但loss正常数据、输入分辨率检查badcase图,提高切片分辨率
某个类别几乎不检出样本量、增强重采样、复制粘贴增强、降低该类置信度阈值
推理框明显偏移坐标映射检查切片到原图的坐标恢复逻辑
大量重复框NMS策略映射到原图后统一NMS,尝试WBF
训练集acc高验证低过拟合增大切片数量,加强增强,加早停

4.4 预处理一致性这类隐性坑

还有一个非常容易出现但经常被忽略的问题:训练和推理阶段的预处理必须完全一致。

比如我在训练时加了对比度增强和随机光照扰动,推理阶段如果不加,模型看到的图像分布和训练时不一致,效果自然会下降。尤其对水渍这种本来就低对比度的目标,预处理差异会直接导致漏检翻倍。

实际操作上,建议把预处理函数单独封装,训练脚本和推理脚本共用同一个函数。不要在两份代码里各写一份,哪怕复制粘贴都要避免,因为一旦改了其中一个忘了另一个,结果就是玄学。

5. 个人经验与后续扩展

5.1 一套可以直接复用的通用管线

做完整个比赛,我沉淀下来的通用管线其实很简洁:高分辨率滑窗切块、通用目标检测器训练、跨块结果合并。这套流程不仅适用于布匹瑕疵数据集,迁移到皮革表面缺陷、钢板表面缺陷、薄膜表面缺陷等场景,只需要改标注类别和切片参数。

建议你拿到一个新数据集后,先用最小的代价跑通一个baseline,把数据加载、训练、评估、可视化的完整链路确认没问题,再开始优化精度。我见过太多人一上来就堆Swin Transformer、各种trick,最后发现数据标签有问题,浪费了几天时间。

5.2 这个数据集还能怎么玩

如果你把检测做完了,这个数据集还有很多可扩展的方向。一个方向是把检测框转成分割mask,做像素级的瑕疵分割。因为矩形框对长条形的三丝和大范围的网纹表达不够精细,分割模型往往能拿到更好的业务效果。

另一个方向是无监督异常检测。只用正常布匹图像训练PatchCore这类模型,让模型学习“正常长什么样”,新样本只要偏离正常分布就视为瑕疵。这个思路对工业场景很有吸引力,因为实际产线上经常会出现数据集里没有的新瑕疵类型,监督学习模型对未知类别无能为力,无监督方案反而更灵活。

最后说一句我的真实体会:在这个数据集上刷分很容易让人上头,但真正有用的能力是能快速定位模型哪里不行、为什么不行。每跑完一轮实验,把预测错误的框画到图上,盯着看十分钟,比盲目调参有用得多。这也是我在布匹瑕疵数据集上最大的收获。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 23:38:01

用神经网络培养孩子的大局观:华容道中的认知教练

1. 这不是教孩子“怎么走”,而是教孩子“往哪看”“训练一个神经网络模型指导小孩玩游戏2-大局观教练”——这个标题乍看像极了某款教育类APP的宣传语,但如果你真把它当成“AI陪玩机器人”,那就完全跑偏了。我带过三届青少年编程夏令营&#…

作者头像 李华
网站建设 2026/9/9 23:37:33

网络安全求职攻略:从基础到SRC实战的全流程指南

又是一年开春,后台关于网络安全求职的私信明显多了起来。不只是应届生,很多做运维、开发甚至土木、机械的朋友都在问一个问题:现在转网络安全到底行不行?这行真有网上说的那么缺人吗?说实话,网络安全这股风…

作者头像 李华
网站建设 2026/9/9 23:34:50

IEC60870开源库选型与实战:lib60870从站/主站开发及排错指南

简介:lib60870-2.0.1是IEC60870标准的开源C语言实现库,面向电力自动化、SCADA及智能电网通信开发者,可直接集成101、102、104协议,支持主站/子站双向通信,省去从零实现复杂协议栈的代价。资源包共114个文件&#xff0c…

作者头像 李华
网站建设 2026/9/9 23:34:31

索爱W550C行货刷机实战:从固件选择到救砖全指南

简介:针对索尼爱立信W550C行货机型的刷机固件资源包,专为遭遇白屏、频繁死机、系统响应缓慢或功能异常的玩家与维修用户准备。压缩包共37个文件、约39.35MB,文件类型覆盖itm固件模块、bin系统镜像、exe刷机工具、inf/sys驱动、xml/log配置与日…

作者头像 李华
网站建设 2026/9/9 23:30:02

PIPE 4.3 Petri网建模与仿真实战:从环境配置到死锁分析

简介:PIPE4.3是一款经典的Petri网可视化建模工具,面向计算机相关专业学生、研究人员以及系统设计开发者,用于并发系统建模、动态模拟与一致性检查。资源包共包含2384个文件,核心为Java类文件、运行库、启动脚本以及界面资源&#…

作者头像 李华