尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

工业缺陷检测算法与库选型:从传统视觉到深度学习实战

工业缺陷检测算法与库选型:从传统视觉到深度学习实战 做工业缺陷检测这一行绕不开一个挺尴尬的现实项目谈下来的时候客户讲的都是要检测出0.05mm的划痕要区分三种脏污等级等真正坐到工位上开始写代码才发现纠结的从来不是用哪个模型而是这个缺陷在图像里到底长什么样、我该用机器视觉里的哪套常用算法、配哪个库能最快跑通。这个系列写到第四篇我想专门聊聊算法与库这件事——不是罗列名词而是把选型的逻辑摊开讲什么缺陷对应什么算法族哪些库吃传统视觉这碗饭、哪些库是深度学习的主场以及到了产线上它们各自会在哪里掉链子。如果你正在做方案评估、或者在项目里被误报率折磨过这篇应该能对上你的痛点。1. 从能测出来到测得稳算法分水岭到底在哪很多人评估算法时盯的是能不能检出但产线验收时卡的是稳不稳。这两件事在技术上是完全不同的难度层级中间的落差就是选型失败的主要来源。1.1 缺陷的四个维度决定算法天花板任何一个缺陷本质上都可以用四个维度描述清楚对比度缺陷和背景的灰度/颜色差、尺寸像素占几个、形态随机性形状是否可枚举、位置随机性在视野里会不会乱跑。这四个维度直接决定了算法的天花板。对比度高、形状固定、位置固定——比如背光下的冲压件缺料孔这种用二值化加连通域分析就够了上百帧每秒毫无压力。对比度低、形状随机、位置随机——比如金属拉丝表面的浅划痕灰度差可能只有5到8个灰阶这种传统算法就非常吃力通常要上深度学习或者特殊打光配合频域滤波。我在实际项目里总结过一个粗略的判断如果缺陷的对比度低于10个灰阶且形态无法用长条形/圆形/点状这类几何参数描述就要优先考虑学习类方法别硬啃传统算子。反过来如果缺陷对比度明显、可以用面积、圆度、长宽比这类参数卡住传统算法在稳定性和速度上几乎是无敌的而且它的判定逻辑能写成文档交给客户这在验收环节是巨大的优势。1.2 光学、算法、判定标准三者是耦合的新手最容易犯的错是把算法当成独立的模块。实际上在工业缺陷检测里光学方案、算法选择和判定标准是三条腿的凳子缺一条就翻。举个具体的例子检测金属表面的凹坑。如果你用同轴光凹坑边缘会产生明暗分明的轮廓这时候用边缘检测加形态学就能做如果你用条栅光凹坑会因为反射角变化产生亮度梯度这时候更适合用局部对比度增强加Blob如果你用多角度频闪合成凹坑在四张图里的亮度分布不同可以用图间差分加逻辑判断。同一类缺陷打光变了算法就完全不一样。反过来说算法选错了有时候靠打光还能救回来——这是行业里很常见的一种补救方式。所以在讨论用哪个库、哪个算法之前先确认光学方案是否已经能把缺陷的对比度拉到可用范围否则再好的库也是白搭。1.3 传统与深度学习的分界不是新旧是样本量外面很多说法把传统算法说成过时技术这是典型的门外话。真实的分界线是样本量能收集到几百张以上带标注的缺陷样本且缺陷形态有多样性深度学习方法就值得上样本只有几十张、甚至只有良品样本那就老老实实用传统方法或者无监督异常检测。另一个分界线是可解释性要求。汽车零部件、医疗耗材这类行业客户往往要求算法能说明为什么判这个位置是缺陷——传统算法可以直接输出连通域面积、灰度均值、边缘强度这些数值非常容易解释。深度学习给出的是一个置信度分数说服成本高得多。我参与过的一个项目最后交付方案是深度模型先粗筛、传统算子做二次确认和量化输出就是折中出来的结果。2. 传统算法库的实战定位谁吃什么饭传统视觉这条线上的库已经非常成熟问题从来不是有没有而是选哪个。下面按缺陷类型倒推算法再倒推库。2.1 Blob 分析与形态学脏污、异物、孔洞的主力Blob分析连通域分析是传统视觉里使用频率最高的方法没有之一。它的流程很固定预处理去噪、阈值分割、连通域标记、特征筛选面积、圆度、凸度、重心、包围盒长宽比、输出判定。关键在阈值分割这一步。全局阈值Otsu适合背景均匀的场景比如背光下的透明件自适应阈值局部均值或高斯加权适合背景有渐变的场景比如弧面上的反光件。我个人的习惯是先用Otsu跑一遍看效果如果缺陷在图像各处都能稳定分出来就用全局的因为速度快且参数少如果边缘区域开始漏检再切到自适应阈值窗口大小一般取缺陷典型尺寸的3到5倍。形态学的作用有两个一是把断裂的缺陷连起来闭运算二是把细小的噪声点消掉开运算。这里有个经验值结构元的尺寸不要超过待检缺陷最小尺寸的三分之一否则小缺陷会被直接抹掉。OpenCV里对应的是cv2.threshold、cv2.adaptiveThreshold、cv2.connectedComponentsWithStats、cv2.morphologyEx。Halcon里是threshold、connection、select_shape、opening_circle。scikit-image里是filters.threshold_otsu、measure.label、measure.regionprops。这三套我都在项目里用过后面有对比表。2.2 模板匹配与卡尺定位和尺寸测量的地基缺陷检测之前几乎都要先做定位。原因很简单ROI感兴趣区域必须跟着产品走产品在视野里偏了2mm固定ROI就会漏掉边缘的缺陷。定位首选基于形状的模板匹配Shape-Based Matching它比灰度归一化互相关NCC抗光照变化能力强得多。Halcon的create_shape_model加上find_shape_model是一套经典组合支持旋转和缩放搜索用金字塔加速后2048×2048的图像里找目标通常只要几毫秒到十几毫秒。OpenCV对应的是cv2.matchTemplate但它的NCC对光照和形变比较敏感如果一定要用灰度匹配建议先做局部对比度归一化。提示模板匹配的搜索范围不要开太大。旋转范围给±15度、缩放给±5%通常就够了。范围开大一倍误匹配率会明显上升速度也会掉。卡尺工具Caliper用来做亚像素级的边缘定位典型应用是测宽度、测间距、测边缘直线度。原理是在一条搜索线上做一维灰度投影找梯度极值点然后通过抛物线拟合或高斯拟合把精度提到0.1像素级别。Halcon的measure_pos和gen_measure_rectangle2以及Cognex VisionPro的Caliper工具都是这类。很多尺寸类缺陷比如装配缝隙超差、宽度公差其实就是靠卡尺加直线拟合完成的并不需要复杂的图像处理。2.3 频域、滤波与参考图差分把划痕从纹理里捞出来划痕检测是传统视觉的经典难题因为背景本身就有纹理拉丝、喷砂、织纹缺陷和背景在灰度上没有明显区别。这类场景常用的三招第一招是频域带通滤波。把图像做FFT缺陷通常处在中高频段背景纹理处在更高频或者更低频用一个环形带通掩膜滤掉背景纹理反变换回来再做阈值。OpenCV里用cv2.dftHalcon里是fft_image加gen_bandpass。这招对周期性纹理特别有效比如金属网、编织布。第二招是局部对比度增强。计算每个像素邻域内的标准差或者最大最小值差缺陷位置的局部对比度会明显偏高。等效实现是原图减去大尺度高斯模糊的结果也就是所谓的高通滤波或同态滤波思路。第三招是参考图差分。如果有良品的Golden模板把待检图和模板做配准相位相关或者ECC配准然后逐像素相减取绝对值后阈值化。这招威力很大但前提是配准精度要够——配准误差必须控制在0.2像素以内否则边缘处会产生假的差分信号。我吃过一次亏机械定位精度不够产品每次旋转角度都有0.3度波动差分图在轮廓处全是伪缺陷最后是靠提高采集时的机械定位重复精度加上亚像素配准才解决的。2.4 主流传统视觉库的横评选库这件事没有绝对答案主要看团队基础、授权预算和交付形式。库/平台开发语言优势短板适用场景OpenCVC / Python免费、生态大、跨平台高级工具少标定和匹配要自己封装自研平台、成本敏感项目HalconHDevelop / C / .NET算子质量高形状匹配和卡尺是标杆授权费用高HDevelop语法需要适应中高端产线交付周期紧VisionPro.NET图形化配置强和产线集成成熟授权贵深度学习模块另外收费3C、电子装配类产线NI VisionLabVIEW / C#和NI硬件生态打通复杂算法灵活性一般测试测量结合的场景scikit-imagePython算法透明、易改速度慢不适合高速产线原型验证、算法预研MATLAB Image ProcessingMATLAB矩阵运算快仿真方便部署授权成本高算法建模和论文验证我自己的习惯是算法预研阶段用Python加OpenCV和scikit-image快速验证思路确认可行之后再决定是移植到Halcon还是用C重写。这个流程能省下大量时间因为预研阶段改一行代码就能看效果而Halcon改一个算子参数要重新导出程序。3. 深度学习这条线的算法地图深度学习在工业缺陷检测里的地位这几年涨得很快但它不是万能的。我把常用的方法按任务类型拆成四类每类的适用边界差别很大。3.1 分类网络适合整个ROI判好坏的场景分类是最简单的形式给定一个裁好的ROI输出它属于良品还是某一类缺陷。常用的骨干网络有ResNet系列、EfficientNet、MobileNet、ConvNeXt。分类适合什么场景缺陷位置固定、ROI容易裁取、只需要知道有没有而不需要知道在哪。比如字符印刷质量的判定、注塑件整体外观的分级。它的优点是训练数据标注成本低一张图一个标签推理速度快224×224输入的ResNet18在GPU上单张推理只要几毫秒。短板也很明显它无法定位缺陷位置而且如果一张图里同时存在多个缺陷分类结果会被最严重的那个主导。我遇到过一个案例客户要求统计每片上缺陷的数量和位置这种需求分类网络就完全做不了必须上检测或者分割。另一个坑是类别不平衡。产线上良品占99%以上缺陷样本本来就少换算到ROI级别可能差三四个数量级。这时候的常规做法是加Focal Loss、做过采样、或者直接把问题转成异常检测见3.3节。3.2 检测与分割需要知道在哪就必须上目标检测YOLO系列、Faster R-CNN、DETR输出的是缺陷的边界框适合缺陷形状相对紧凑、需要计数和定位的场景。近年YOLOv8、YOLOv11这类单阶段检测器在工业场景里用得最多因为速度快、精度也够。但边界框有个天然缺陷划痕、裂纹这类细长缺陷用矩形框标注会包进大量背景框的面积远大于缺陷面积评价指标IoU会被稀释训练效率下降。这类缺陷更适合语义分割U-Net、DeepLabV3、SegFormer或者实例分割Mask R-CNN。分割输出的是像素级掩膜能精确给出缺陷的面积和形状非常适合后续做等级判定。任务类型代表模型输出适合的缺陷训练数据成本分类ResNet、EfficientNet类别标签整体外观判定低目标检测YOLO系列、Faster R-CNN边界框点状、块状、可计数缺陷中语义分割U-Net、DeepLabV3、SegFormer像素掩膜划痕、裂纹、细小缺陷高实例分割Mask R-CNN、YOLOv8-seg掩膜加实例多缺陷计数加计量高分割的代价是标注成本。像素级标注一张2048×2048的图熟练的标注员也要十几分钟。如果项目里缺陷样本本来就不多这个成本是绕不过去的坎。我一般会建议客户先从分类或检测起步等产线稳定运行、样本积累起来之后再升级到分割。3.3 无监督异常检测小样本场景的现实解这是这几年工业视觉里最实用的方向也是很多样本只有几十张项目的救命稻草。核心思路是只用良品样本训练一个模型让它学会正常长什么样推理时凡是偏离正常分布的区域就判为异常。代表性方法有PatchCore用预训练骨干提取局部特征建立正常样本的特征记忆库推理时做最近邻检索用距离作为异常分数。它不需要训练只用良品样本建库推理速度取决于记忆库大小通常通过贪心降采样把记忆库压到原来的1%到10%。PaDiM对每个位置建模多元高斯分布用马氏距离衡量异常。FastFlow用归一化流做特征分布的密度估计训练快、推理快。EfficientAD主打低延迟适合高节拍产线。这些方法有个共同的优势不需要缺陷样本。产线刚上线、缺陷样本还没积累的时候这是唯一能跑起来的深度方案。而且正常样本的采集几乎零成本从产线随手抓几百张良品图就行。它们的边界也很清楚只能告诉你这里不正常不能告诉你这是哪类缺陷对反光变化、光照漂移比较敏感如果训练时的良品图没有覆盖实际生产的全部光照变化推理时会大面积误报。我的做法是把正常样本按班次、按批次、按不同时间段都采一遍尽量覆盖光照和环境的自然波动。注意无监督异常检测的阈値不是靠交叉验证调出来的而是要在产线上用真实数据慢慢收敛。上线初期宁可把阈值调松宁可漏不要错杀等误报率稳定后再逐步收紧。3.4 训练框架与部署库的分工算法是一回事能不能在产线上跑起来是另一回事。整个链路上会用到不同层次的库各司其职。训练侧PyTorch是绝对主流配合torchvision、timm预训练骨干、albumentations数据增强。检测任务常用MMDetection、YOLO官方仓库、PaddleDetection。异常检测可以直接用Anomalib它把PatchCore、PaDiM、FastFlow这些都封装好了几行配置就能跑通。部署侧训练出来的模型通常先导出成ONNX再用TensorRTNVIDIA平台或OpenVINOIntel平台做图优化和量化推理速度普遍能提升2到5倍。边缘设备上常用Jetson系列配合TensorRT纯CPU场景用OpenVINO的FP16或者INT8量化速度提升更明显。如果设备性能很弱还可以考虑NCNN这类轻量推理库。这里有个真实的数据参考一个输入640×640的YOLOv8s模型在服务器级GPU上FP32推理大约10到15毫秒转成TensorRT FP16之后降到5到8毫秒同一模型在普通桌面CPU上跑可能要100毫秒以上。如果你的产线节拍要求单件200毫秒以内这个差距足以决定方案能不能落地。4. 3D与点云库高度、共面度、段差类缺陷的专用兵器不是所有缺陷都能在二维图像里看出来。高度差、凹陷深度、平面度、装配段差这些二维图像只能通过阴影间接推测精度和稳定性都不可靠。4.1 什么时候必须从2D切到3D判断标准很简单如果缺陷的本质是Z方向的几何变化那就必须上3D。典型场景包括焊点高度、胶路宽度和高度、零件装配后的段差、表面凹坑深度、平面度。二维方案在这些场景下不是不能做而是只能做定性判断无法给出量化数值。一旦客户要求段差超过0.15mm就报警二维方案就必须换成3D。4.2 点云库的选型逻辑3D方案里硬件通常用结构光、激光轮廓仪或者线激光扫描。软件侧则涉及点云处理。PCLPoint Cloud Library开源点云处理的标配滤波、配准、分割、曲面重建都有。适合自研平台Python侧可以用python-pcl或者open3d替代open3d在易用性上更好。Halcon 3D把2D和3D算子整合在同一套环境里表面配准、3D匹配、高度图分析都有现成算子学习成本相对低。硬件厂商SDK结构光相机通常自带深度图获取和标定SDK做基础的高度测量够用但复杂的点云分析能力有限。实际操作中我更多是把3D数据转成高度图2D灰度图灰度值代表高度然后用成熟的2D算法处理。这样能直接复用已有的Blob、滤波、差分工具链开发效率高很多。只有在需要做曲面拟合、平面度评估、复杂配准的时候才会真正用到PCL或者open3d里的点云算法。5. 选型不是选最强是选最匹配工具本身没有优劣只有匹配度。这一节我把前面散落的判断逻辑收拢成一张决策表再补两笔必须提前算的账。5.1 缺陷类型到算法的映射缺陷类型推荐算法族推荐库/框架备注脏污、异物、孔洞Blob加形态学OpenCV、Halcon阈值分割质量决定成败尺寸超差、装配缝隙卡尺加直线拟合Halcon、VisionPro必须做亚像素划痕、裂纹有纹理背景频域滤波、局部对比度、参考图差分OpenCV、Halcon优先考虑打光优化字符、印刷质量模板匹配加分类网络OpenCV、PyTorch字符识别可叠加OCR多类缺陷混检目标检测YOLO系列、MMDetection标注成本中等细小缺陷精确计量语义分割U-Net、SegFormer标注成本高缺陷样本极少无监督异常检测Anomalib、PatchCore只用良品样本高度、段差、平面度3D测量加点云处理Halcon 3D、PCL、open3d需高度图转换这张表不能当公式用但可以当起点。实际项目里通常是两三种方法组合比如异常检测先粗筛、传统算子做量化确认。5.2 像素精度这笔账要在选算法之前算很多项目失败在光学选型阶段而不是算法阶段。像素精度这个概念必须提前算清楚。公式很简单像素精度 视野宽度 / 相机横向分辨率。假设视野宽100mm用500万像素相机2448×2048那单像素对应 100 / 2448 ≈ 0.0408mm也就是约41微米。如果你要检10微米的缺陷靠单个像素是绝对测不出来的必须依赖亚像素算法或者提高光学放大倍率。亚像素算法比如卡尺的边缘拟合通常能做到0.1到0.2像素的重复精度换算过来大约4到8微米。听起来够用但这是理想条件下的重复精度实际还要打折镜头畸变、机械振动、打光波动、产品放置角度变化都会吃掉精度。我的经验是把理论亚像素精度乘以2到3倍的余量来评估可行性。提示客户说要检0.05mm的缺陷时一定要追问一句是要求稳定检出还是只要能看到。这两个要求的相机成本可能差三倍以上。5.3 节拍这笔账决定你用什么级别的模型节拍计算经常被忽略但它直接锁死了算法选择范围。算一下产线30件每分钟就是每件2秒。如果单工位单相机图像采集大约20到50毫秒取决于曝光和传输留给算法的时间大约1.5秒。这个预算下传统算法随便用小模型也随便用甚至可以跑分割网络。但如果产线是每分钟300件每件200毫秒采集占掉30毫秒算法预算只剩150毫秒。这个预算下大分辨率的分割模型就很危险必须用轻量检测器加TensorRT加速或者干脆回到传统算法。我一般会在方案阶段就把三笔账一起算像素精度、节拍预算、样本量。三者共同决定算法族而不是先选算法再想办法适配。6. 让算法在产线上活下来几个真实的坑算法在实验室跑通到产线上稳定运行中间还有一段距离。这一段踩过的坑往往比算法本身更值得记下来。6.1 误报率高的时候先怀疑打光和机械再怀疑算法这是我反复验证过的一条经验。产线误报突然增多第一反应是去调算法阈值但很多时候根因在别处光源老化导致亮度下降、镜头或防护玻璃沾了油污、产品定位夹具磨损、车间环境光在某个时间段发生变化。排查顺序建议是先看误报图像的时间分布如果集中在某个时段多半是环境或光源问题如果分散分布再看误报位置如果集中在视野边缘通常是镜头畸变或者打光不均如果位置随机才考虑算法本身。我处理过一次典型问题某产线的划痕检测在下午两点到四点误报激增。查了三天算法参数没结果最后发现是西晒的太阳光透过车间窗户打到了检测工位上那个时间段正好直射。加装遮光罩之后问题消失。算法一行没改。6.2 阈值不是一个数是一组数加一个后处理链新手常常以为阈值调好就完事实际上一个稳定的判定逻辑通常包含多层过滤第一层是像素级阈值灰度、概率、异常分数第二层是形态学过滤最小面积、最小长度、最大宽度第三层是ROI掩膜把不可能出现缺陷的区域排除掉第四层是多帧确认连续N帧同一位置都判缺陷才报警。加上多帧确认这一层误报率往往能下降一个数量级代价是最小检测时间变成N倍的帧周期。如果产线节拍允许这一层性价比极高。6.3 模型上线不是终点是数据回流的起点深度模型上线后准确率会随着时间慢慢漂移原因包括原材料批次变化、供应商更换、设备磨损。所以上线时一定要把数据回流机制设计好把产线判定的每一张图连同结果人工复判后的标签都存下来定期做增量训练或者阈值重校准。我见过的最省事的做法是留一个疑似样本池模型置信度落在0.4到0.6之间的图自动存档人工每天花十分钟复判一批。这批数据用来做增量训练最有价值因为它是模型最不确定的部分。6.4 别忽略库的授权和部署形态这一条是给做方案的朋友的提醒。Halcon按开发授权和运行授权分开收费运行授权按设备数量算如果项目要铺几百台设备成本会非常可观。相比之下OpenCV是BSD协议商用免费但需要自己封装算法模块开发人力成本高。这个权衡在报价阶段必须算清楚不能等到交付前才发现授权成本吃掉了利润。另外如果用到了某些深度学习框架也要确认其模型权和专利条款特别是涉及预训练权重商用的时候。最后分享一个我自己一直在用的判断方法面对一个新缺陷我先用手机或者工业相机拍十张图用最简单的OpenCV脚本跑一遍Otsu阈值加连通域看缺陷能不能被分出来。如果能分出来说明对比度够传统路线是首选如果分不出来再考虑打光能不能改善打光也改不了才上深度学习。这个三步走帮我省下了大量不必要的模型训练时间也避免了很多为了用深度学习而用深度学习的项目。算法选型这件事能用简单方法解决的就别让它复杂化产线要的从来不是最先进的技术而是明天早上八点开机它还能正常工作。
返回列表