
手眼标定实战眼在手上、眼在手外两种方案代码实现手眼标定就像给机械臂配了一副翻译眼镜——把相机看到的世界坐标翻译成机械臂能懂的动作坐标。这篇直接上代码两种方案一网打尽。一、手眼标定两种安装方式1.1 眼在手上Eye-in-Hand相机安装在机械臂末端法兰盘上随机械臂一起运动。机械臂走到哪相机就看到哪——相当于你伸手过去的时候手上的眼睛就近观察目标。特点视野随末端移动近距离观测精度高但看不到全局。1.2 眼在手外Eye-to-Hand相机固定在工作空间外部支架/天花板不随机械臂移动。相当于一个上帝视角全局俯瞰整个桌面。特点视野固定覆盖整个工作区域定位精度受距离影响但能看到全局布局。二、两种方案对比对比维度眼在手上 (Eye-in-Hand)眼在手外 (Eye-to-Hand)视野范围局部随末端移动全局覆盖整个工作空间定位精度近距离高精度远距离精度略降标定难度中等需要多组末端位姿中等需要多组基座位姿适用场景精细装配、近距离抓取大范围分拣、多目标场景深度获取可近距测深误差小需额外深度相机或三角测量标定矩阵含义相机→末端坐标变换相机→基座坐标变换选哪种取决于你的任务精细操作选眼在手上全局分拣选眼在手外。三、手眼标定数学原理AXXB 方程手眼标定的核心方程A * X X * B其中A机械臂两次位姿之间的变换末端相对于基座B相机两次观测之间的变换标定板相对于相机X我们要求解的手眼变换矩阵相机坐标系与机械臂坐标系的桥梁方程的含义从机械臂视角看到的运动A经过翻译字典X后应该等于相机视角看到的运动B。求解方法至少需要3 组以上不同位姿的 (A, B) 数据对通过 OpenCV 的calibrateHandEye()即可求解 X。数据越多、位姿越多样标定越准。四、眼在手外标定流程1. 固定相机位置将标定板放在工作台上 2. 控制机械臂移动到多个不同位姿每个位姿 - 记录机械臂末端位姿关节角度→基座坐标系下的变换矩阵 - 同步拍摄标定板图像 3. 对每张图像提取标定板角点用 solvePnP 得到标定板→相机变换 4. 计算相邻位姿之间的 A机械臂运动和 B标定板在相机中的运动 5. 调用 calibrateHandEye() 求解 X相机→基座变换矩阵五、眼在手上标定流程1. 将相机安装在机械臂末端标定板固定在工作台 2. 控制机械臂移动到多个不同位姿每个位姿 - 记录末端位姿相对于基座的变换矩阵 - 同步拍摄标定板图像 3. 对每张图像提取角点solvePnP 得到标定板→相机变换 4. 计算相邻位姿的 A 和 B 5. 调用 calibrateHandEye() 求解 X相机→末端变换矩阵注意区别眼在手外求的是相机→基座的关系眼在手上求的是相机→末端的关系。参数传入方式不同。六、OpenCV 手眼标定 APIcalibrateHandEye()cv2.calibrateHandEye(R_gripper2base,# 末端→基座旋转矩阵列表眼在手外或末端→基座眼在手上t_gripper2base,# 末端→基座平移向量列表R_target2cam,# 标定板→相机旋转矩阵列表t_target2cam,# 标定板→相机平移向量列表R_cam2gripper,# 输出相机→末端旋转眼在手上t_cam2gripper,# 输出相机→末端平移眼在手上methodcv2.CALIB_HAND_EYE_TSAI# 求解方法)关键参数说明眼在手上R_cam2gripper输出的是相机→末端变换眼在手外同样的函数但你需要把输入中的R_gripper2base换成基座→末端的逆输出的R_cam2gripper实际对应相机→基座OpenCV 提供多种求解方法TSAI、PARK、HORAUD、ANDREFF、DANIILIDIS。一般用TSAI方法即可经典且稳定。七、标定板选择标定板类型优点缺点棋盘格最经典OpenCV原生支持制作简单角点检测受光照影响圆点阵列精度更高圆心定位更稳定OpenCV 支持不如棋盘格完善ArUco标记单标记即可定位快速便捷精度略低标记需足够大建议入门先用棋盘格精度要求高换圆点阵列快速原型用ArUco。八、标定数据采集注意事项位姿多样性是标定质量的关键旋转范围机械臂末端至少覆盖 3 个不同旋转方向避免只在同一平面运动位置分布标定板在相机视野中的位置要多变不要都集中在中心数据量至少 15~20 组位姿数据越多越稳定避免共面所有标定板位置如果近似在同一平面方程会退化求解不稳定同步采集机械臂到位后停稳再拍照避免运动模糊九、完整手眼标定代码Python OpenCVimportcv2importnumpyasnp# 眼在手上标定 # 假设已采集数据R_gripper2base, t_gripper2base, R_target2cam, t_target2cam# 这些数据来自机械臂位姿记录和 solvePnP 结果R_gripper2base_list[]# 末端→基座 旋转矩阵t_gripper2base_list[]# 末端→基座 平移向量R_target2cam_list[]# 标定板→相机 旋转矩阵t_target2cam_list[]# 标定板→相机 平移向量defcollect_calib_data(robot_poses,images,camera_mtx,dist_coeffs,board_size(9,6),square_size25.0):采集标定数据机械臂位姿 solvePnPobjpnp.zeros((board_size[0]*board_size[1],3),np.float32)objp[:,:2]np.mgrid[0:board_size[0],0:board_size[1]].T.reshape(-1,2)*square_sizeforpose,img_pathinzip(robot_poses,images):# 机械臂位姿 → 变换矩阵根据你的机器人SDK获取R_gb,t_gbpose_to_transform(pose)# 自行实现R_gripper2base_list.append(R_gb)t_gripper2base_list.append(t_gb)# 图像 → solvePnPimgcv2.imread(img_path)graycv2.cvtColor(img,cv2.COLOR_BGR2GRAY)ret,cornerscv2.findChessboardCorners(gray,board_size,None)ifnotret:continuecorners2cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),(cv2.TERM_CRITERIA_EPScv2.TERM_CRITERIA_MAX_ITER,30,0.001))success,rvec,tveccv2.solvePnP(objp,corners2,camera_mtx,dist_coeffs)ifsuccess:R_tc,_cv2.Rodrigues(rvec)R_target2cam_list.append(R_tc)t_target2cam_list.append(tvec)# 执行手眼标定collect_calib_data(robot_poses,images,camera_mtx,dist_coeffs)R_cam2grippernp.zeros((3,3))t_cam2grippernp.zeros((3,1))cv2.calibrateHandEye(R_gripper2baseR_gripper2base_list,t_gripper2baset_gripper2base_list,R_target2camR_target2cam_list,t_target2camt_target2cam_list,R_cam2gripperR_cam2gripper,t_cam2grippert_cam2gripper,methodcv2.CALIB_HAND_EYE_TSAI)print(手眼标定结果相机→末端)print(旋转矩阵:\n,R_cam2gripper)print(平移向量:\n,t_cam2gripper.flatten())十、标定精度验证方法标定完成后务必验证视觉验证用相机检测已知位置物体通过标定矩阵转换到机械臂坐标与实际物理坐标对比误差应在 ±2mm 以内运动验证控制机械臂移动到视觉计算出的目标位置观察末端是否准确到达物体上方多位置验证在工作空间不同区域测试确保标定不是局部有效# 验证示例将像素坐标转换到机械臂坐标defpixel_to_robot(u,v,z_depth,camera_mtx,R_cam2gripper,t_cam2gripper):像素坐标 → 机械臂基座坐标眼在手上# 像素 → 相机3D坐标fx,fycamera_mtx[0,0],camera_mtx[1,1]cx,cycamera_mtx[0,2],camera_mtx[1,2]x_cam(u-cx)*z_depth/fx y_cam(v-cy)*z_depth/fy z_camz_depth p_camnp.array([x_cam,y_cam,z_cam])# 相机坐标 → 末端坐标p_gripperR_cam2gripper p_camt_cam2gripper.flatten()# 末端坐标 → 基座坐标需要当前末端位姿# p_base R_gripper2base p_gripper t_gripper2basereturnp_gripper十一、常见标定失败原因排查问题原因解决方法标定结果偏差大位姿数据量不足或缺乏多样性增加采集组数覆盖不同旋转和位置平移向量异常数值过大机械臂位姿单位错误mm vs m统一单位为毫米每次标定结果不一致标定板检测角点不稳定改善光照使用高分辨率图像旋转矩阵不正交数据共面或近似共面避免所有位姿在同一平面眼在手外结果明显偏输入位姿方向搞反了确认是末端→基座还是基座→末端精度只在工作空间中心有效标定数据覆盖范围不够在边缘区域也采集标定数据手眼标定是机械臂视觉抓取的地基地基不稳上层再华丽也白搭。耐心采集、认真验证后续的抓取精度才有保障。