3D相机与机械臂手眼标定流程

1.采集n组点云数据,将第一组点云命名为(点云target)基准点云

   这些数据可以通过3D相机采集得到,然后通过一些处理方法(如去噪、滤波等)进一步优化。

2.采集n组点云的同时记录n组机械臂位姿,同样将第一组位姿设为基准位姿(机械臂target)

3.将获取的n组机械臂位姿由欧拉角转换为4×4变换矩阵

 (x,y,z,rx,ry,rz 变成 4×4变换矩阵)

4.通过点云配准方法如icp等计算出其余点云(source)相对于第一组点云(target)的变换矩阵(B)

 (ICP配准后返回的结果为B矩阵)

5.通过A=Tpose1^-1 *Tpose2 计算出其余机械臂位姿相对于第一组机械臂位姿的变换矩阵(A)

(采集第一帧target点云时机械臂的位姿为Pose1,剩下的位姿以此为Pose2.3.4.....;按照  A=Tpose1^-1 *Tpose2可以计算出A)

6.通过西尔维斯方程( AX=XB ),计算出手眼变换矩阵X

//================================更新===================================

求得手眼变换矩阵X后,就可以将3D相机坐标系下的点云数据转换到机械臂坐标系下,转换的过程通过矩阵的乘法来实现,步骤如下:

1.需要将点云数据(x,y,z)转化为齐次坐标(齐次坐标是表达空间点的方式),通过转换将点云数     据变成(x,y,z,1)

2.将首演变换矩阵X(4x4)乘以每个点的齐次坐标(4x1) ->   [X,Y,Z,W] = X*[x,y,z,1]

3.最后需要将结果转换为笛卡尔坐标,通过将每个坐标除以W,最终得到机械臂坐标系下的坐标(x',y',z')  ->   x' = X / W、 y' = Y / W、 z' = Z / W

//==============================更新=====================================

上述已经获得了手眼变换矩阵X,也就是相机和机械臂末端的位姿转换关系,那么如何利用X获取目标在相机坐标系下的坐标转换为机械臂基坐标系下的坐标呢?

要获得物体在机械臂基座表系下的坐标需要进行以下步骤,实现公式如下:

T_{target}^{base} =T_{end}^{base}T_{camera}^{end}T_{target}^{camera}

其中,T_{camera}^{end}是4×4手眼变换矩阵X,T_{target}^{camera} 是目标在相机坐标系下的坐标,T_{end}^{base}是机器人示教器上读取的坐标,乘法其实就是坐标转化变换。

//==============================待更新====================================

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是一段深度相机机械手眼标定的程序: ```python import numpy as np import cv2 import glob # 初始化机械和深度相机的变量 robot_pose = [] depth_pose = [] robot_pose_inv = [] depth_pose_inv = [] # 读取机械和深度相机标定图像 robot_images = sorted(glob.glob('robot_calib_images/*.jpg')) depth_images = sorted(glob.glob('depth_calib_images/*.png')) # 从标定图像中提取角点 robot_criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) depth_criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) robot_objp = np.zeros((6*7,3), np.float32) robot_objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2) depth_objp = np.zeros((6*7,3), np.float32) depth_objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2) robot_objpoints = [] depth_objpoints = [] robot_imgpoints = [] depth_imgpoints = [] for robot_img, depth_img in zip(robot_images, depth_images): robot_img = cv2.imread(robot_img) depth_img = cv2.imread(depth_img, cv2.IMREAD_UNCHANGED) gray_robot = cv2.cvtColor(robot_img, cv2.COLOR_BGR2GRAY) gray_depth = cv2.cvtColor(depth_img, cv2.COLOR_BGR2GRAY) ret_robot, corners_robot = cv2.findChessboardCorners(gray_robot, (7,6), None) ret_depth, corners_depth = cv2.findChessboardCorners(gray_depth, (7,6), None) if ret_robot and ret_depth: robot_objpoints.append(robot_objp) depth_objpoints.append(depth_objp) corners_robot = cv2.cornerSubPix(gray_robot,corners_robot,(11,11),(-1,-1),robot_criteria) corners_depth = cv2.cornerSubPix(gray_depth,corners_depth,(11,11),(-1,-1),depth_criteria) robot_imgpoints.append(corners_robot) depth_imgpoints.append(corners_depth) # 进行机械和深度相机手眼标定 retval, robot_matrix, robot_distCoeffs, robot_rvecs, robot_tvecs = cv2.calibrateCamera(robot_objpoints, robot_imgpoints, gray_robot.shape[::-1], None, None) retval, depth_matrix, depth_distCoeffs, depth_rvecs, depth_tvecs = cv2.calibrateCamera(depth_objpoints, depth_imgpoints, gray_depth.shape[::-1], None, None) for robot_rvec, robot_tvec, depth_rvec, depth_tvec in zip(robot_rvecs, robot_tvecs, depth_rvecs, depth_tvecs): robot_rmat, _ = cv2.Rodrigues(robot_rvec) depth_rmat, _ = cv2.Rodrigues(depth_rvec) robot_pose.append(np.hstack((robot_rmat, robot_tvec))) depth_pose.append(np.hstack((depth_rmat, depth_tvec))) robot_pose_inv.append(np.hstack((robot_rmat.T, -robot_rmat.T.dot(robot_tvec)))) depth_pose_inv.append(np.hstack((depth_rmat.T, -depth_rmat.T.dot(depth_tvec)))) robot_pose = np.array(robot_pose) depth_pose = np.array(depth_pose) robot_pose_inv = np.array(robot_pose_inv) depth_pose_inv = np.array(depth_pose_inv) H = np.zeros((3,3)) for i in range(len(robot_pose)): H += np.dot(robot_pose[i], depth_pose_inv[i]) U, S, V = np.linalg.svd(H) R = np.dot(U, V) T = np.dot(depth_pose.mean(axis=0)[:3], R.T) - np.dot(robot_pose.mean(axis=0)[:3], R.T) # 输出标定结果 print('Robot camera matrix:\n', robot_matrix) print('Robot distortion coefficients:\n', robot_distCoeffs) print('Depth camera matrix:\n', depth_matrix) print('Depth distortion coefficients:\n', depth_distCoeffs) print('Rotation matrix:\n', R) print('Translation vector:\n', T) ``` 这段程序首先读取了机械和深度相机标定图像,并从中提取出角点。然后,使用这些角点进行机械和深度相机相机内参数标定,得到了相机矩阵和畸变系数。接着,使用这些角点进行机械和深度相机手眼标定,得到了机械和深度相机之间的转换矩阵。最后,使用SVD方法求解旋转矩阵和平移向量,输出标定结果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值