
在SMT产线上蹲过的人都清楚一片PCB板进到贴片机里机器第一件事不是急着贴元件而是先找板子上的mark点。mark点是印在PCB上的一个圆形基准标记通常有两个分布在板子的对角位置贴片机靠着这两个mark点来锁定整块板的位置和旋转角度然后才敢把成千上万个焊盘坐标换算成机械轴的动作路径。今天这篇就聊聊两个mark点是怎么把板上任意一个目标点的位置给算出来的——这套思路不仅贴片机在用AOI检测、锡膏印刷机、光学点胶机凡是做视觉对位的设备底层逻辑都是同一套。我最早接触mark点定位是在调试一台国产贴片机的时候当时客户投诉某款板子上的QFP芯片总是偏位偏的方向还不固定。排查到最后问题就出在mark点的识别和坐标补偿算法上而不是贴片头本身。从那以后我对“两个点定一个平面”这件事有了很深的体会今天把这些经验和计算过程掰开揉碎讲一讲。1. 为什么是两个mark点不是三个也不是一个1.1 一个点只能回答“在哪”回答不了“往哪转”先想一个最基础的问题一块板子放在传送带上它的实际位置和理论位置之间有几种偏差答案是三种X方向平移、Y方向平移、绕板子某点旋转一个角度。这是一个平面刚体在二维空间里的全部自由度一共三个。如果只用单个mark点做定位视觉系统识别出来的是一个坐标值(x, y)只能解出两个自由度的偏差也就是X和Y方向的平移。旋转角度是完全未知的。这一点很多人一开始没想明白觉得“我找到一个基准点把元件坐标都加上这个偏移不就行了吗”。问题是板子在传送带上不是规规矩矩正着放的可能有零点几度甚至一两度的角度偏差。哪怕只有0.5度的偏转在一块200mm长的板子上远离mark点的位置就会产生大约1.7mm的偏差。这种偏差对贴装0402封装、0.5mm脚距的QFP来说已经是毁灭性的了焊盘位置早就偏到焊膏外面去了。1.2 两个点的几何约束刚好锁死三个自由度两个mark点解决的就是这个旋转自由度的问题。每个mark点识别出来后有两个坐标值两个点一共四个坐标观测值而板的位置姿态只有三个自由度所以方程组是超定的旋转角度也能被唯一确定。具体来说我们把第一个mark点当作板坐标系的基准原点第二个mark点作为方向基准。两个mark点连线的方向代表了板子自身的“摆向”。任意一个元件焊盘的理论坐标都是在这个板坐标系里定义的。视觉系统识别出两个mark的实际位置后就能算出板坐标系相对于机器坐标系的平移量和旋转角然后把每个目标点的理论坐标映射到机器坐标系里去执行。这个思路可以类比成在地上画了一条线你说“站在线的这一端面朝线的方向往前走两米”。只要线在方向就在知道方向和原点任何相对位置都能还原出来。视觉定位里常说的“欧几里得变换”本质就是这么回事一个平移加一个旋转三个参数解决问题。1.3 三个mark点什么时候才需要那两个点都够用了为什么有些设备还要用三个甚至更多的mark点主要是因为板子会变形。PCB经过回流焊高温之后或者拼板上的某块小板与整板之间存在位置公差板子本身可能发生热胀冷缩或者翘曲。两点的刚体变换模型默认板子是“刚性”的只包含平移和旋转处理不了板子的缩放和扭曲。这时候就需要第三个mark点来引入胀缩系数或者做分区映射把板子不同区域的尺寸变化都补偿进去。所以在实际项目中贴片机程序默认用两个板边大mark点做整板定位但如果板子尺寸特别大、有细间距密脚IC、或者工艺上容易产生明显胀缩产线工程师会选择在板子的中间或关键元件附近加一个局部mark点用来做局部补偿。这也是很多PCB设计规范里“拼板加mark、大板加mark、密脚器件周围加mark”这些要求的由来。2. 想把mark识别准先从设计规范和光源细节说起2.1 什么样的mark点才是“好”的mark点很多软件层面的定位问题追根溯源是mark点本身设计得就不合格。IPC标准里对mark点有明确建议形状是实心圆直径一般在1.0mm左右表面是裸铜、镀锡或者镀金周围有一个环形禁铜区禁铜区的宽度至少和mark直径相当而且mark点边缘到板边或者其它导电图形要留出足够距离。这个环形禁铜区特别关键。它存在的意义是让视觉系统在图像里看到一个“干净的圆”中间是亮的金属圆斑外面一圈是与基材底色接近的空白区再外面才允许有其他走线。如果mark点周围密密麻麻都是走线二值化之后圆斑外面全是噪声圆心拟合结果自然不稳定。我见过一块设计得很差的板子mark点和板边的邮票孔离得特别近贴片机相机一到那边邮票孔的金属毛刺和mark的轮廓混在一起圆心识别偏了零点零几毫米整板元件跟着偏移。另外mark点的表面处理也直接影响识别稳定性。裸铜容易氧化氧化后颜色发暗与基材对比度下降镀锡板表面反光强容易过曝。如果同一块板子上多个mark表面处理工艺不一致调试参数就很麻烦。所以做产品设计时mark点的表面处理工艺最好和板面铜箔保持一致避免出现“这个mark亮、那个mark暗”的情况。2.2 视觉识别mark点的三种主流方法识别mark点本质上是图像处理问题产线上常见的手段有三类。第一类是模板匹配。提前保存一张标准mark的灰度图像作为模板在实拍图像里滑动窗口计算相似度找到最匹配的位置。这种方法对背景复杂的板子比较有效缺点是运算量偏大对光照变化也比较敏感模板和实拍图像亮度差异大时匹配分数会下降。第二类是blob分析加圆拟合这是当前设备里最主流的方法。流程很简单先做灰度阈值分割把图像变成二值图亮斑和暗斑就分开了然后用面积、圆度、长宽比等几何特征过滤掉不相关的斑块最后对保留下来的圆斑边缘做最小二乘圆拟合圆心坐标就是mark的中心。这个方法速度快、稳定性好我接触过的贴片机和AOI百分之八九十是这条路子。第三类是边缘检测加霍夫圆变换。先用Canny算子提取边缘再用霍夫变换找圆。它对光照变化和mark残缺的适应性更强但参数多、算力开销大而且容易把板上的过孔、圆焊盘误判成mark。所以除非板面条件很差一般不太推荐在实时产线上用。2.3 光源选错了再好的算法也白搭识别mark点的时候最折磨人的不是算法而是光源。金属mark表面反射率很高尤其是镀锡、镀银的表面用高角度的环形光打上去中心区域直接过曝变成一片白圆斑的轮廓反而找不准拟合出来的圆心会往亮区偏移。我用下来的经验是低角度环形光对mark识别最友好。光从接近水平的角度打到板面mark边缘会形成一圈柔和的明暗过渡圆形轮廓的灰度梯度非常干净。如果mark表面是镜面反光很强的金光亮铜可以考虑同轴光源它的光线通过半反半透镜垂直照射物体专门对付这种高反光表面。还有一个很容易被忽略的问题相机的安装角度必须和板面垂直。相机斜了圆斑成像就变成椭圆圆心拟合倒是还能勉强找到但坐标精度会明显下降。另外板子放不平、有大面积翘曲时mark点所在位置的高度变化会导致放大倍率不一致像素当量就不准了这也是定位偏差的来源之一。补充一句算法识别出来的只是像素坐标要换算成毫米单位的物理坐标必须做相机标定把像素当量和镜头畸变系数标清楚这一步不做或者标定参数过期后面所有补偿都是空中楼阁。3. 从识别到坐标解算两个mark点怎么算出任意目标点3.1 先把“板坐标系”定义清楚在讨论计算之前要先把坐标系说清楚不然公式一推就乱。PCB设计文件里每个元件焊盘中心都有一个坐标值这些坐标是以板子的某个原点为基准定义的我们叫它板坐标系。视觉系统拍照之后mark点位置是在图像坐标系里经过标定后可以换算到机器坐标系。定位的目标就是已知两个mark点在板坐标系里的理论坐标以及它们在机器坐标系里的实测坐标求解一个从板坐标系映射到机器坐标系的变换关系。有了这个变换关系板上任何一个焊盘的理论坐标都能映射成机器能执行的实际坐标。实际项目中两个mark点的理论坐标大家习惯直接取Gerber里的设计值。如果设计文件里没有现成的mark坐标就在机器上手动示教一次让设备记住第一次识别到的位置作为基准后续每次进来都拿当前识别结果跟这个基准做对比。这种“示教原点”的方式在很多设备上反而比图纸坐标更实用因为设备自己定义的基准和它的机械轴坐标系更契合。3.2 一步步算一个具体的数值例子理论上来讲我们假设一块板的两个mark点理论坐标是P1 (20, 20)单位mmP2 (120, 20)也就是说两个mark点在同一水平线上间距100mm。板上某个QFP芯片的焊盘中心理论坐标是(70, 50)也就是两个mark点连线的正中间偏上30mm的位置。现在设备实际进板后视觉系统识别出的mark点实测坐标是P1 (24, 25)P2 (124, 19)首先算角度偏差。理论方向向量V (120-20, 20-20) (100, 0)实测方向向量V (124-24, 19-25) (100, -6)。两个向量之间的夹角用atan2函数算θ atan2(-6, 100) - atan2(0, 100) ≈ -0.0599 rad ≈ -3.43度角度是负的意思是板子相对理论位置逆时针转了一点点。这里有第一个容易踩坑的地方旋转角度必须以两个mark点的连线为基准来计算不能只看单个mark。很多新手直接用P1与P1的差当平移量然后用这个平移量去补偿所有点完全不考虑旋转结果就是离P1近的元件偏得少、离P1远的元件偏得多怎么调都调不好。其次算平移量。选择以理论P1点作为旋转中心。目标点(70, 50)相对P1的向量是r (70-20, 50-20) (50, 30)把这个向量旋转θ角。旋转公式是Rx 50 × cos(-3.43°) - 30 × sin(-3.43°) Ry 50 × sin(-3.43°) 30 × cos(-3.43°)cos(-3.43°) ≈ 0.9982sin(-3.43°) ≈ -0.0599代入Rx ≈ 50 × 0.9982 - 30 × (-0.0599) ≈ 49.91 1.80 ≈ 51.71 Ry ≈ 50 × (-0.0599) 30 × 0.9982 ≈ -2.99 29.95 ≈ 26.95最后把这个旋转后的相对坐标加上实测P1的坐标就得到目标点的实际位置x 24 51.71 ≈ 75.71 y 25 26.95 ≈ 51.95所以视觉系统应该让贴片头跑到(75.71, 51.95)这个位置去贴装。相比理论坐标(70, 50)X方向偏了5.71mmY方向偏了1.95mm。这个偏差里既有P1本身平移的量X偏4mm、Y偏5mm也有板子旋转后离P1越远累计偏得越多的部分。3.3 通用化用仿射变换矩阵一步到位手工按上面的步骤算一次可以但产线上每块板都要算几百上千个点肯定不能这么笨算。工程实现上这些变换通常用齐次坐标的仿射变换矩阵来表达[x] [cosθ -sinθ tx] [x] [y] [sinθ cosθ ty] [y] [1 ] [0 0 1] [1]注意这里的tx和ty并不是简单的P1减P1而是把旋转中心放在P1之后、再平移到P1的合成平移量本质上和我上面手算的“先绕P1转、再平移到P1”是一回事。用代码实现的话可以直接用OpenCV的getAffineTransform它需要三组对应点。第三个点怎么来用第二个mark绕第一个mark旋转90度的虚拟向量来构造即可。import cv2 import numpy as np # 理论mark点和实测mark点单位mm src np.float32([[20, 20], [120, 20]]) # 理论坐标 dst np.float32([[24, 25], [124, 19]]) # 实测坐标 p1_s, p2_s src[0], src[1] p1_d, p2_d dst[0], dst[1] # 构造第三个对应点从第一个mark出发、绕法向旋转90度的向量 v_s p2_s - p1_s # (100, 0) v_d p2_d - p1_d # (100, -6) src3 np.float32([p1_s, p2_s, p1_s np.float32([-v_s[1], v_s[0]])]) dst3 np.float32([p1_d, p2_d, p1_d np.float32([-v_d[1], v_d[0]])]) # 使用三组对应点求解仿射变换矩阵 M cv2.getAffineTransform(src3, dst3) # 对目标点理论坐标做变换 pts np.array([[70, 50]], dtypenp.float32) result cv2.transform(pts.reshape(1, -1, 2), M) print(result) # 输出约 [[75.71, 51.95]]这段代码在生产级设备里当然不会被直接用工业上通常用Halcon的vector_to_rigid或者设备供应商封装好的标定函数但底层数学完全一样。理解了矩阵每个元素怎么来的不管换什么视觉库都能快速上手。3.4 完整定位流程从拍照到坐标补偿把上面的计算方法放到实际设备里一次完整的mark点定位流程是这样的。第一步相机在指定位置拍摄两个mark点的图像。第二步图像预处理包括灰度化、滤波、二值化让mark区域从背景里跳出来。第三步用blob分析或模板匹配定位两个mark的圆心坐标并通过相机标定把像素坐标换算成毫米坐标。第四步拿实测坐标和理论mark坐标计算角度偏差和平移量。第五步按照3.3节的变换矩阵把板上所有目标点的理论坐标批量转换成补偿后的实际坐标。第六步设备运动轴系根据补偿后的坐标执行贴装、检测或点胶动作。这套流程在贴片机里是每进一块板就执行一次的整块板的定位时间通常控制在几百毫秒以内。所以视觉定位不仅要准还要快。这也是为什么产线上的视觉程序都会尽量裁小搜索区域、减少图像处理像素范围把识别耗时压到最短。4. 产线调试中容易翻车的几个坑与排查思路4.1 识别不到或识别错位先分三层查实际产线调试的时候mark识别问题最让人头疼因为它可能是软件、硬件、工艺里任何一个环节出的问题。我总结了一个三层排查法先看图像再查参数最后动机构。看图像这一步直接把相机的实时画面调出来看mark点成像是否清晰有没有过曝、欠曝、遮挡、反光光晕的问题。图像层面不正常不要去调软件参数那是在错误的基础上叠错误。图像正常了再检查二值化阈值、面积范围、圆度限制这些识别参数确认程序圈选的是mark本身而不是旁边某个圆焊盘或过孔。如果图像和参数都没问题才需要怀疑相机松动、光源频闪、机构抖动这类硬伤。现象常见原因首选排查方向mark点找不到光照过暗、mark表面氧化、阈值设置不当查看图像确认mark成像可见圆心识别偏位反光光晕、邻近视场干扰、标定参数失真调整光源角度与亮度检查相机标定误识别成其他圆孔板上有相似的圆形过孔或焊盘收紧面积和圆度范围限定ROI搜索区域识别结果偶发抖动光源频闪、板子抖动、相机支架松动检查机构紧固和光源驱动稳定性这套表格是我在几个项目里反复验证过的遇到故障按顺序查比无头苍蝇一样乱调参数效率高得多。4.2 PCB涨缩问题两点定位的边界在哪里前面说了两点定位默认板子是刚性的。但实际产线中PCB并不是绝对刚体尤其是多层板经过回流焊之后基材的树脂固化收缩、铜箔与玻纤布的CTE差异都会让板子尺寸发生细微变化。一块300mm长的板子涨缩万分之五远端位置就能偏0.15mm这个量对细间距连接器来说已经不能忽略了。遇到这种情况两点定位的模型先要跑一遍在远离两个mark点的区域如果依然偏位就要怀疑是不是胀缩问题。解决办法是在板子中间、或者大尺寸元器件附近增加局部mark点把板子划分成多个区域每个区域用各自的mark点做局部坐标补偿。这种“多mark分区定位”在大板、拼板项目里非常常见。我调试过一个客户的双面板项目拼板尺寸很大客户坚持用两个板边mark点做统一补偿AOI检测时四角的焊盘位置一直在临界值附近波动。后来加了板中央一个mark点做分区处理一次性解决了边缘区域精度超差的问题。所以两点定位是最基础的模型但不是一个万能模型板子一大、工艺一严多点补偿几乎是不可避免的。4.3 标定问题坐标算得再聪明基础烂了全白搭产线调试里还有一个特别容易背锅的环节——相机标定。mark算法算得再准如果相机标定参数不对输出到运动轴系的坐标照样是偏的。最常见的情况是相机安装平面与运动轴平面不平行导致图像不同位置的像素当量不一致。比如视场中心区域1毫米对应50个像素视场边缘因为倾斜变成52个像素如果全视场用同一个像素当量mark识别出的坐标在边缘区域就会渐变性偏移。这种偏差不是固定值很难靠mark补偿消掉只能重新做标定。另一个高频问题是没有做旋转中心标定。有些设备在定位结束后还需要根据mark偏差调整运动轴的旋转角度这时如果旋转中心没有标定旋转补偿会引入额外的平移误差。很多“mark定位准了但动作还是偏”的案例最后都查到旋转中心和相机坐标系的转换关系上。所以做视觉引导对位项目标定环节一定要严格走完这个钱省不得。4.4 快速验证定位结果的土办法在产线上快速验证mark定位是否准确我有一个习惯每次调完程序都手动指定一个已知坐标的元件焊盘让设备按补偿后的坐标移动到该位置然后用显微镜观察贴装头或探针是否正好落在焊盘中心。这一步看着土但比看任何数据日志都直观能快速暴露坐标系方向、符号取反之类的低级错误。另外在调试阶段可以把mark识别结果实时显示在界面上让设备连续空跑二三十次记录每次识别出的mark坐标波动范围。如果圆心坐标波动在±0.01mm以内说明当前的光源和参数组合基本可靠如果波动超过±0.03mm建议先调光源和图像预处理再考虑算法参数不要硬扛着误差往下调试。这套方法帮我避过很多次深夜产线救火的局面算是压箱底的经验。定位这件事原理不复杂但真正让它跑得稳、跑得久靠的还是一个个细节。我对mark点的要求就三条两个点之间的连线尽量长、mark周围要干净、识别参数要留出余量。连线越长角度计算越精准周围干净识别圆心才稳定参数有余量换一批板子、换一种表面处理工艺也不至于崩。希望这篇能帮到正在跟mark点较劲的同行。