尧图精选

表面缺陷检测实战:从传统图像算法到深度学习的完整指南

🕒 发布时间:2026/9/16 1:25:41 📁 来源:尧图网络
如果说机器视觉在工业自动化里是那个最会“挑刺”的技术那表面缺陷检测绝对算得上“挑刺中的地狱模式”。我在产线改造项目里做过不少视觉方案测尺寸、做定位一般几天就能跑通一旦碰上缺陷检测事情就变得棘手——同一块金属外壳换个打光角度那条划痕可能就消失了同一条划痕换一批物料批次算法又可能认不出来了。这几年总有同行问我缺陷检测到底是怎么做的用传统图像算法还是深度学习为什么别人家的方案能检出来我的就检不出来这篇文章不打算照搬教科书定义而是从一个视觉工程师的视角把表面缺陷检测这件事拆开讲清楚它到底在检测什么、传统方法和深度学习各自怎么用、一个项目从需求到上线要经历哪些坑。1. 缺陷检测到底在检测什么把“肉眼能看出的问题”翻译成“算法能算的问题”1.1 缺陷检测不是“找不同”而是“定义异常”跟尺寸测量、定位引导不一样缺陷检测没有一个绝对的标准答案。测一个孔的直径孔径是10毫米还是10.05毫米卡尺一量就知道但一条划痕深不深、长不长、算不算不良品不同的人可能有不同的判断。这也是缺陷检测项目最容易被低估的地方——你连“什么是缺陷”都没法用一句话说清楚时算法就更无从下手。所以做缺陷检测的第一件事不是选算法而是把缺陷翻译成图像特征。从视觉角度去看所有表面缺陷归根结底都是四类特征的异常灰度异常比周围亮或暗比如脏污、色斑、发黄边缘异常本应连续的边界断了比如裂纹、缺料、崩边纹理异常表面纹路出现方向、周期性的局部破坏比如拉丝金属上的刮痕、布面上的织疵颜色异常色相、饱和度偏离正常范围比如电镀件发黑、塑料件发白。划痕看起来千变万化但在图像里就是一条低灰度或高灰度的细线线两侧有灰度跳变脏污就是一块灰度跟背景差异明显的区域凹陷则更隐蔽它不一定有颜色变化而是因为光照角度产生了一片阴影本质上还是灰度异常。把缺陷理解成“某种图像特征被破坏了”后面选算法、调参数才有方向。1.2 为什么表面缺陷检测比想象中难很多人以为缺陷检测就是把产品拍一张照片然后“看一眼”有没有问题。实际上表面缺陷检测难在几个地方。第一是缺陷形态极度不可控。同样是划痕有的是直线、有的是弧线、有的断断续续像虚线同样的脏污有时是油渍、有时是粉尘、有时是水渍干了之后留下的痕迹。传统算法要靠人工设计特征来覆盖这么多形态很容易顾此失彼。第二是对比度太低。很多缺陷在肉眼下都很勉强到了相机里更是一片糊。尤其是透明材质玻璃、薄膜或高反光材质镜面、电镀件缺陷和背景的灰度差可能只有几个像素值噪声稍微大一点就淹没掉了。第三是背景本身的干扰。金属拉丝表面的纹理、铸件表面的颗粒感看起来跟缺陷很像。算法容易把正常纹理误判成缺陷这也是过检率居高不下的主要原因。还有一个隐藏难点是样本分布极不均衡。正常品成百上千件真正有缺陷的可能百里挑一而且每件缺陷长得都不一样。这种数据分布让很多“看起来很厉害”的深度学习模型直接失灵。1.3 衡量缺陷检测好坏的三个指标不管是跟客户沟通还是内部做方案评审有三个指标绕不开指标含义实际影响检出率/召回率检出的真实缺陷数占实际缺陷总数的比例漏检意味着不良品流出客户最关心过检率/误检率被判为缺陷的正常品数量占比过检导致产线复检量暴增人工成本上升节拍单件检测耗时检测速度跟不上产线所有算法白搭一个容易踩的误区是只盯着检出率把阈值调到能抓到所有缺陷结果过检率高得吓人。现场运营人员每天要复查几百上千个“疑似不良”嘴上不说心里已经想换掉这套系统了。缺陷检测项目的实质是在漏检和过检之间找一个产线能接受的平衡点而不是追求“零漏检”的完美主义。2. 传统机器视觉三板斧阈值、形态学与Blob是怎么把划痕揪出来的传统图像算法在缺陷检测领域依然占据很大比重尤其在前几年深度学习方法还没这么普及的时候工厂里真正跑稳的方案基本都是传统方法。我拿当初做过的一个金属外壳表面划痕检测项目来举例把整个处理链路拆开讲。2.1 预处理先把图像弄干净再谈检测相机拍出来的原始图像直接拿去分割往往效果很差。噪声、光照不均、背景纹理都会干扰判断所以第一步通常是预处理。针对划痕检测我习惯先用中值滤波或高斯滤波去除传感器噪声。划痕是窄条状的信号中值滤波在去噪的同时能较好保留边缘比均值滤波更合适。比去噪更重要的是光照不均的校正。金属外壳是曲面打光很难做到完全均匀图像上会有一个从亮到暗的缓慢背景变化。如果不处理阈值分割时暗区的正常区域会比亮区的划痕还暗根本没法用固定阈值。这里我常用形态学顶帽变换用一个大尺寸的结构元估计背景再用原图减掉背景把缓慢变化的背景压平让局部异常的划痕凸显出来。这一步做完很多对比度低到肉眼都费劲的划痕在图像里会变成清晰的暗色细线。2.2 阈值分割与Blob分析划道“分数线”再把合格的筛出来预处理之后做阈值分割目的就是把“可能是缺陷”的像素从背景里分离出来。光照均匀的场景用全局阈值就行比如大于180的算亮缺陷、小于60的算暗缺陷。但工业现场很难保证绝对均匀所以局部自适应阈值更常用——每个像素跟自己周围一块区域的均值做比较超过偏移量就判为缺陷。这就是为什么Halcon里的dyn_threshold或者OpenCV里的自适应阈值在缺陷检测里出场率这么高。阈值分割出来的通常是很多离散的像素块这时候要做形态学处理开运算去掉孤立的噪点闭运算把断裂的划痕线段连接起来。做完形态学再用连通域分析把像素块变成一个个独立的区域。拿到区域之后Blob分析才是真正“出结果”的地方。我会提取每个连通域的面积、长宽比、长度、圆度、灰度均值等特征再按规则筛选。比如金属外壳上值得判不良的划痕面积要大于某个值、长宽比要大于5:1太短太粗的可能是磕碰伤要另算圆溜溜的小点大概率是灰尘。注意Blob分析的阈值参数不要只调面积。实际项目里长宽比和灰度对比度往往比纯面积更可靠因为同一类缺陷在不同批次物料上面积波动可能很大但形状特征相对稳定。2.3 背景固定用差影周期纹理靠频域划痕检测用阈值Blob能解决大部分场景但还有两类情况需要上更“讲究”的传统方法。一类是背景完全固定的场合比如检测固定治具上的印刷品、芯片引脚可以把标准图像提前存好检测时直接做差影法——待测图跟标准图相减差异大的区域就是缺陷。差影法的优点是速度快、实现简单缺点是对打光稳定性要求极高光源稍微变一点整幅图的差值都会变大误报飙升。另一类是周期性纹理表面比如拉丝金属、编织物。这类表面正常时就有一排排规律的方向纹理直接在空间域做阈值分割会把纹理本身当成缺陷。这时可以转到频域处理正常纹理在傅里叶频谱上会形成规律分布的亮点一旦表面出现划痕、压伤这些频域特征会被破坏。用带通或陷波滤波器把正常纹理的频段抑制掉剩下的就是真正的异常区域。Gabor滤波器也常用于这类场景它可以单独提取特定方向、特定频率的纹理分量用来检测拉丝金属上的横向或纵向刮伤。传统方法的优点很实在速度快单张图几毫秒到几十毫秒逻辑透明出了误检能直接定位是哪一步规则导致的调试维护方便。缺点也是明摆着的——设计特征全靠工程师的经验换一个产品、换一种缺陷可能整套参数就得重新调。3. 深度学习检测模型什么时候必须上YOLO什么时候用传统算子更快近年来YOLOv8这类目标检测模型在缺陷检测里很火但不代表每个项目都该无脑上深度学习。我在实际选型时有一套自己的判断标准。3.1 先想清楚传统方法是真的做不了还是你还没调到位深度学习不是万能的。它需要大量标注数据、GPU推理硬件、更复杂的工程链路而且模型误检后的排查难度远高于传统规则。因此我的习惯是先问三个问题缺陷和背景在灰度、形状、纹理上是否有可描述的差异如果有传统算法大概率能解决。缺陷形态是否高度统一比如金属表面的规则压印不良每个都差不多用模板匹配或差影就够了。产线节拍是不是极快传统算法在普通工业PC上轻松跑到几十毫秒内深度学习模型同样条件下可能要多出几倍的推理时间。只有当缺陷类型复杂多变、跟背景纹理长得太像、甚至人眼都要想一下“这算不算不良”的时候才轮到深度学习出场。3.2 用目标检测模型做缺陷定位与分类YOLOv8这类目标检测模型检测的是“图像里有什么缺陷、缺陷在哪个位置”。它的用法很直接采集一批缺陷图像用标注框把缺陷圈出来标注类别划痕、脏污、缺料……然后划分训练集、验证集、测试集训练完成后再导出成推理模型部署到产线。这里有一个经常被忽略的细节数据集的数量和质量。很多刚入门的朋友觉得“只要我标注几百张就能跑”实际产线上做工程化每种缺陷类别最好有500到2000个实例起步而且必须保证缺陷的多样性——不同光线、不同位置、不同严重程度都要覆盖到。否则模型在实验室里mAP再好看一到现场就会被没见过的“新长相缺陷”打得措手不及。训练细节上工业缺陷图像往往分辨率很高比如500万像素、1200万像素的工业相机。直接把整张图缩放到YOLO的默认输入尺寸通常是640×640小缺陷会被压缩到几个像素基本等于没检测。我常用的做法是把大图切成多个patch或者用Tiling推理的框架让模型在放大后的局部图上找缺陷检出的效果会好很多。3.3 细长划痕类缺陷分割模型比目标检测更合适目标检测输出的是一个矩形框但划痕、裂纹这类缺陷细长且不规则用框标注会框进大量正常背景训练时模型会被这些背景干扰。更合适的是用语义分割模型比如U-Net或者DeepLabV3输出一个像素级的缺陷掩码不仅定位精确还能直接计算缺陷的长短、面积给后端的机械手剔除或复检工序提供更准的信息。分割模型训练时标注成本确实高一些因为要在缺陷边缘一像素一像素地描轮廓。但工业项目里我反而更推荐在细长缺陷场景用分割因为传统方法加形态学处理之后的区域测量逻辑可以直接用在分割结果上业务衔接很顺。3.4 工业场景深度学习的三个坎第一是样本少。缺陷本身很少出现靠自然产生来积累样本项目周期根本等不及。解决思路有几条一是迁移学习用预训练权重在小样本上微调二是合成缺陷把真实的缺陷贴图叠加到正常产品图像上做增广三是刻意收集把试产阶段的次品全部保留不要只留存样。扩增的时候要注意像翻转、旋转、加噪这些通用操作可以用但不要改变缺陷的本质特征比如把一条划痕翻转成一条横向划痕可能不符合真实物理形态。第二是小目标。缺陷只占图像几个像素时检测难度极高。除了切patch还可以使用高分辨率输入、调整模型anchor尺寸甚至把“是否缺陷”和“缺陷在哪”拆成两步——先用传统算法框出可疑区域再用深度学习对可疑区域做精确分类。这种做法我称之为“传统深度混合”在很多项目里比单个大模型更稳、更快。第三是算力与节拍。产线上动辄要求2秒甚至1秒检测一件工业PC不带GPU的话跑深度学习模型很吃力。落地时一般会做模型轻量化用更小的backbone、做剪枝量化、转成ONNX后用TensorRT加速。我在一个手机外壳检测项目里把YOLOv8s裁剪量化之后推理时间从80毫秒压到了25毫秒精度损失在可接受范围内。4. 从一个真实需求到上线打光、选相机、定阈值缺陷检测项目的落地链路很多方案死在实验室里不是因为算法不行而是因为需求没谈清楚、成像没做好、验证方式不严谨。一个缺陷检测项目真正跑起来的链路我总结下来有这么几步。4.1 先谈指标再谈算法项目启动会上我会要求客户填一张表逐项列清楚缺陷类型具体描述最小尺寸要求允许漏检率允许过检率划痕长条形凹陷可见但无明显手感长度≥2mm且深度≥0.02mm0.1%3%脏污油渍、白斑不可擦拭直径≥0.5mm0.05%2%这张表决定了后面的所有选型。如果客户说“所有缺陷都要检漏检为0”那这个项目还没开始就已经不可能了——你需要把目标量化成“什么尺寸以上的缺陷、允许多少过检率”这样才能在验收时有据可依。4.2 打光方案决定检测上限我一直跟团队强调缺陷检测里光学方案决定了系统的上限算法只是在下限附近做补救。光源选得好一条细微划痕在图像里黑白分明光源选得不对再好的算法也无能为力。常用光源选型逻辑是这样的环形光均匀照明适合大多数表面但划痕这类凹陷缺陷表现一般。低角度环形光/条光光线几乎水平地掠过表面凹凸不平的缺陷会产生阴影或散射是金属、玻璃表面划痕检测的首选。同轴光光路跟相机同轴适合高反光平面能看清铭牌字符、镜面划痕。背光相机对面打光看轮廓适合透明物体内部的缺陷、异物。穹顶光多次反射形成均匀光照适合曲面、球面。回到金属外壳划痕的案例当初我试过同轴光划痕若隐若现换成低角度条形光之后细小划痕在图像里变成一条条清晰发亮的线因为划痕破坏了表面的平滑反射把光散射到了相机方向。打光这一步看似简单实际上占了整个项目一半以上的工作量。4.3 相机和镜头的参数怎么定相机分辨率取决于需要识别的最小缺陷尺寸。一个粗略估算公式是单像素精度 视野宽度 ÷ 传感器水平像素数。假设视野宽度是100mm要检测0.05mm的划痕一般至少需要3个像素来稳定识别那么单像素精度至少要0.015mm换算下来相机水平像素数需要100 ÷ 0.015 ≈ 6667像素也就是说至少选600万像素级别的相机。如果景深要求高还要考虑使用远心镜头它能保证不同高度的物体成像大小一致减少畸变。帧率相对好算如果节拍是2秒一件加上算法处理时间相机触发帧率能到1fps就够。但如果产线是连续运动的比如传送带不停就需要线阵相机配合编码器按运动速度计算行频这部分通常要单独做机构方案。4.4 算法选型的决策要点验证阶段我会在样机上装好光源和相机采集几百张真实样本然后按以下逻辑快速定方向缺陷在图像里灰度差异明显、背景简单 → 用阈值分割Blob半小时能出结果。缺陷是纹理异常、背景有方向性纹理 → 优先试频域滤波或Gabor不行再上深度学习。缺陷类型多且杂、形态不固定 → 用YOLOv8/分类网络按缺陷类型分别训练。细长、不规则的划痕裂纹 → 用分割网络输出掩码再算长度面积。选型不是一次到位的。我曾经做个项目先用传统方法做了第一版检出率只有80%后来改成“传统定位深度学习分类”的混合方案把检出率提到了97%同时过检率控制在2%以内。混合方案的核心思路是传统算法负责“快而广”的候选人筛选深度学习负责“准”的精细决策两边各干自己擅长的事。4.5 现场调试与验收实验室跑完不代表项目结束。上现场之前我强烈建议先离线验证一组包含正常品和缺陷品的混合样本让团队用测试集把阈值调好不要到现场边跑边调。现场调试时重点关注两件事一是环境光的隔离产线上的顶灯、窗户光、安全警示灯都会影响成像一致性加遮光罩、用频闪光配合外触发可以明显改善二是长期稳定性新系统最好连续运行一周每天统计漏检和过检数量而不是只跑两个小时就宣布验收通过。5. PCBA、电机绕线、玻璃、外墙与隧道不同行业的检测差异在哪里表面缺陷检测没有一个通用的万能方案每个行业都有自己独特的成像和算法组合。这里结合我接触过的几个典型场景拆一下它们各自的门道。5.1 PCBA缺陷检测PCBA线路板组件检测的特点是小目标密集、缺陷类型多常见的包括元件缺失、贴装偏移、桥连、少锡、字符不良。传统AOI自动光学检测设备通常先做基准点定位再用模板匹配或深度学习对每个焊盘、引脚做局部判断。由于板面复杂深度学习方案往往比纯传统方法表现更好尤其面对元件种类多的板子时靠人工写规则会写到崩溃。检测速度和误报的平衡是最大挑战产线节拍通常要求在几秒内完成整板检测所以常用的做法就是前面提到的“先定位可疑区域再精确分类”。5.2 电机转子绕线缺陷检测电机转子上密布漆包铜线绕线层叠交错正常状态下纹理已经非常复杂再叠加绕线松脱、断线、绝缘层损伤这类缺陷传统算法很难用简单的阈值解决。这个场景的成像关键是把绕线表面的“立体感”照出来通常用低角度光营造阴影缺陷处会产生明显的灰度或纹理突变。算法上可以先做方向纹理分析找出异常区域再用深度学习区分“真缺陷”和“绕线交叠产生的假影”。需要特别注意的是绕线有方向性同一个缺陷在不同角度下表现差异很大训练数据要尽量覆盖多个旋转角度。5.3 玻璃与镜面划痕检测玻璃检测的难点是透明和反光。常规照明下玻璃表面的浅划痕几乎看不见需要采用暗场照明也就是让光线以很低的角度掠射玻璃表面微小的划痕会把光线散射进相机镜头在暗背景上形成亮线对比度一下就出来了。实际项目中长条玻璃一般用线阵相机配合线扫光源一边传送一边成像效率和效果都很好。算法上传统频域方法和深度分割都常见但玻璃划痕检测真正难的不是算法而是怎么把划痕“照出来”。5.4 外墙与隧道缺陷检测这两个场景跟产线检测不太一样属于大尺度、户外环境的结构表面检测。外墙缺陷包括裂缝、空鼓、渗水痕迹数据由无人机搭载相机采集分辨率高但光照不稳定、背景复杂还经常有窗户、管道等正常结构干扰。隧道缺陷则是移动检测车搭载线阵相机和激光扫描在行进中连续采集衬砌图像重点检测裂缝和渗漏水。这类场景由于环境复杂、缺陷形态多样深度学习几乎是必选方案而且通常是分割模型为主因为裂缝是细长不规则的。难点在于样本标注成本极高以及不同光照、不同距离下图像一致性差模型泛化能力会受到很大考验。6. 我踩过的几个坑样本、阈值、光源与“一个模型打天下”的错觉6.1 只拿“好看”的缺陷图做验证现场一秒破功早期做项目时我习惯让客户提供一些典型缺陷样件用来调算法。实验室里检得干干干净净一到现场就发现漏检不断。原因很简单客户给的样件都是“一眼假”的明显缺陷现场产线上真正让操作工头疼的是那些模棱两可的边界案例。现在我做验证时一定会强调缺陷样本必须覆盖轻微、中等、严重三个等级而且要预留一部分现场随机采集的样本用来压测不能用同一批图又调参又验收。数据体系建得越早后面返工就越少。6.2 阈值调得越严过检率越爆炸有个项目客户咬死“漏检必须为零”我把阈值压得很紧结果任何一点灰尘、水渍、指纹全都被判成缺陷过检率超过20%现场复检工位忙到瘫痪。后来跟客户重新对齐用一条PR曲线说明漏检和过检之间的关系一起定了一个“漏检0.3%、过检3%”的平衡点系统才算真正跑起来。这件事给我的教训很深缺陷检测项目的验收标准必须在技术实施前跟客户谈清楚而且要让他们理解漏检和过检是一对矛盾不是算法不行而是物理上就不存在“零漏检零过检”的完美系统除非后端再加一道人工复检这就是代价。6.3 光源不一致白天黑夜判若两人还有一次系统上午运行正常下午误检率飙升。排查了一整天最后发现是车间西侧的窗户下午阳光直射到设备上局部光线变了图像整体灰度偏移原本调好的阈值全部失真。从那以后我对所有缺陷检测项目的成像一致性都极其敏感加遮光罩是必须的光源要选带恒流控制器的相机触发用硬件信号而不是软件延时尽量避免环境光的干扰。成像如果每天都不一样算法的参数再准也没有意义。6.4 “一个模型解决所有缺陷”这个诱惑要忍住早期我也追求用一个万能模型把所有缺陷一网打尽后来发现不同类型缺陷的形态差异太大混在一起训练模型容易顾此失彼训练集越加越乱。现在我的习惯是按缺陷类型拆分模型或者至少分多条检测流程。比如一个项目里划痕用分割模型做脏污用目标检测做两类缺陷分开训练、分开调阈值部署时串并行执行这样每一路都简单、稳定、可维护。缺陷检测做到最后我的体会是它更像一个“光学工程数据工程算法工程”三合一的项目算法只是最后一公里。很多项目失败并不是算法不够先进而是连缺陷定义都没跟客户对齐、打光方案没做透、样本覆盖不全面。如果你正准备启动一个缺陷检测项目我的建议是先花两周时间跟产线操作工聊清楚他们每天实际看到的问题用手机在不同角度打光拍一拍缺陷样件把“怎么照出来”这个问题先解决再考虑相机型号和算法框架。这几步看起来不起眼但能帮你避开我当年走过的绝大多数弯路。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →