ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Matlab的PCB板卡一致性检测:图像配准与差分算法实战

基于Matlab的PCB板卡一致性检测:图像配准与差分算法实战 前阵子我接到一个和电子板卡一致性检测相关的需求工厂里同一批次的PCB板卡在贴片回流焊之后需要抽检有没有元件漏贴、贴偏、焊点桥连这类问题。原来的做法是人工目检配上放大镜效率低而且每个人判定的尺度不一样检完一批还要复核一遍。项目要求用工业视觉的方式做一套自动检测方案并且先在Matlab里把算法链路跑通这样既方便调参又能快速验证检测思路。这个项目做完之后我最深的感受是一致性检测这个东西算法本身并不复杂真正决定成败的反而是前期的检测项定义、光学环境稳定性和配准精度。这篇文章就把整个方案的思路、参数推算、Matlab实现主链路以及我实测中踩过的坑完整梳理一遍。想用工业视觉做PCB外观检测的同行或者正在用Matlab写图像处理实验的同学可以拿去当一条完整的参考路径。1. 一致性检测先要定义清楚检什么检测项、模板与容差1.1 一致性检测和缺陷检测是两码事很多人一上来就想着我要用深度学习识别所有缺陷这是把需求拔高了。一致性检测的核心不是识别缺陷而是比较拿被测板卡和一块标准良品模板做逐区域对比找出不一样的地方。换句话说缺陷检测解决的是这个东西坏没坏一致性检测解决的是这个东西和标准品像不像。这个区别决定了技术路线。一致性检测里模板是已知的、固定的检测目标也是已知的所以传统图像处理手段完全够用不需要标注大量缺陷样本。我在项目里第一阶段就没碰深度学习全部用图像配准加差分加特征量测做下来效果已经能覆盖大部分抽检场景。1.2 电子板卡上值得做一致性检测的项目PCB板卡的一致性检测并不是简单拍一张照片对比一下。常见检测项可以划分为以下几类。检测项风险等级对应检测策略元件缺失高功能失效模板差分比对该区域是否有元件轮廓元件位置偏移高焊接不良区域重心比对计算贴装偏移量元件极性反向高上电烧板局部模板匹配或字符/色环比对焊点桥连高短路连通域分析检查相邻焊盘是否粘连焊锡过量/不足中可靠性隐患区域灰度或面积统计板面划痕/异物中外观不良局部灰度突变检测从这张表能看出不同检测项需要不同的图像特征。有的要靠比比如元件缺失、多余物直接差分就能看出来有的要靠量比如偏移量、桥连长度必须做几何特征提取。后面第4章我会详细讲这两类方法的配合。1.3 一套检测方案成立的前提模板的有效性模板选不好后面全白搭。我见过不少项目卡在检测结果天天误报最后查下来是模板本身有问题。模板采集有几个基本要求必须是确认过的良品板卡最好从当前批次里选不要拿老批次或者不同版本的板子。同一块板卡至少采集5到10张不同摆放位姿的图像用来验证配准算法的稳定性。板面必须清洁不能有指纹、油污否则这些污渍会被当成标准特征学进去。另外注意不要直接用PCB设计软件导出的CAD图当模板。CAD图是矢量图形和相机拍出来的灰度纹理差异很大直接差分会产生大量假阳性。我在项目里踩过这个坑后来老老实实回到实拍良品图。2. 图像采集的参数倒推从检测精度到相机、镜头和光源2.1 从最小检测目标推算像素分辨率工业视觉里第一个问题永远是你要看清多小的东西像素分辨率是倒推出来的。以检测元件偏移为例实际生产中最常见的容忍范围是±0.1mm。检测算法要可靠识别0.1mm级别的偏移至少需要让这个偏移量在图像中占4到5个像素否则亚像素边缘对不准。按5个像素折算像素分辨率 0.1mm / 5pixel 0.02mm/pixel这个值是整个光学方案的设计基准。如果分辨率达不到后面算法再精细也没用。2.2 视野、分辨率与相机选型视野FOV取决于要拍的板卡大小。假设一块典型的控制板是60mm × 60mm那么横向需要的像素数就是横向像素数 60mm / 0.02mm/pixel 3000像素这说明200万像素相机约1600×1200已经不够了至少要500万像素级别2448×2048才能同时覆盖视野和精度。如果板卡尺寸更大比如200mm × 200mm那就要考虑拼接或者提高相机分辨率。我实际使用的是一台500万像素的工业面阵相机配16mm定焦工业镜头工作距离控制在200mm左右光圈收到F8以增加景深。这里有个经验宁可让图像稍微偏暗也别把光圈开大因为PCB板面有元件高度差光圈太大会导致部分区域跑焦。2.3 光源选型不同缺陷吃不同角度光源是工业视觉里被严重低估的部分。PCB表面是复杂的非朗伯面元件、焊点、丝印的反射特性各不相同选择什么角度、什么颜色的光直接影响缺陷的对比度。我在这个项目里的光源配置如下环形光源0°到30°低角度主要用于焊点检测。低角度光能把焊点的三维轮廓照出来球形焊点会形成明显的亮环桥连区域则不会有这个特征。同轴光垂直照射用于检测板面划痕、丝印和字符。同轴光对镜面反射敏感划痕在图像里会表现为暗条纹。条形光大角度掠射用于检测元件是否翘起、浮高。掠射光会在元件边缘投下阴影从阴影方向可以判断高度差异。如果你的Matlab代码里做的是灰度差分但拍出来的图光源不均匀那预处理阶段就要花大量精力去补偿。光源这一项投入产出比极高值得先花时间调好再写算法。2.4 光学平台的几个实际细节板卡定位用一个带定位销的治具固定板卡每次放下去的位置误差控制在±1mm以内。这样可以大幅减轻后期配准压力。环境光隔离给整个检测工位加遮光罩或者把设备放在暗室环境里排除日光灯频闪的影响。相机安装保证相机光轴垂直于板面。我测过哪怕倾斜2度板卡边缘的元件位置就会产生1到2个像素的偏移误检率立刻上升。3. 预处理与配准检测精度的真正分水岭3.1 预处理不只是去噪预处理的目的不是让图好看而是让后续的差分和特征提取对光照、噪声不敏感。我用的预处理链路是灰度化rgb2gray如果后续要检测丝印颜色差异则保留RGB三个通道分别分析。高斯滤波imgaussfilt(I, 1.5)轻度去噪注意核不要太大否则会把细小缺陷抹掉。顶帽变换imtophat(I, strel(disk, 50))这一步很关键。PCB板面不同区域的反射亮度差异很大顶帽变换能去掉大面积背景亮度不均匀保留局部细小特征。顶帽变换的原理可以理解为用一个半径较大的圆盘形结构元素做开运算得到一个背景亮度估计然后用原图减去这个背景。效果是暗区域被提亮亮区域的背景被削平让整个板面亮度趋于均匀。对差分检测来说这能直接减少因为板卡批次间底色差异带来的误报。3.2 配准的精度决定差分的可信度这是整个项目里我体会最深的一件事不做配准就直接差分等于自杀。如果不做几何配准被测板卡和模板板卡哪怕只偏移了3个像素差分结果在元件边缘、焊盘边缘就会出现一圈亮边这些亮边会被误判为缺陷。实际治具定位精度能做到±1mm换算成像素就是50个像素左右根本没法直接比。配准的目标是让被测图像和模板图像在像素级对齐误差控制在亚像素到1个像素之间。达到这个精度差分的可信度才有保障。3.3 粗配准加精配准的落地方法我的做法是两阶段配准。第一阶段粗配准。把两幅图分别二值化得到板卡的整体轮廓然后计算轮廓的质心和主轴方向。通过平移和旋转把被测图大致摆到模板的位置上。这一步能消除治具摆放带来的大位移和大角度偏差。% 粗配准计算连通域质心和方向 bw_t imbinarize(imgaussfilt(template_gray, 2)); bw_s imbinarize(imgaussfilt(sample_gray, 2)); stats_t regionprops(bw_t, Centroid, Orientation); stats_s regionprops(bw_s, Centroid, Orientation); % 位移量 shiftX stats_t(1).Centroid(1) - stats_s(1).Centroid(1); shiftY stats_t(1).Centroid(2) - stats_s(1).Centroid(2); angleDiff stats_t(1).Orientation - stats_s(1).Orientation; % 构建相似变换矩阵 tform affine2d([cosd(angleDiff) -sind(angleDiff) 0; sind(angleDiff) cosd(angleDiff) 0; shiftX shiftY 1]); sample_aligned imwarp(sample_gray, tform, OutputView, imref2d(size(template_gray)));第二阶段精配准。粗配准之后两幅图还有1到2像素的残差。此时用归一化互相关normxcorr2做局部偏移修正或者用SURF特征点匹配后求单应矩阵。我推荐先试normxcorr2它不依赖特征点数量对纹理较弱的板卡更稳定。% 精配准在画面中心区域取一块模板子图做归一化互相关 center_patch template_gray(200:400, 300:500); c normxcorr2(center_patch, sample_aligned); [maxVal, imax] max(abs(c(:))); [ypeak, xpeak] ind2sub(size(c), imax(1)); % 计算偏移并重新平移 corr_offset [(xpeak-size(center_patch,2)) (ypeak-size(center_patch,1))]; tform2 affine2d([1 0 0; 0 1 0; corr_offset(1) corr_offset(2) 1]); sample_final imwarp(sample_aligned, tform2, OutputView, imref2d(size(template_gray)));3.4 配准误差的量化与验收配准不是看起来差不多就行。我做的验收方式是在模板和被检图上人工标定10组对应点比如元件本体上的特征角点、丝印字符的端点配准后计算这些点的坐标残差。要求平均残差小于0.5像素最大残差不超过1像素才认为配准合格。这里建议把配准后的叠加图像模板半透明叠加到检测图上可视化保存下来排查问题时非常有帮助。我发现很多误检最终都能追溯到配准残差偏大而不是算法本身有bug。4. 一致性判定差分量有没有变特征量变了多少4.1 图像差分法的适用边界图像差分是一致性检测最直观的手段diff_img imabsdiff(template_final, sample_final)然后做二值化把差异区域提取出来。差分法最适合以下场景元件缺失该有元件的地方空白了差分区域面积大且形状规整。多余物/异物模板中没有的物体差分区域明显。大面积色差比如板面氧化变色整体灰度差异显著。但差分法的短板也很明显对轻微偏移不敏感。一个电阻偏移0.3mm在差分图上会出现一侧亮边、另一侧暗边的成对区域如果用单纯的面积阈值判定很容易误判成缺陷或者漏判成正常。所以差分法只能作为第一层筛查输出候选区域不能直接下结论。4.2 基于regionprops的特征量测差分筛选出的候选区域需要进一步用特征量测来判定是否真正超差。我在Matlab里用的是bwconncomp加regionprops组合对每个候选区域提取以下几类特征面积Area区分微小噪声和真实缺陷的关键。外接矩形和质心BoundingBox, Centroid用于计算元件相对模板位置的偏移量。长宽比和偏心度MajorAxisLength/MinorAxisLength, Eccentricity用于区分细长桥连和圆形异物。平均灰度差候选区域的灰度差值大小辅助判断缺陷严重程度。以焊桥检测为例两个相邻焊盘中间出现桥连在差分图上表现为一条细长的亮带连通域特征通常是面积中等、长宽比很大、偏心度接近1和球形锡珠面积小、接近圆形完全不同。用几何特征就能把两者区分开。cc bwconncomp(bw_regions); stats regionprops(cc, Area, BoundingBox, Centroid, Eccentricity); for k 1:length(stats) if stats(k).Area 30 continue; % 小于30像素的连通域视为噪声 end % 桥连特征偏心度大且长宽比大同时落在焊盘ROI内 bbox stats(k).BoundingBox; aspectRatio bbox(4) / max(bbox(3), 1); if stats(k).Eccentricity 0.85 aspectRatio 2.5 % 标记为焊桥缺陷 end end4.3 判定规则的组合设计一致性检测的判定逻辑不要设计成一刀切建议分成三级硬缺陷差分面积大、几何特征明确直接判NG不经过人工复核。疑似缺陷面积处于阈值边缘、灰度差略超限标记出来进入人工复核队列。正常差异小于噪声下限直接通过。这个设计能让产线在漏检和误检之间找到可调的平衡。实际运行中我会把疑似缺陷的比例作为系统健康度的指标如果一批板卡疑似缺陷率突然升高优先排查是不是光源衰减、板卡批次变化或者治具松动而不是急着调算法阈值。5. Matlab实现的主链路与核心代码拆解5.1 主流程框架整个Matlab工程的结构不复杂我按模块拆分成了四个脚本main_process.m主入口负责读取模板和待检图调用各处理函数输出检测报告。preprocess.m预处理输出顶帽变换后的灰度图。align_image.m粗配准加精配准输出配准后的待检图。detect_diff.m差分、连通域分析和特征判定输出缺陷标注图和数据表。主入口的逻辑很直接template_gray preprocess(imread(template.tif)); fileList dir(samples/*.tif); for i 1:length(fileList) sample_gray preprocess(imread(fullfile(fileList(i).folder, fileList(i).name))); sample_final align_image(template_gray, sample_gray); [defectMask, stats, result] detect_diff(template_gray, sample_final); if result.hasDefect imwrite(defectMask, fullfile(results, [defect_ fileList(i).name])); end results(i) result; end实际工程我只写了这四个模块但每个模块内部的参数顶帽半径、配准子图大小、连通域面积阈值全部通过一个配置文件管理方便调参而不需要改代码。5.2 配准模块的工程化处理配准模块里容易出错的是imwarp的OutputView设置。如果不指定输出视图imwarp默认输出的尺寸会跟着变换矩阵走导致和模板尺寸不一致差分时矩阵维度对不上。这是新手最容易踩的坑。我在align_image.m里的处理方式是tform_final affinetform2d(...); % 组合粗配准和精配准的变换矩阵 sample_final imwarp(sample_gray, tform_final, OutputView, imref2d(size(template_gray)));同时我会在配准完成后做一次尺寸和数据类型校验assert(isequal(size(sample_final), size(template_gray)), 配准输出尺寸不一致);还有一个细节工业相机拍出来的图像如果是高动态范围RAW格式读入之后要统一转成double类型再参与计算否则差分计算时uint8的溢出问题会让结果变得很诡异。5.3 差分与连通域分析的参数设置差分阈值我用的是相对值而不是绝对值。因为被测图经过顶帽变换后灰度分布已经比较集中但不同板卡间仍有微小差异固定绝对阈值容易一边倒。diff_img imabsdiff(template_gray, sample_final); thresh graythresh(diff_img); % Otsu全局阈值先自动粗选 bw_diff imbinarize(diff_img, max(thresh, 0.12)); % 下限保护这里设置下限0.12归一化灰度是为了防止Otsu在差异很小时把噪声也选成前景。二值化之后用形态学开运算去掉孤立噪点bw_clean imopen(bw_diff, strel(disk, 2));结构元素半径2的圆盘对3像素以下的孤立噪点有效同时基本不伤真正的缺陷边缘。5.4 批处理与检测报告输出产线使用场景下检测结果需要留档。我用writetable把每次检测的判定结果、缺陷数量、面积特征写进Excel同时把缺陷标注图保存到指定目录。标注方法是在原图上用rectangle画框figure(Visible, off); imshow(sample_final); hold on; for k 1:length(stats) rectangle(Position, stats(k).BoundingBox, EdgeColor, r, LineWidth, 2); end saveas(gcf, fullfile(results, fileList(i).name)); close;需要注意Matlab在批处理时弹出figure窗口会拖慢速度务必用Visible, off或者set(gcf, Visible, off)。批量跑几百张图时这个细节能省下不少时间。6. 实测结果、误检案例与后续优化6.1 测试集和结果指标我用50块已知状态的板卡做了验证其中40块良品、10块人工挑出的不良品包含元件缺失3块、偏移3块、桥连2块、丝印不良2块。测试结果如下指标数值说明缺陷检出率100%10块不良品全部被标记良品误检率7.5%40块良品中有3块被标记为疑似缺陷平均处理时间约0.8秒/块包含配准和差分计算不含图像读取3块良品被误检的原因查下来都是光照问题两块是板卡表面有轻微水纹状污渍被顶帽变换放大一块是治具定位柱踩到了元件的边缘导致配准参考点轻微偏移。这再次验证了前面说的——光学环境和治具稳定性对检测的影响远大于分类算法本身。6.2 三个典型的误检案例第一个案例是板卡反光。某个电解电容的金属外壳反光造成局部过曝差分区域面积大于阈值被误判。解决办法是在预处理阶段对外壳高亮区域做灰度截断把超过240的像素压到模板对应位置的值让高光不再参与差分。第二个案例是配准子图选得不好。我在精配准时选了画面中心的一片无特征区域做模板结果normxcorr2的峰值非常平偏移收敛很慢。后来改成选丝印密集的角落区域相关峰变得尖锐配准残差从2像素降到0.3像素。选配准参考区域时优先选纹理特征丰富的区域而不是画面中心的区域。第三个案例是板卡轻微变形。长板卡两端受力不均导致中间区域有约1.5像素的局部形变全局仿射变换纠正不了。如果遇到这种情况可以考虑按区域分块配准但会显著增加计算量。我的折中方案是画ROI时避开形变明显的板卡边缘区域优先检测元件密集的中心区域。6.3 可以继续深化的方向如果后续要把这套方案推向更高通过率我建议按顺序做三件事引入多光源图像融合。把环形光、同轴光、条形光分别采集的图像各自处理后在特征层融合能明显降低反光类误检。用深度学习分类器替代部分手工阈值判定。差分图提取的候选区域数量通常不大用一个小型CNN对候选区域做二分类可以把误检率再降一个量级。对接产线MES系统。把检测结果实时写入数据库并通过控制IO信号驱动分拣机构。Matlab做原型验证、生成报告没有问题但真正上产线建议把核心算法迁移到C或部署到工业视觉控制器上。最后分享一段我自己的体会这类视觉检测项目总时间里有六成花在让图像稳定上只有四成在写算法。Matlab的优势在于图像处理函数齐全、调参方便能让你快速验证这个缺陷到底用白光还是红光、用差分还是用连通域这类问题。先把Matlab链路跑通再考虑性能优化和迁移部署是性价比最高的推进路径。如果你正在做类似的板卡检测研究希望这篇文章能帮你少走几段弯路。
返回列表