恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
固晶机视觉标定】九点相似变换 + 三点角度标定 + 吸嘴旋转中心补偿|C# 极简单文件实现 标签:# 机器视觉 #固晶机 #九点标定 #视觉纠偏 #C# 视觉标定 #XYθ 平台
首页
资讯中心
/
固晶机视觉标定】九点相似变换 + 三点角度标定 + 吸嘴旋转中心补偿|C# 极简单文件实现 标签:# 机器视觉 #固晶机 #九点标定 #视觉纠偏 #C# 视觉标定 #XYθ 平台
固晶机视觉标定】九点相似变换 + 三点角度标定 + 吸嘴旋转中心补偿|C# 极简单文件实现 标签:# 机器视觉 #固晶机 #九点标定 #视觉纠偏 #C# 视觉标定 #XYθ 平台
发布时间:2026/7/30 20:18:39
前言固晶机主流方案吸嘴拾取芯片 → 移动至视觉工位拍照识别芯片位置与角度 → 平台 XYθ 联合运动完成贴装纠偏。 工程开发中存在 3 个核心难点相机安装倾斜像素坐标无法直接映射平台世界坐标视觉识别角度和 θ 电机角度存在偏差需要角度标定θ 轴旋转中心吸嘴轴心≠相机视野中心旋转时芯片产生 XY 偏移必须几何补偿。市面上很多 Demo 只实现九点坐标转换忽略旋转偏心补偿现场调试持续偏位。本文提供一体化单文件 C# 实现 ✅九点相似变换标定相机倾斜、缩放、原点校正 ✅三点线性角度标定视觉角度→θ 电机角度映射 ✅最小二乘拟合吸嘴旋转中心 ✅内置绕旋转中心旋转变换补偿 ✅极简调用业务层一行代码完成换算 ✅.NET Framework 4.6.1 无第三方依赖WinForms 工控软件直接接入重要说明所有几何运算全部在【平台世界坐标系】完成。旋转中心吸嘴轴心与相机视野中心点不需要重合算法天然支持任意位置。整体模型说明九点相似变换公式像素→世界\(W_x A\cdot P_x - B\cdot P_y OffsetX\)\(W_y B\cdot P_x A\cdot P_y OffsetY\) 自带全局相机旋转、等比例缩放、平移修正。θ 角度线性映射\(MotorAngle K \times VisionAngle BTheta\)旋转偏心补偿逻辑 芯片识别得到世界坐标以吸嘴旋转中心为圆心反向旋转电机目标角度抵消 θ 转动带来的 XY 偏移得到最终贴装目标点位。完整源码 Calibration.cscsharp运行using System; using System.Collections.Generic; namespace VisionCalibration { /// summary九点标定点(像素坐标 ↔ 平台世界坐标)/summary public struct Calib9Point { public double WorldX; public double WorldY; public double PixelX; public double PixelY; } /// summaryθ角度标定点(视觉角度 ↔ 电机角度)/summary public struct RotCalibPoint { public double VisionAngle; public double MotorAngle; } /// summary统一标定参数容器直接Newtonsoft.Json序列化保存/加载/summary public class CalibData { //九点坐标标定参数 public double A; public double B; public double OffsetX; public double OffsetY; //θ角度标定参数 public double K; public double BTheta; //吸嘴旋转中心【平台世界坐标】 public double RotCenterX; public double RotCenterY; } public static class Calibrator { #region 标定求解 /// summary九点坐标标定求解/summary public static CalibData Solve9Point(ListCalib9Point points) { if (points.Count 9) throw new Exception(九点标定至少采集9组点位); double sumPx 0, sumPy 0; double sumPx2 0, sumPy2 0; double sumWx 0, sumWy 0; double sumWxPx 0, sumWxPy 0; double sumWyPx 0, sumWyPy 0; int n points.Count; foreach (var p in points) { sumPx p.PixelX; sumPy p.PixelY; sumPx2 p.PixelX * p.PixelX; sumPy2 p.PixelY * p.PixelY; sumWx p.WorldX; sumWy p.WorldY; sumWxPx p.WorldX * p.PixelX; sumWxPy p.WorldX * p.PixelY; sumWyPx p.WorldY * p.PixelX; sumWyPy p.WorldY * p.PixelY; } double m11 sumPx2 sumPy2; double r1 sumWxPx sumWyPy; double r2 -sumWxPy sumWyPx; if (Math.Abs(m11) 1e-12) throw new Exception(标定点分布异常无法求解); double a r1 / m11; double b r2 / m11; double ox (sumWx - a * sumPx b * sumPy) / n; double oy (sumWy - b * sumPx - a * sumPy) / n; return new CalibData { A a, B b, OffsetX ox, OffsetY oy }; } /// summary三点θ角度标定结果写入CalibData/summary public static void SolveThetaCalib(CalibData data, ListRotCalibPoint points) { if (points.Count 3) throw new Exception(角度标定至少3组采样); int n points.Count; double sumX 0, sumY 0, sumXX 0, sumXY 0; foreach (var pt in points) { double x pt.VisionAngle; double y pt.MotorAngle; sumX x; sumY y; sumXX x * x; sumXY x * y; } double denom n * sumXX - sumX * sumX; if (Math.Abs(denom) 1e-12) throw new Exception(角度标定点线性相关拟合失败); double K (n * sumXY - sumX * sumY) / denom; double Bt (sumY - K * sumX) / n; data.K K; data.BTheta Bt; } /// summary最小二乘拟合旋转中心传入多组旋转后的芯片世界坐标/summary public static void FitRotCenter(CalibData data, ListTupledouble, double worldPoints) { int n worldPoints.Count; if (n 3) throw new Exception(拟合旋转中心至少采集3个点位); double sumX 0, sumY 0, sumXX 0, sumYY 0, sumXY 0; double sumX3 0, sumY3 0, sumXYY 0, sumXXY 0; foreach (var p in worldPoints) { double x p.Item1; double y p.Item2; sumX x; sumY y; sumXX x * x; sumYY y * y; sumXY x * y; sumX3 x * x * x; sumY3 y * y * y; sumXYY x * y * y; sumXXY x * x * y; } double A n * (sumXX sumYY) - sumX * sumX - sumY * sumY; double B 0.5 * ((sumXX sumYY) * sumX - n * (sumX3 sumXYY)); double C 0.5 * ((sumXX sumYY) * sumY - n * (sumXXY sumY3)); data.RotCenterX B / A; data.RotCenterY C / A; } #endregion #region 业务调用接口 /// summary /// 一站式转换【拾取后纠偏标准接口】 /// 像素坐标视觉角度 → 平台目标X Y Theta自带吸嘴旋转中心补偿 /// 适用固晶机吸嘴抓取芯片后视觉拍照纠偏 /// /summary /// param namecalib标定总参数/param /// param namepx芯片中心像素X/param /// param namepy芯片中心像素Y/param /// param namevisionAngleNCC识别芯片角度(°)/param /// param nametargetX输出平台X/param /// param nametargetY输出平台Y/param /// param nametargetTheta输出θ电机角度/param public static void Transform(CalibData calib, double px, double py, double visionAngle, out double targetX, out double targetY, out double targetTheta) { //1.像素坐标转为平台原始世界坐标 double wx0 calib.A * px - calib.B * py calib.OffsetX; double wy0 calib.B * px calib.A * py calib.OffsetY; //2.视觉角度换算θ电机目标角度 targetTheta calib.K * visionAngle calib.BTheta; //3.绕吸嘴旋转中心反向旋转补偿消除θ旋转偏心 double rad -targetTheta * Math.PI / 180.0; double c Math.Cos(rad); double s Math.Sin(rad); double dx wx0 - calib.RotCenterX; double dy wy0 - calib.RotCenterY; double rx dx * c - dy * s; double ry dx * s dy * c; targetX calib.RotCenterX rx; targetY calib.RotCenterY ry; } /// summary /// 简易转换【无旋转偏心补偿】 /// 适用晶圆台自带θ拾取前纠偏场景 /// /summary public static void TransformSimple(CalibData calib, double px, double py, double visionAngle, out double targetX, out double targetY, out double targetTheta) { targetX calib.A * px - calib.B * py calib.OffsetX; targetY calib.B * px calib.A * py calib.OffsetY; targetTheta calib.K * visionAngle calib.BTheta; } #endregion } }使用示范1. 生产实时换算业务层最简调用csharp运行using VisionCalibration; //全局标定参数软件启动从Json文件加载 CalibData _calib; //视觉NCC识别输出 double pixelX 640.22; double pixelY 510.15; double chipAngle 3.72; //一行代码完成全部坐标、角度、偏心补偿计算 Calibrator.Transform(_calib, pixelX, pixelY, chipAngle, out double destX, out double destY, out double destTheta); //直接下发运动控制器2. 完整标定流程csharp运行//1.九点坐标标定 ListCalib9Point nineList new ListCalib9Point(); //填充9组 {平台WorldX,WorldY ↔ 相机PixelX,PixelY} CalibData calib Calibrator.Solve9Point(nineList); //2.三点角度标定 ListRotCalibPoint thetaList new ListRotCalibPoint(); //填充 3组 {视觉识别角度电机实际角度} Calibrator.SolveThetaCalib(calib, thetaList); //3.拟合吸嘴旋转中心 ListTupledouble, double rotPointList new ListTupledouble, double(); //吸嘴抓取芯片θ旋转多个角度拍照转换为世界坐标存入集合 Calibrator.FitRotCenter(calib, rotPointList); //序列化calib对象保存到本地json开机自动载入现场标定操作指南①九点标定平台移动 9 个点位视觉识别 Mark记录每组【平台实际坐标】和【相机像素坐标】。点位尽量铺满整个视野不要集中在一小块区域。②θ 角度标定吸嘴抓取芯片固定 XYθ 分别转到 - 10°,0°,10°每次拍照获取视觉角度形成三组采样点拟合 K、BTheta。③吸嘴旋转中心标定吸嘴吸取芯片XY 锁定θ 旋转多个角度拍照识别芯片坐标九点换算成世界坐标调用 FitRotCenter 拟合圆心即吸嘴旋转轴心。重点不需要将吸嘴移动到相机视野中心进行标定两种接口区分现场别调用错Calibrator.Transform()✅带旋转中心偏心补偿 ✅拾取芯片后移动视觉拍照主流固晶方案必须使用这个Calibrator.TransformSimple()❌无旋转偏心补偿 适合晶圆载台自带 θ 轴先校正角度再拾取芯片场景调试验证方法吸嘴 XY 保持不动θ 轴旋转 ±10° 拍照识别调用 Transform 计算目标 XY。 理想状态下输出的 targetX、targetY 几乎不变。 如果 XY 明显漂移 1旋转中心标定不准 2角度标定参数误差大 3NCC 识别角度噪声过大。补充拓展CalibData 字段可以直接使用 Newtonsoft.Json 序列化持久化 如果需要后续我可以补充像素逆变换、标定残差计算函数方便评估标定精度。结语XYθ 固晶视觉纠偏最大坑就是忽略吸嘴旋转偏心。很多工程师只做九点标定调试时出现角度越大、偏移越大的现象。本文代码在世界坐标系完成旋转变换完美解决旋转中心与相机中心不重合问题可以直接落地半导体封装设备。