ARTICLE DETAIL

资讯详情

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

眼在手上2D九点标定:动态场景下的戳点验证与精度提升实战

眼在手上2D九点标定:动态场景下的戳点验证与精度提升实战 1. 眼在手上2D九点标定到底在标什么先把概念理清楚不然后面全是糊涂账。眼在手上Eye-in-Hand指的是相机固定在机械臂末端法兰上跟着手臂一起动。这个配置和眼在手外Eye-to-Hand最大的区别在于相机坐标系和工具坐标系之间的相对位姿是固定的但相机看到的世界会随着手臂运动不断变化。你每次移动机械臂相机也跟着换了个视角。那2D九点标定又是什么简单说就是让机械臂带着相机走九个不同的位置在每个位置拍一张标定板的图通过这九组“机械臂坐标”和“图像坐标”的对应关系解算出图像像素坐标到机械臂运动平面坐标的映射矩阵。这个矩阵通常是一个3×3的仿射变换矩阵能把图像上的像素点(u,v)换算成机械臂平面上的物理坐标(x,y)。为什么是九点而不是三点、四点三点只能解一个仿射变换平移旋转缩放错切四点可以做透视变换但九点能覆盖更大的工作区域而且通过最小二乘法能有效抑制单点误差。实际用下来九点标定在平面作业场景比如抓取、点胶、贴合里精度和效率的平衡点找得最好。动态场景这个词是标题里的关键限定。静态标定是标定板不动、机械臂动动态场景意味着标定过程中可能有外部干扰或者标定板本身在移动又或者需要在机械臂运动过程中完成标定。这就对标定的鲁棒性提出了更高要求——你不能指望每次拍照时标定板都完美地静止在视野正中央。戳点验证则是标定完成后的必做动作让机械臂末端或末端上的针尖去戳标定板上的某个已知点看实际戳的位置和理论计算的位置差多少。这个差值就是标定精度的直接体现。很多人标定完不验证等到实际生产时才发现偏差大得离谱那时候排查成本就高了。这套东西适合谁做机器人视觉引导抓取、自动点胶、激光打标、贴合对位的工程师尤其是用Halcon、OpenCV做手眼标定的朋友。如果你用的是UR、安川、汇川这类机械臂配合海康、大恒的工业相机这篇文章的流程可以直接参考。2. 标定方案选型与核心原理拆解2.1 为什么选2D九点而不是3D手眼标定手眼标定分两大类2D标定和3D标定。3D标定要解AXXB的经典方程需要相机内参、外参、机械臂位姿全参与计算量大对数据质量要求极高。而2D九点标定本质上是在一个平面上做映射不需要知道相机的内参和外参也不需要知道机械臂的绝对位姿只需要建立“像素坐标→机械臂平面坐标”的对应关系。这个选择背后的逻辑是如果你的作业场景是平面的就不要用3D标定。比如PCB板上的点胶、平面上的抓取、屏幕贴合这些场景里Z方向的变化很小2D标定完全够用而且精度往往比3D标定更高因为少了很多误差传递环节。但2D九点标定有个前提相机光轴要尽量垂直于标定平面。如果倾斜角度太大透视畸变会让仿射变换的精度下降。一般建议倾斜角控制在5度以内超过这个范围就要考虑做透视变换或者先做畸变校正。2.2 仿射变换矩阵的数学本质九点标定解的是一个仿射变换[x] [a b c] [u] [y] [d e f] [v] [1]其中(u,v)是图像像素坐标(x,y)是机械臂平面坐标。a、b、d、e控制旋转、缩放和错切c、f控制平移。这个矩阵有6个未知数理论上3个点就能解出来但为什么用9个点因为实际图像坐标有噪声——标定板角点检测有误差、机械臂定位有重复精度误差、相机有畸变。用9个点做最小二乘相当于用冗余数据来平均掉随机误差。我实测下来9个点的标定精度比3个点稳定得多尤其是工作区域边缘的位置。2.3 标定板的选择棋盘格还是圆点热词里提到了棋盘格标定和aruco标定板这里说下我的选择逻辑。棋盘格的优势是角点检测精度高OpenCV和Halcon都有成熟的角点检测算法亚像素级别的精度很容易做到。缺点是角点检测对图像质量敏感光照不均或者有遮挡时容易丢点。圆点标定板的优势是圆心检测更鲁棒即使有部分遮挡也能找到圆心。缺点是圆心提取的精度通常比棋盘格角点低半个像素左右。对于2D九点标定我一般推荐用棋盘格因为标定板是静止的光照可以控制角点检测的精度优势能充分发挥。棋盘格的大小选择有个经验公式让标定板占据相机视野的1/2到2/3。太小了角点检测精度不够太大了边缘容易出视野。2.4 动态场景下的特殊考量标题里的“动态场景”是我要重点说的。静态标定很简单摆好标定板机械臂走九个点拍照解矩阵完事。但动态场景下你可能遇到这些情况标定板不在机械臂的正下方需要机械臂带着相机去“找”标定板标定过程中机械臂不能完全停止需要在运动模糊可接受的范围内拍照标定板的位置有微小变动需要每次重新定位环境光变化导致图像亮度不一致这些情况要求你的标定流程有更强的自适应能力。我的做法是先用模板匹配或者形状匹配粗定位标定板然后在ROI内做角点检测最后用RANSAC剔除误匹配点。这样即使标定板位置有偏移也能稳定找到角点。3. 实操过程与核心环节实现3.1 硬件配置与现场布置先说我用的配置供参考部件型号备注机械臂安川GP7重复定位精度±0.02mm相机海康MV-CE050-10GM500万像素GigE接口镜头海康MVL-HF0828M-6MP8mm焦距工作距离约300mm标定板棋盘格11×9格格距5mm陶瓷基底精度±0.01mm光源环形白光漫射板减少反光现场布置有几个要点。第一标定板要固定在机械臂工作平面的某个位置用真空吸盘或者夹具锁死确保标定过程中不会移动。第二光源要从侧面打或者用环形光避免直射反光导致角点检测失败。第三相机要锁紧在法兰上线缆要留够余量但也不能太松防止运动时拉扯。注意标定板的平整度很关键。我见过有人把标定板放在一张纸上纸下面有气泡结果标定出来的精度怎么都上不去。陶瓷基底的标定板虽然贵但平整度有保障长期用下来更划算。3.2 九点位置的规划与示教九个点怎么走不是随便走九个位置就行。我的规划原则是覆盖工作区域九个点要均匀分布在你实际作业的平面范围内最好形成一个3×3的网格网格间距根据你的工作范围来定。包含中心点第五个点放在工作区域的正中心这样标定矩阵在中心区域的精度最高。避免极端位置最边缘的点不要贴着工作范围的边界留出10%的余量防止机械臂运动到极限位置。Z高度一致九个点的Z坐标必须完全相同这是2D标定的前提。如果Z有变化标定矩阵就不准了。示教的时候我习惯用机械臂的示教器手动走点每个点让相机能清晰看到标定板的完整图像。走完一个点记录机械臂的(x,y)坐标拍一张照保存图像。九个点走完你就有了九组对应数据。这里有个细节机械臂坐标取的是工具坐标系还是基坐标系取决于你的应用。如果是眼在手上通常取工具坐标系TCP的坐标因为你要控制的是工具末端的位置。但标定矩阵解出来的是图像坐标到机械臂坐标的映射所以你要明确用的是哪个坐标系后面验证的时候也要用同一个。3.3 图像采集与角点提取图像采集有几个坑要避开。第一曝光时间要固定不能用自动曝光否则九张图的亮度不一致角点检测的阈值就不好设。第二增益要调低宁可暗一点后期提亮也不要高增益带来的噪声。第三拍照时要等机械臂完全停止运动模糊会让角点变糊检测精度直线下降。角点提取我用的是OpenCV的findChessboardCorners加cornerSubPix。代码大概长这样import cv2 import numpy as np # 棋盘格内角点数量 pattern_size (10, 8) # 存储角点 obj_points [] img_points [] # 机械臂坐标示例 robot_coords [ (100.0, 200.0), (150.0, 200.0), (200.0, 200.0), (100.0, 250.0), (150.0, 250.0), (200.0, 250.0), (100.0, 300.0), (150.0, 300.0), (200.0, 300.0) ] for i in range(9): img cv2.imread(fcalib_{i}.png) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 查找角点 ret, corners cv2.findChessboardCorners(gray, pattern_size, None) if ret: # 亚像素优化 criteria (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) corners_refined cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) # 取标定板中心点作为对应点 center np.mean(corners_refined, axis0)[0] img_points.append(center) obj_points.append(robot_coords[i]) else: print(f第{i}张图角点检测失败) # 解仿射变换矩阵 img_points np.array(img_points, dtypenp.float32) obj_points np.array(obj_points, dtypenp.float32) M, _ cv2.estimateAffine2D(img_points, obj_points) print(仿射变换矩阵) print(M)这段代码的核心是estimateAffine2D它用最小二乘法解出6个参数。如果你用Halcon对应的算子是vector_to_hom_mat2d逻辑一样。实操心得角点检测失败是家常便饭。我的经验是如果某张图检测失败先看图像是不是太暗或者太亮调整曝光重拍。如果还是不行检查标定板是不是有反光或者遮挡。实在不行用鼠标手动点四个角点然后做透视变换把标定板摆正再检测角点。3.4 矩阵求解与精度评估解出矩阵后第一件事是回代验证。把九张图的角点中心坐标代入矩阵算出机械臂坐标和实际记录的机械臂坐标对比看误差有多大。# 回代验证 errors [] for i in range(9): img_pt np.array([img_points[i][0], img_points[i][1], 1.0]) pred M img_pt actual np.array(obj_points[i]) error np.linalg.norm(pred - actual) errors.append(error) print(f点{i1}: 预测({pred[0]:.3f}, {pred[1]:.3f}), 实际({actual[0]:.3f}, {actual[1]:.3f}), 误差{error:.3f}mm) print(f平均误差: {np.mean(errors):.3f}mm) print(f最大误差: {np.max(errors):.3f}mm)平均误差在0.1mm以内算优秀0.2mm以内算合格超过0.5mm就要找原因了。误差大的常见原因标定板不平、机械臂重复定位精度差、角点检测不准、Z高度不一致。3.5 戳点验证的具体操作标定矩阵解出来只是第一步戳点验证才是见真章的时候。具体怎么做方法一用机械臂末端的针尖去戳标定板上的某个角点。先在图像上找到这个角点的像素坐标用标定矩阵算出机械臂应该走到的位置然后手动示教机械臂让针尖对准这个角点看实际坐标和计算坐标差多少。方法二在标定板上选一个不在九点标定范围内的点比如标定板边缘的某个角点用同样的方法验证。这样可以检验标定矩阵的泛化能力。方法三用激光笔代替针尖。激光笔固定在法兰上打开激光让光点落在标定板上拍照找到光点的像素坐标算出机械臂坐标然后移动机械臂让光点对准目标点看偏差。我一般用方法一因为针尖的物理接触最直观。戳点的时候要注意针尖要尽量垂直于标定板斜着戳会有余弦误差。另外戳的时候力度要轻别把标定板戳坏了。注意戳点验证的误差要区分“标定误差”和“机械臂误差”。如果戳点误差在0.1mm左右基本是标定误差如果误差在0.3mm以上很可能是机械臂的重复定位精度不够或者TCP标定不准。这时候要先做TCP标定再做手眼标定。4. 常见问题与排查技巧实录4.1 角点检测失败怎么办这是最高频的问题。我整理了一个排查表现象可能原因解决方法完全检测不到角点标定板不在视野内调整机械臂位置让标定板完整出现在图像中检测到角点但数量不对标定板被遮挡清除遮挡物或调整光源角度角点位置偏移镜头畸变大先做相机畸变校正再检测角点角点检测不稳定光照不均用漫射光源避免直射反光边缘角点丢失标定板超出视野缩小标定板尺寸或增大工作距离我的独家技巧是在检测角点之前先做一次直方图均衡化。这招对光照不均的场景特别有效能把暗处的角点“拉”出来。代码就一行gray cv2.equalizeHist(gray)但要注意直方图均衡化会放大噪声如果图像本身噪声就大均衡化后反而更糟。所以这招适合光照不均但噪声小的场景。4.2 标定精度上不去怎么排查精度问题是最让人头疼的。我的排查顺序是第一步检查机械臂重复定位精度。让机械臂走同一个点十次记录每次的坐标看波动范围。如果波动超过0.05mm标定精度肯定上不去。这时候要先修机械臂或者换一台重复定位精度更高的。第二步检查标定板平整度。把标定板放在大理石平台上用塞尺检查有没有翘曲。陶瓷标定板一般没问题但如果是打印的纸质标定板翘曲是常态。第三步检查Z高度一致性。九个点的Z坐标必须完全相同。我见过有人示教的时候没注意Z差了0.5mm结果标定误差直接飙到1mm以上。第四步检查角点检测精度。把同一张图检测十次看角点坐标的波动。如果波动超过0.1像素说明图像质量有问题要调曝光或者换镜头。第五步检查标定点的分布。九个点如果太集中标定矩阵的泛化能力就差。尽量让九个点均匀分布在工作区域。4.3 动态场景下的特殊问题动态场景下标定板可能不在机械臂的正下方需要机械臂带着相机去“找”标定板。这时候有几个坑坑一机械臂运动到标定板附近时相机可能撞到标定板。我的做法是先在安全高度走XY到了目标位置再下降Z。安全高度根据你的夹具和标定板的高度来定一般留50mm以上。坑二运动模糊导致角点检测失败。如果必须在运动过程中拍照要缩短曝光时间同时提高光源亮度。曝光时间控制在1ms以内运动速度控制在50mm/s以内基本能消除运动模糊。坑三环境光变化导致图像亮度不一致。动态场景下机械臂可能带着相机走到不同的光照区域。我的做法是用主动光源环形光并且把光源控制器和相机触发同步每次拍照时光源亮度一致。坑四标定板位置有微小变动。如果标定板不是完全固定每次标定前要重新定位。我的做法是用模板匹配粗定位标定板然后在ROI内做角点检测。这样即使标定板偏移了5mm也能稳定找到角点。4.4 戳点验证的常见误区戳点验证看起来简单但有几个误区要避开误区一只戳一个点。一个点验证不了什么至少要戳三个点而且这三个点要分布在工作区域的不同位置。我一般戳五个点中心一个四个角各一个。误区二用标定过的点验证。用九点标定范围内的点验证误差肯定小但这不能说明标定矩阵的泛化能力。要用标定范围外的点验证比如标定板边缘的角点。误区三忽略机械臂的绝对定位精度。戳点验证的误差包含标定误差和机械臂误差。如果机械臂的绝对定位精度是0.1mm那戳点误差至少是0.1mm。这时候你不能指望标定误差小于0.1mm。误区四不记录验证数据。戳点验证的结果要记录包括每次的误差、环境条件、机械臂状态。这样如果后面精度下降你能快速定位是标定问题还是机械臂问题。4.5 标定矩阵的更新与维护标定矩阵不是一劳永逸的。以下情况需要重新标定相机被碰撞或者松动镜头被调整过焦距或者光圈机械臂维修过或者更换过部件工作环境温度变化超过10度标定精度下降超过0.1mm我的做法是每周做一次快速验证用戳点法戳一个点看误差有没有变化。如果误差稳定就不重新标定如果误差变大就重新标定。重新标定的时候我习惯把旧的标定矩阵备份新的矩阵解出来后和旧的对比。如果差异很大说明硬件有变动要排查原因。如果差异很小说明标定过程稳定可以放心用。5. 从标定到落地实际项目中的经验总结5.1 标定精度和节拍的平衡在实际产线上标定精度和节拍是一对矛盾。九点标定走九个点每个点要拍照、检测角点、记录坐标整个流程下来大概需要3到5分钟。如果产线换型频繁这个时间成本就很高。我的优化方案是把九点标定拆成“粗标定”和“精标定”两步。粗标定用三个点快速解一个初始矩阵精度大概在0.5mm左右。精标定用九个点在粗标定的基础上做优化精度能到0.1mm。如果产线对精度要求不高粗标定就够了如果要求高再做精标定。另一个优化是把标定和验证合并。九点标定走完八个点第九个点用来验证。如果第九个点的误差在允许范围内就直接用如果超差再补点重新标定。这样能省掉单独的验证步骤。5.2 不同机械臂品牌的标定差异我用过安川、UR、汇川、埃斯顿的机械臂标定流程大同小异但有几个差异要注意安川的机械臂坐标系定义比较特殊TCP标定要用六点法标定完还要做工具坐标系的验证。安川的重复定位精度很好标定精度容易做高。UR的机械臂用起来最简单示教器上直接有TCP标定向导跟着走就行。但UR的绝对定位精度一般标定精度受限于机械臂本身。汇川和埃斯顿的机械臂性价比高但示教器的操作逻辑和安川、UR不太一样标定的时候要仔细看手册。不管用哪个品牌标定流程都是一样的先做TCP标定再做手眼标定最后戳点验证。TCP标定不准手眼标定肯定不准。5.3 视觉引导抓取的完整流程标定只是视觉引导抓取的第一步。完整的流程是相机标定标定相机内参和畸变系数用张正友标定法拍15到20张棋盘格图。手眼标定九点标定解图像到机械臂的映射矩阵。目标检测用模板匹配或者深度学习检测目标物体的位置和角度。坐标转换把目标物体的像素坐标用标定矩阵转换成机械臂坐标。抓取规划根据目标物体的位置和角度规划机械臂的抓取路径。执行抓取机械臂运动到目标位置闭合夹爪完成抓取。这里面每一步都有坑。相机标定不准手眼标定再准也没用目标检测不稳定抓取成功率就上不去抓取规划不合理机械臂可能撞到障碍物。我的经验是先把相机标定和手眼标定做扎实这两步是基础。基础不牢后面全是空中楼阁。5.4 标定结果的长期稳定性标定结果能管多久这取决于你的使用环境。在恒温恒湿的实验室里标定结果能管几个月。在温度变化大、振动大的产线上可能几天就要重新标定。提高长期稳定性的方法相机和镜头的连接要锁死用螺纹胶或者防松垫圈。线缆要固定好避免运动时拉扯相机。标定板要存放在恒温恒湿的环境避免热胀冷缩。定期做戳点验证发现精度下降及时重新标定。我一般建议客户每周做一次快速验证每月做一次完整标定。如果产线环境恶劣验证频率要更高。5.5 一个真实的踩坑案例最后分享一个我踩过的坑。有一次给客户做视觉引导抓取标定的时候精度很好戳点误差0.05mm。但实际生产时抓取成功率只有80%经常抓偏。排查了半天发现问题是标定时的Z高度和实际抓取时的Z高度不一致。标定时相机离标定板300mm实际抓取时相机离工件280mm。虽然只差了20mm但镜头的畸变在不同工作距离下是不一样的导致标定矩阵在280mm高度下不准。解决方法很简单标定时的Z高度要和实际作业时的Z高度一致。如果作业时Z高度会变化就要做多高度的标定或者先做畸变校正。这个坑让我明白了一个道理标定不是解一个矩阵就完事要把标定条件和实际作业条件对齐。工作距离、光照、温度、振动这些因素都要考虑进去。后来我养成了一个习惯标定之前先把实际作业的工况摸清楚然后在相同的工况下做标定。这样标定出来的矩阵在实际作业时才能发挥最大效用。
返回列表