给公司创建网站流程,seo是指通过,有没有代做模型的网站,网络正能量你懂我意思的操作系统#xff1a;ubuntu22.04 OpenCV版本#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言#xff1a;C11
算法描述
计算手眼标定#xff1a; g T c _{}^{g}\textrm{T}_c gTc cv::calibrateHandEye 是 OpenCV 中用于手眼标定的函数。该函数通过已知的机器人… 操作系统ubuntu22.04 OpenCV版本OpenCV4.9 IDE:Visual Studio Code 编程语言C11
算法描述
计算手眼标定 g T c _{}^{g}\textrm{T}_c gTc cv::calibrateHandEye 是 OpenCV 中用于手眼标定的函数。该函数通过已知的机器人末端执行器gripper相对于基座base和平板target相对于相机cam的姿态来计算相机相对于末端执行器的姿态。
该函数使用各种方法进行手眼标定。一种方法包括先估计旋转再估计平移可分离解法并且实现了以下方法 R. Tsai, R. Lenz A New Technique for Fully Autonomous and Efficient 3D Robotics Hand/Eye Calibration [269] F. Park, B. Martin Robot Sensor Calibration: Solving AX XB on the Euclidean Group [208] R. Horaud, F. Dornaika Hand-Eye Calibration [124] 另一种方法包括同时估计旋转和平移同时解法并且实现了以下方法 N. Andreff, R. Horaud, B. Espiau On-line Hand-Eye Calibration [12] K. Daniilidis Hand-Eye Calibration Using Dual Quaternions [63] 下图描述了手眼标定问题其中需要估计安装在机器人末端执行器上的相机“eye”相对于末端执行器“hand”的变换。这种配置称为 eye-in-hand。
eye-to-hand 配置由一个静态相机观察安装在机器人末端执行器上的校准图案组成。然后可以通过输入合适的变换矩阵到函数中来估计从相机到机器人基座坐标系的变换见下方说明。 标定过程如下
使用静态校准图案来估计目标坐标系和相机坐标系之间的变换。 移动机器人末端执行器以获取多个姿态。 对于每个姿态记录从末端执行器坐标系到机器人基座坐标系的齐次变换矩阵例如使用机器人的运动学。 [ X b Y b Z b 1 ] [ b R g b t g 0 1 × 3 1 ] [ X g Y g Z g 1 ] \begin{bmatrix} X_b\\ Y_b\\ Z_b\\ 1 \end{bmatrix} \begin{bmatrix} _{}^{b}\textrm{R}_g _{}^{b}\textrm{t}_g \\ 0_{1 \times 3} 1 \end{bmatrix} \begin{bmatrix} X_g\\ Y_g\\ Z_g\\ 1 \end{bmatrix} XbYbZb1 [bRg01×3btg1] XgYgZg1 对于每个姿态记录从校准目标坐标系到相机坐标系的齐次变换矩阵例如使用基于2D-3D点对应关系的姿态估计方法PnP。 [ X c Y c Z c 1 ] [ c R t c t t 0 1 × 3 1 ] [ X t Y t Z t 1 ] \begin{bmatrix} X_c\\ Y_c\\ Z_c\\ 1 \end{bmatrix} \begin{bmatrix} _{}^{c}\textrm{R}_t _{}^{c}\textrm{t}_t \\ 0_{1 \times 3} 1 \end{bmatrix} \begin{bmatrix} X_t\\ Y_t\\ Z_t\\ 1 \end{bmatrix} XcYcZc1 [cRt01×3ctt1] XtYtZt1 手眼标定过程返回以下齐次变换矩阵 [ X g Y g Z g 1 ] [ g R c g t c 0 1 × 3 1 ] [ X c Y c Z c 1 ] \begin{bmatrix} X_g\\ Y_g\\ Z_g\\ 1 \end{bmatrix} \begin{bmatrix} _{}^{g}\textrm{R}_c _{}^{g}\textrm{t}_c \\ 0_{1 \times 3} 1 \end{bmatrix} \begin{bmatrix} X_c\\ Y_c\\ Z_c\\ 1 \end{bmatrix} XgYgZg1 [gRc01×3gtc1] XcYcZc1 这个问题也被称为求解 AXXB 方程
对于 eye-in-hand 配置
对于 eye-to-hand 配置 注意 更多信息可以在该网站上找到。 至少需要两个具有非平行旋转轴的运动来确定手眼变换。因此至少需要 3 个不同的姿态但强烈建议使用更多的姿态。
函数原型
void cv::calibrateHandEye
(InputArrayOfArrays R_gripper2base,InputArrayOfArrays t_gripper2base,InputArrayOfArrays R_target2cam,InputArrayOfArrays t_target2cam,OutputArray R_cam2gripper,OutputArray t_cam2gripper,HandEyeCalibrationMethod method CALIB_HAND_EYE_TSAI
) 参数
参数[in] R_gripper2base: 从齐次矩阵中提取的旋转部分该矩阵将一个用末端执行器坐标系表示的点变换到机器人基座坐标系 ( b T g _{}^{b}\textrm{T}_g bTg)。这是一个包含所有从末端执行器坐标系到机器人基座坐标系变换的旋转矩阵3x3或旋转向量3x1的向量vector。参数[in] t_gripper2base: 从齐次矩阵中提取的平移部分该矩阵将一个用末端执行器坐标系表示的点变换到机器人基座坐标系 ( b T g _{}^{b}\textrm{T}_g bTg)。这是一个包含所有从末端执行器坐标系到机器人基座坐标系变换的平移向量3x1的向量vector。参数[in] R_target2cam: 从齐次矩阵中提取的旋转部分该矩阵将一个用校准目标坐标系表示的点变换到相机坐标系 ( c T t _{}^{c}\textrm{T}_t cTt)。这是一个包含所有从校准目标坐标系到相机坐标系变换的旋转矩阵3x3或旋转向量3x1的向量vector。参数[in] t_target2cam: 从齐次矩阵中提取的平移部分该矩阵将一个用校准目标坐标系表示的点变换到相机坐标系 ( c T t _{}^{c}\textrm{T}_t cTt)。这是一个包含所有从校准目标坐标系到相机坐标系变换的平移向量3x1的向量vector。参数[out] R_cam2gripper: 估计的从齐次矩阵中提取的旋转部分该矩阵将一个用相机坐标系表示的点变换到末端执行器坐标系 ( g T c _{}^{g}\textrm{T}_c gTc)。这是一个 3x3 的旋转矩阵。参数[out] t_cam2gripper: 估计的从齐次矩阵中提取的平移部分该矩阵将一个用相机坐标系表示的点变换到末端执行器坐标系 ( g T c _{}^{g}\textrm{T}_c gTc)。这是一个 3x1 的平移向量。参数[in] method: 实现的手眼标定方法之一见 cv::HandEyeCalibrationMethod。
代码示例 #include iostream
#include opencv2/opencv.hpp
#include vectorusing namespace cv;
using namespace std;int main()
{// 假设我们有四组数据分别对应不同的抓取位置int num_poses 4;// 从 gripper 到 base 的旋转矩阵和位移向量vector Mat R_gripper2base( num_poses );vector Mat t_gripper2base( num_poses );// 从 target 到 cam 的旋转矩阵和位移向量vector Mat R_target2cam( num_poses );vector Mat t_target2cam( num_poses );// 初始化示例数据R_gripper2base[ 0 ] ( Mat_ double ( 3, 3 ) 1, 0, 0, 0, 1, 0, 0, 0, 1 );t_gripper2base[ 0 ] ( Mat_ double ( 3, 1 ) 0.1, 0.2, 0.3 );R_gripper2base[ 1 ] ( Mat_ double ( 3, 3 ) 0, -1, 0, 1, 0, 0, 0, 0, 1 );t_gripper2base[ 1 ] ( Mat_ double ( 3, 1 ) 0.4, 0.5, 0.6 );R_gripper2base[ 2 ] ( Mat_ double ( 3, 3 ) 0, 0, -1, 0, 1, 0, 1, 0, 0 );t_gripper2base[ 2 ] ( Mat_ double ( 3, 1 ) 0.7, 0.8, 0.9 );R_gripper2base[ 3 ] ( Mat_ double ( 3, 3 ) 0, 0, 1, 0, 1, 0, -1, 0, 0 );t_gripper2base[ 3 ] ( Mat_ double ( 3, 1 ) 1.0, 1.1, 1.2 );R_target2cam[ 0 ] ( Mat_ double ( 3, 3 ) 1, 0, 0, 0, 1, 0, 0, 0, 1 );t_target2cam[ 0 ] ( Mat_ double ( 3, 1 ) 0.3, 0.4, 0.5 );R_target2cam[ 1 ] ( Mat_ double ( 3, 3 ) 0, -1, 0, 1, 0, 0, 0, 0, 1 );t_target2cam[ 1 ] ( Mat_ double ( 3, 1 ) 0.6, 0.7, 0.8 );R_target2cam[ 2 ] ( Mat_ double ( 3, 3 ) 0, 0, -1, 0, 1, 0, 1, 0, 0 );t_target2cam[ 2 ] ( Mat_ double ( 3, 1 ) 0.9, 1.0, 1.1 );R_target2cam[ 3 ] ( Mat_ double ( 3, 3 ) 0, 0, 1, 0, 1, 0, -1, 0, 0 );t_target2cam[ 3 ] ( Mat_ double ( 3, 1 ) 1.2, 1.3, 1.4 );// 输出变量Mat R_cam2gripper, t_cam2gripper;// 执行手眼标定calibrateHandEye( R_gripper2base, t_gripper2base, R_target2cam, t_target2cam, R_cam2gripper, t_cam2gripper, CALIB_HAND_EYE_TSAI );// 输出结果cout Rotation matrix from camera to gripper:\n R_cam2gripper endl;cout Translation vector from camera to gripper:\n t_cam2gripper endl;return 0;
}
运行结果
Rotation matrix from camera to gripper:
[0.7999999999999999, 0.6000000000000001, 0;-0.6000000000000001, 0.7999999999999999, 0;0, 0, 1]
Translation vector from camera to gripper:
[-0.4380000000000001;-0.6659999999999999;-0.63]