机器视觉焊点检测:Otsu阈值分割与分水岭算法实战解析
简介焊点质量直接影响电子产品可靠性与寿命传统人工检测效率低难以满足现代制造业对速度和精度的要求。这份PDF论文《基于计算机视觉的焊点缺陷检测系统的设计》面向机器视觉、图像处理及工业质检方向的研究生与工程师系统阐述利用图像处理技术自动识别虚焊、漏焊、焊穿等缺陷的方法。全文从图像预处理入手依次介绍平滑去噪、Otsu阈值分割、倒三角距离变换与分水岭算法的组合流程并给出基于焊点面积、形状等特征的分类方案同时说明机器视觉系统融合光学、传感器与图像处理软件可实现非接触在线检测实验证明该方法能高效识别多种排列焊点。压缩包共1个PDF文件大小约308KB便于离线阅读与打印内含中英文摘要、关键词、算法步骤及实验数据尤其适合作为课程设计、毕业设计或课题预研的参考文献。目前已有207人学习下载是掌握机器视觉在工业质检中落地应用的实用资料。1. 从人工目检到像素级判别焊点检测为什么要换一条技术路线在点焊机生产线上焊点质量检测长期依赖人工目检。工人拿着放大镜在强光下逐个判断焊点是否虚焊、漏焊或焊穿。这种方式的瓶颈很明显连续工作半小时后注意力下降误判率就会上升而且人工记录只能给出“好/坏”的结论无法量化焊点面积、灰度分布这类过程数据。我拆过不少类似的视觉项目深有体会——检测环节的自动化程度往往决定了整条产线的良率上限焊接本身再快质检跟不上一样得停线。这篇论文提供了一套完整的机器视觉检测方案先把焊点图像做平滑去噪再用 Otsu 方法自动确定阈值做二值化接着用倒三角距离变换把二值图像转成灰度信息最后通过分水岭算法把粘连在一起的焊点逐个切开并利用面积、内部灰度变化等特征区分正常焊点、虚焊和焊穿。整套流程覆盖了从成像、分割到分类的完整链路。对正在做计算机视觉大作业、或者刚接触机器视觉入门、需要设计一套电子系统检测方案的读者来说这篇论文的算法选型和参数推导逻辑都很值得参考。2. 系统架构与成像选型0.1 mm 检测精度是怎么凑出来的2.1 硬件构成与选型逻辑论文中的检测对象是一块 100 mm × 40 mm 的不锈钢薄板点焊机焊接后表面会留下排列不规则的圆形焊点。系统的硬件层由工业数字摄像机、光学镜头、光源三部分组成辅以控制单元和上位机软件。这里最关键的一个指标是 0.1 mm 的检测精度要求。论文选用的是 500 万像素工业面阵 CCD通过 1394 接口FireWire与上位机通信。为什么选 500 万像素你可以用视场除以分辨率来估算单像素对应的物理尺寸。假设视场覆盖整个 100 mm × 40 mm 的工件500 万像素面阵 CCD 的典型分辨率是 2448 × 2048 左右那么在 X 方向上单像素约为 100 mm / 2448 ≈ 0.04 mm论文里给出的数值与此吻合。也就是说0.1 mm 的检测精度对应约 2.5 个像素在视觉检测里属于合理的裕量范围。光源用的是 LED 颗粒的同轴白色光源采用正面打光方式。这个选择很关键。同轴光的特点是光线经过半反半透镜后垂直照射到被测物体表面反射光再沿原路返回进入镜头。对于不锈钢这类高反光材质同轴光能有效避免环境光的漫反射干扰让背景灰度尽量均匀。在实际项目中我一般会在光源控制器上加一个 PWM 调光模块因为 LED 在低电流下会有色温和亮度的漂移恒定电流驱动比脉冲调光更稳定。2.2 上位机软件流程与模块划分上位机软件是整个检测系统的神经中枢。从论文给出的流程图来看采集到原始图像后依次经过平滑处理、Otsu 阈值分割、倒三角距离变换、分水岭算法、圆拟合最后做缺陷判别并输出信号给控制工作台。这个流水线设计有一个好处每个模块都是独立的图像处理操作便于单独调参和替换算法。比如平滑核的大小、Otsu 的直方图区间、距离变换的模板尺寸都可以作为参数暴露在配置文件中而不是硬编码在程序里。一个容易忽略的细节是光机结构的固定方式。论文提到不锈钢表面容易受环境光变化和位置偏移影响因此相机、镜头和光源必须由支架固定在产品上方并与产品水平面保持平行。这个在实验室里很容易被忽视——手持相机拍一张和固定机位拍一张后续分割算法跑出来的结果差异非常大。光照角度变化几度焊点边缘的灰度梯度就会改变Otsu 自动计算的阈值也会跟着偏移最终导致分割结果不稳定。3. 从像素到焊点平滑、Otsu 与倒三角距离变换的完整链路3.1 图像平滑为什么卷积核必须是奇数图像在采集和传输过程中不可避免会引入噪声点同时焊点背景区域可能存在细微的焊渣颗粒。论文使用卷积核与图像做卷积来实现平滑。设原始图像为 f(x, y)卷积核为 G(s, t)核大小为 m × n则处理后的图像 g(x, y) 为g(x, y) ΣΣ G(s, t) · f(x s, y t)其中 s 和 t 的取值围绕核中心对称m 和 n 为奇数。这是因为卷积核需要一个明确的中心锚点。如果核尺寸是偶数锚点会落在两个像素之间的位置导致输出的卷积结果在空间上偏移半个像素。对后续需要精确计算焊点中心和半径的圆拟合来说这种亚像素偏移会影响最终判定结果。在实际工程中我一般用高斯核作为平滑核。普通均值卷积在去除噪声的同时会让边缘变得模糊而高斯核的中心权重更大能在去噪和保留边缘之间取得更好的平衡。OpenCV 里的实现非常直接import cv2 import numpy as np src cv2.imread(solder_joint.bmp, cv2.IMREAD_GRAYSCALE) # 高斯平滑核大小选用 5x5标准差设为 1.5 blurred cv2.GaussianBlur(src, (5, 5), 1.5) # 对比均值模糊 box_blurred cv2.blur(src, (5, 5))高斯核的两个关键参数是核尺寸和标准差 sigma。核尺寸决定了参与卷积的邻域范围sigma 控制了权重在空间上的衰减速度。sigma 太小则平滑效果有限噪声仍然存在sigma 太大则会把焊点边缘的灰度梯度磨平后续 Otsu 分割时边缘会变得模糊。从工程角度来说sigma 一般取核尺寸的 1/6 左右这样高斯核在边缘处接近自然衰减到零不会出现截断突变。3.2 Otsu 阈值分割自适应的最大类间方差逻辑平滑处理之后是阈值分割。论文采用 Otsu 方法即最大类间方差法。它的核心思想是给定一个灰度阈值 T把图像像素分为前景和背景两类计算两类的类间方差。当类间方差最大时说明前景和背景的区分度最高此时 T 即为最佳分割阈值。Otsu 的好处是不需要人工干预算法会遍历所有可能的灰度级自动找到最优阈值。在焊点检测场景下为什么不能用一个固定阈值因为产线上的光照环境不可能完全恒定LED 光源老化、产品表面氧化程度不同都会导致焊点的绝对灰度值发生漂移。固定阈值需要人工不断调整效率太低。论文在综述部分也提到文献 [3] 的模式匹配方法检测速度快但阈值参数依赖人工设定这恰恰是 Otsu 要解决的核心痛点。OpenCV 里调用 Otsu 只需要在 threshold 函数里加上 THRESH_OTSU 标志返回值里的 ret 就是算法自动找出的最优阈值# 大津法二值化自动计算阈值 ret, binary cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) print(fOtsu 自动阈值: {ret:.1f}) # 如果焊点是亮目标但背景偏亮可以取反 # binary_inv cv2.bitwise_not(binary)这里有个实际工程中很容易踩的坑Otsu 假设图像灰度直方图是双峰分布。如果光照不均导致背景灰度范围过大直方图可能出现多峰Otsu 计算的阈值就会偏向面积更大的那一类。常见的解决方案是先对图像做归一化或同态滤波把光照不均的影响压下去再去跑 Otsu。另一个方案是在中值滤波之后再进 Otsu中值滤波在去除椒盐噪声方面比高斯滤波更有效。3.3 倒三角距离变换把像素关系变成灰度信息二值化之后焊点区域已经是白色前景、黑色背景的纯像素集合。但对于相互粘连的焊点直接做连通域分析没法把它们分开。距离变换是解决这个问题的第一步。它的数学定义是对每个前景像素计算它到最近背景像素的距离把这个距离值作为该像素的新灰度值。距离越长的像素灰度值越高。论文特别强调使用倒三角算法来计算距离变换原因是标准的全局距离变换需要每个前景像素都去扫描全图中的背景像素计算量随图像尺寸呈指数级增长在 500 万像素的大图上是不可接受的。倒三角法类似于卷积操作用 3 × 3 的模板做两次扫描第一遍从左到右、自顶向下第二遍从右到左、自底向上。每次扫描时模板中心像素的值更新为模板覆盖区域内所有像素值与模板系数之和的最小值。这个算法的本质是动态规划通过两次单向传播来近似全局距离计算复杂度从 O(N²) 降到了 O(N)其中 N 是图像像素数量。论文在 2.2 节明确指出“全局操作的计算量是非常大的”这也是选型倒三角算法的直接动机。OpenCV 内建了距离变换函数支持多种距离度量和掩码类型# 距离变换使用欧氏距离度量3x3 掩码 dist cv2.distanceTransform(binary, cv2.DIST_L2, 3) # 归一化到 0~255 方便可视化 dist_norm cv2.normalize(dist, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)DIST_L2 对应欧氏距离DIST_L1 对应曼哈顿距离DIST_C 对应切比雪夫距离。在焊点这类近似圆形的目标上欧氏距离最合适因为它计算的是真实的几何距离能最准确地反映从焊点中心到边缘的像素距离。距离变换之后焊点中心区域灰度值高离背景远边缘区域灰度值低离背景近每个粘连的焊点内部会形成一个局部的灰度峰值。这个峰值就是后续分水岭分割的种子起点。3.4 分水岭算法处理粘连焊点的关键步骤距离变换之后的图像每个焊点中心像一个山丘的顶点相连焊点之间的凹陷区域则形成山谷。分水岭算法模拟水从局部最低点开始上涨的过程水面上涨到山脊时山脊线就构成了分割边界。论文中提到先对灰度图像做梯度变换梯度图像中边缘提取趋近于零二值化后分成大于阈值和小于阈值的两部分分别对应“陆地”和“水域”两者的分界就是分水岭。在 OpenCV 中实现分水岭的标准流程是先找到每个焊点的中心标记marker再传入梯度图像让分水岭算法自动扩展标记区域# 分水岭标准流程 dist_thresh cv2.threshold(dist_norm, 0.2 * np.max(dist_norm), 255, cv2.THRESH_BINARY)[1] dist_thresh np.uint8(dist_thresh) # 形态学操作去除噪声和填洞 kernel np.ones((3, 3), np.uint8) opened cv2.morphologyEx(dist_thresh, cv2.MORPH_OPEN, kernel, iterations2) # 找到确定的背景区域 sure_bg cv2.dilate(opened, kernel, iterations3) # 标记连通域 num_labels, labels cv2.connectedComponents(opened) # 给标记加 1使背景为 0 labels labels 1 # 未知区域置 0 unknown cv2.subtract(sure_bg, opened) labels[unknown 255] 0 # 执行分水岭 markers cv2.watershed(cv2.cvtColor(blurred, cv2.COLOR_GRAY2BGR), labels)分水岭算法对噪声敏感过分割oversegmentation是最大的坑。论文的处理顺序值得一提先做距离变换再进分水岭而不是直接在梯度图上跑分水岭。距离变换本身就带有一点“滤波”的性质能把焊点内部的灰度波动抹平让每个焊点形成一个干净的单峰区域大幅降低过分割的概率。如果分割结果还是碎了可以检查一下 opened 的形态学开操作次数或者调低 0.2 这个距离阈值系数——阈值越低被标记为前景的区域越少分割粒度越粗。4. 缺陷分类的几何基础圆拟合、面积计算与灰度判别4.1 最小二乘圆拟合从离散点到标准圆分割完成后每个焊点区域是一组像素点集合。论文采用最小二乘法拟合圆用标准圆来近似表示样本点集的坐标关系。距离公式定义如下di² (xi - A)² (yi - B)²拟合的目标是找到圆心坐标 (A, B) 和半径 R使得所有样本点到圆心的距离与半径之差的平方和最小。论文给出的代价函数展开为Q(a, b, c) Σ(xi² yi² a·xi b·yi c)²把问题化为线性最小二乘其中 a -2Ab -2Bc A² B² - R²所以求解 a、b、c 之后即可反向推出圆心和半径。直接求解这个线性方程组耗时远小于传统的非线性迭代优化方法。在 OpenCV 里直接用 minEnclosingCircle 可以求最小外接圆但对有缺陷的焊点最小外接圆的半径容易被边缘噪声拉大更适合的做法是先用 findContours 拿到轮廓点集再对轮廓点做代数圆拟合# 在分水岭分割后的图上提取每个焊点轮廓 contours, hierarchy cv2.findContours( np.uint8(markers region_id), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) for cnt in contours: area cv2.contourArea(cnt) if area 50: # 过滤过小噪声区域 continue # 方式一最小外接圆 (x, y), r_min cv2.minEnclosingCircle(cnt) # 方式二轮廓矩求质心再基于质心作代数圆拟合 M cv2.moments(cnt) if M[m00] 0: continue cx int(M[m10] / M[m00]) cy int(M[m01] / M[m00]) # 拟合圆半径可用等效半径sqrt(面积 / pi) r_equiv np.sqrt(area / np.pi)从算法鲁棒性角度我用 minEnclosingCircle 时会注意焊点边缘是否平滑。如果焊点边缘有少量毛刺最小外接圆半径会比实际偏大此时用面积反推等效半径更可靠。等效半径的定义是 r_equiv sqrt(area / π)在焊点形状接近规则圆时这个值与最小外接圆的差别很小。从最小二乘拟合圆到缺陷分类存在一个容易忽视的问题拟合结果对轮廓点集的纯度高度敏感。分割时如果把焊渣、背景中的亮点也划进了焊点前景面积会偏大圆拟合的圆心也会偏移。所以在工程实现中我会在拟合前先对轮廓做多边形逼近把轮廓点数量降到可控范围并结合每个点与初始圆心的距离做离群点剔除。4.2 面积与灰度特征虚焊和焊穿怎么区分论文检测的缺陷主要针对虚焊和焊穿两类。通过比较发现虚焊产生的焊点面积比正常焊点小焊穿产生的焊点内部灰度均匀没有明显的亮色区域。因此第一个判别维度是面积。按照论文的思路焊点拟合圆之后求出面积直接和正常焊点的面积基准做对比。正常焊点的基准值需要在实际产线上采样统计——采集几百个由合格焊件得到的拟合圆面积计算均值和标准差作为判别阈值的依据。第二个判别维度是焊点内部灰度值的变化。焊穿的特征是内部灰度均匀这与正常焊点的外观有明显不同。正常焊点由于焊接时金属熔融后再凝固表面常形成不规则的亮斑灰度方差较大而焊穿区域因为材料被高温熔穿表面失去原有的纹理特征灰度分布趋于平坦。用方差来量化这个差异# 用掩膜统计焊点区域内部的灰度分布 mask np.zeros_like(gray) cv2.drawContours(mask, [cnt], -1, 255, thicknesscv2.FILLED) # 提取焊点区域的灰度值 pixels gray[mask 255] # 计算灰度均值和标准差 mean_gray np.mean(pixels) std_gray np.std(pixels) # 判别规则 if area area_normal_mean - 2 * area_normal_std: label 虚焊 elif std_gray std_gray_normal_threshold: label 焊穿 else: label 正常这里有三个参数需要标定面积下限阈值、面积上限阈值、灰度标准差阈值。灰度标准差阈值本质上刻画的是“内部灰度均匀”的程度——该值设得越小判定为焊穿的条件越严格。设得太大则会误把正常焊点的反光区域也判成焊穿。论文原文描述的是“内部灰度均匀无明显亮色区域”这句话对应到代码上就是像素灰度值的高斯分布方差比较小。在这个步骤里一个常见的错误是直接在原始灰度图上统计方差而不是基于分割后的掩膜来统计。如果掩膜不准把背景或相邻焊点也划进来了灰度方差的可靠性就会大打折扣。所以面积判别的第一个闸门很重要它先把面积离群区域筛掉再针对面积正常的焊点做灰度分析通过级联的方式降低误判率。5. 产线落地的边界条件与实践技巧5.1 系统标定与基准阈值确定论文在系统功能测试一节提到配备视觉系统前后各生产 200 块产品进行对比结果表明视觉检测能有效识别有缺陷的焊点。但这里有一个隐含的前提判别阈值是从哪一份样本集里学出来的在实际落地时我会建议分两步走。第一步是采集 100200 个由工艺工程师确认过的合格焊点样本统计面积和灰度方差的均值和标准差第二步是采集虚焊、焊穿样本各 50 个左右验证阈值分界是否清晰。如果虚焊样本的面积分布和正常焊点有重叠单纯靠面积做单维判别是不够的需要增加圆度特征4π·area / perimeter²作为补充维度。阈值系数也有讲究。论文没有给出具体的系数值但按常见的做法推荐用均值加减 2~3 倍标准差。2 倍标准差意味着假设正态分布下约 95% 的正常样本落在区间内那约 5% 的正常焊点会被误判为缺陷3 倍标准差则更保守但可能放过一部分虚焊焊点。到底是偏严还是偏松取决于后段工序还能不能做人工复检。如果后段能复检可以偏严宁可把疑似缺陷挑出来如果后端直接出货就要偏松避免误杀合格品。5.2 光照漂移与分水岭过分割的工程处理LED 同轴光源在连续工作若干小时后会出现光衰光谱特性也会发生变化导致采集到的焊点图像整体变暗。这时 Otsu 自动计算的阈值会随之调整但分水岭算法对距离阈值系数的敏感度较高可能需要定期校正。一个工程处理方案是监控 Otsu 返回的阈值如果连续 N 个工件的结果都偏移超过预先记录的基准阈值的某个百分比比如 15%给出报警提示让人去检查光源状态。分水岭过分割的另一个容易被忽视的来源是焊点边缘的反光。正面打光下不锈钢焊点的边缘可能出现一圈高亮的月牙形区域这个区域在距离变换后会形成一个独立的局部峰值导致分水岭算法把同一个焊点切成了两半。解决这个问题的通用做法是分水岭分割后过滤面积过小的碎片并把碎片归属到相邻最大的分割区域。这个后处理逻辑用 Python 实现很容易统计每个标记区域的面积后将面积小于阈值的区域合并到与之相邻的最近区域。5.3 论文之外的现实接口问题论文中用的是 1394 接口FireWire相机。这个接口在当年的工业相机场合很常见但放到今天新产线上的视觉项目更多采用 USB3.0 或 GigE Vision 接口。USB3.0 的理论带宽是 5 Gbps传输 500 万像素灰度图约 5 MB/帧可以做到 60 fps 以上GigE 则更利于多相机组网和中长距离传输。从传输协议上看论文中的图像处理链路并不依赖 1394 接口的特殊性换成 USB3.0 的工业相机只需要把图像采集的 API 层替换掉后续的 OpenCV 处理链路完全不需要改动。这一点在做复现实验时值得注意——直接拿论文的流程用现代相机重跑一遍整体逻辑依然成立。如果你需要验证这套算法的效果我建议先用手机或普通工业相机拍几张正对焊点的图像按论文流程跑一遍观察二值化的结果是否把焊点完整地提出来以及两个相邻焊点之间的距离变换灰度剖面是否有明显的山峰结构。如果焊点太密山峰之间的山谷不明显分水岭很难切干净就要考虑提高相机的物距或者在光源上做文章来加大焊点边缘的对比度。这些细节论文不一定写到但它们是把这个系统从论文带进产线的必经之路。另外距离变换的模板尺寸可以从 3 × 3 扩到 5 × 5。更大的模板意味着距离传播速度更快但精度会有所下降。在焊点直径只有几个像素的小目标场景3 × 3 模板的精度才够用在焊点直径几十像素以上的常规场景5 × 5 模板的计算效率优势更明显。具体选哪个可以统计所有焊点前景像素的最小直径后做个简单的除法来判断。本文还有配套的精品资源点击获取