OpenCV相机标定与3D重建(10)眼标定函数calibrateHandEye()的使用

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

计算手眼标定: 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

这个问题也被称为求解 AX=XB 方程:

对于 eye-in-hand 配置

对于 eye-to-hand 配置

注意

更多信息可以在该网站上找到。

至少需要两个具有非平行旋转轴的运动来确定手眼变换。因此,至少需要 3 个不同的姿态,但强烈建议使用更多的姿态。

函数原型

cpp 复制代码
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。

代码示例

cpp 复制代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>

using 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;
}

运行结果

bash 复制代码
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]
相关推荐
xian_wwq5 小时前
【学习笔记】倾斜摄影、高斯泼溅(3DGS)、点云与数字孪生“族谱”全盘点
笔记·学习·3d
AI视觉网奇5 小时前
stl转glb glb缩放
开发语言·3d
七77.6 小时前
【3D 场景生成】WorldGen: From Text to Traversable and Interactive 3D Worlds
3d·世界模型
文创工作室6 小时前
2024年Adobe Substance 3D Designer
3d·adobe
远离UE46 小时前
3D SDF 多光源 阴影 的不同尝试
3d
人工智能培训6 小时前
用知识图谱重构搜索引擎
大数据·人工智能·3d·重构·知识图谱·agent
FII工业富联科技服务7 小时前
AI+3D世界模型:重构园区安防的“可感知、可推演、可进化”
大数据·人工智能·3d·ai·制造
_李小白21 小时前
【android opencv学习笔记】Day 32:直线检测之霍夫变换
android·opencv·学习
HyperAI超神经1 天前
深度估计准确率冲上0.9,Meta提出VLM³,论证视觉模型天生会学3D,以Qwen3-VL-4B为基础实现多任务的统一建模
人工智能·3d·大模型·多模态·空间推理·3d感知·3d理解
ZK_H1 天前
3D NAND Flash手册阅读指南
3d