OpenCV相机标定与3D重建(11)机器人世界手眼标定函数calibrateRobotWorldHandEye()的使用

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

算法描述

计算机器人世界/手眼标定: w T b _{}^{w}\textrm{T}_b wTb 和 c T g _{}^{c}\textrm{T}_g cTg。

cv::calibrateRobotWorldHandEye 是 OpenCV 中用于机器人世界手眼标定的函数。该函数通过已知的世界坐标系(world)、相机坐标系(cam)、基座坐标系(base)和平板坐标系(gripper)的姿态来计算基座相对于世界的姿态以及末端执行器相对于相机的姿态。

函数原型

cpp 复制代码
void cv::calibrateRobotWorldHandEye
(
	InputArrayOfArrays 	R_world2cam,
	InputArrayOfArrays 	t_world2cam,
	InputArrayOfArrays 	R_base2gripper,
	InputArrayOfArrays 	t_base2gripper,
	OutputArray 	R_base2world,
	OutputArray 	t_base2world,
	OutputArray 	R_gripper2cam,
	OutputArray 	t_gripper2cam,
	RobotWorldHandEyeCalibrationMethod 	method = CALIB_ROBOT_WORLD_HAND_EYE_SHAH 
)	

参数

  • 参数R_world2cam: 从世界坐标系(world)到相机坐标系(camera)的齐次矩阵中提取的旋转部分 (cTw)。这是一个包含所有从世界坐标系到相机坐标系变换的旋转矩阵 (3x3) 或旋转向量 (3x1) 的向量 (vector)。
  • 参数t_world2cam: 从世界坐标系(world)到相机坐标系(camera)的齐次矩阵中提取的平移部分 (cTw)。这是一个包含所有从世界坐标系到相机坐标系变换的平移向量 (3x1) 的向量 (vector)。
  • 参数R_base2gripper: 从机器人基座坐标系(base)到末端执行器坐标系(gripper)的齐次矩阵中提取的旋转部分 (gTb)。这是一个包含所有从机器人基座坐标系到末端执行器坐标系变换的旋转矩阵 (3x3) 或旋转向量 (3x1) 的向量 (vector)。
  • 参数t_base2gripper: 从机器人基座坐标系(base)到末端执行器坐标系(gripper)的齐次矩阵中提取的平移部分 (gTb)。这是一个包含所有从机器人基座坐标系到末端执行器坐标系变换的平移向量 (3x1) 的向量 (vector)。
  • 参数R_base2world: 估计的从机器人基座坐标系(base)到世界坐标系(world)的齐次矩阵中提取的旋转部分 (wTb),即 (3x3) 旋转矩阵。
  • 参数t_base2world: 估计的从机器人基座坐标系(base)到世界坐标系(world)的齐次矩阵中提取的平移部分 (wTb),即 (3x1) 平移向量。
  • 参数R_gripper2cam: 估计的从末端执行器坐标系(gripper)到相机坐标系(camera)的齐次矩阵中提取的旋转部分 (cTg),即 (3x3) 旋转矩阵。
  • 参数t_gripper2cam: 估计的从末端执行器坐标系(gripper)到相机坐标系(camera)的齐次矩阵中提取的平移部分 (cTg),即 (3x1) 平移向量。
  • 参数method: 实现的机器人世界/手眼标定方法之一,参见 cv::RobotWorldHandEyeCalibrationMethod。

代码示例

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

using namespace cv;
using namespace std;

int main()
{
    // 假设我们有四组数据,分别对应不同的抓取位置
    int num_poses = 4;

    // 从 world 到 cam 的旋转矩阵和位移向量
    vector< Mat > R_world2cam( num_poses );
    vector< Mat > t_world2cam( num_poses );

    // 从 base 到 gripper 的旋转矩阵和位移向量
    vector< Mat > R_base2gripper( num_poses );
    vector< Mat > t_base2gripper( num_poses );

    // 初始化示例数据
    R_world2cam[ 0 ] = ( Mat_< double >( 3, 3 ) << 1, 0, 0, 0, 1, 0, 0, 0, 1 );
    t_world2cam[ 0 ] = ( Mat_< double >( 3, 1 ) << 0.1, 0.2, 0.3 );

    R_world2cam[ 1 ] = ( Mat_< double >( 3, 3 ) << 0, -1, 0, 1, 0, 0, 0, 0, 1 );
    t_world2cam[ 1 ] = ( Mat_< double >( 3, 1 ) << 0.4, 0.5, 0.6 );

    R_world2cam[ 2 ] = ( Mat_< double >( 3, 3 ) << 0, 0, -1, 0, 1, 0, 1, 0, 0 );
    t_world2cam[ 2 ] = ( Mat_< double >( 3, 1 ) << 0.7, 0.8, 0.9 );

    R_world2cam[ 3 ] = ( Mat_< double >( 3, 3 ) << 0, 0, 1, 0, 1, 0, -1, 0, 0 );
    t_world2cam[ 3 ] = ( Mat_< double >( 3, 1 ) << 1.0, 1.1, 1.2 );

    R_base2gripper[ 0 ] = ( Mat_< double >( 3, 3 ) << 1, 0, 0, 0, 1, 0, 0, 0, 1 );
    t_base2gripper[ 0 ] = ( Mat_< double >( 3, 1 ) << 0.3, 0.4, 0.5 );

    R_base2gripper[ 1 ] = ( Mat_< double >( 3, 3 ) << 0, -1, 0, 1, 0, 0, 0, 0, 1 );
    t_base2gripper[ 1 ] = ( Mat_< double >( 3, 1 ) << 0.6, 0.7, 0.8 );

    R_base2gripper[ 2 ] = ( Mat_< double >( 3, 3 ) << 0, 0, -1, 0, 1, 0, 1, 0, 0 );
    t_base2gripper[ 2 ] = ( Mat_< double >( 3, 1 ) << 0.9, 1.0, 1.1 );

    R_base2gripper[ 3 ] = ( Mat_< double >( 3, 3 ) << 0, 0, 1, 0, 1, 0, -1, 0, 0 );
    t_base2gripper[ 3 ] = ( Mat_< double >( 3, 1 ) << 1.2, 1.3, 1.4 );

    // 输出变量
    Mat R_base2world, t_base2world;
    Mat R_gripper2cam, t_gripper2cam;

    // 执行机器人世界手眼标定
    calibrateRobotWorldHandEye( R_world2cam, t_world2cam, R_base2gripper, t_base2gripper, R_base2world, t_base2world, R_gripper2cam, t_gripper2cam, CALIB_ROBOT_WORLD_HAND_EYE_SHAH );

    // 输出结果
    cout << "Rotation matrix from base to world:\n" << R_base2world << endl;
    cout << "Translation vector from base to world:\n" << t_base2world << endl;
    cout << "Rotation matrix from gripper to camera:\n" << R_gripper2cam << endl;
    cout << "Translation vector from gripper to camera:\n" << t_gripper2cam << endl;

    return 0;
}

运行结果

bash 复制代码
Rotation matrix from base to world:
[1, 0, 0;
 0, 1, 0;
 0, 0, 1]
Translation vector from base to world:
[4.163336342344337e-17;
 9.71445146547012e-17;
 1.387778780781446e-17]
Rotation matrix from gripper to camera:
[1, 0, 0;
 0, 1, 0;
 0, 0, 1]
Translation vector from gripper to camera:
[-0.2;
 -0.1999999999999999;
 -0.2000000000000001]
相关推荐
云飞云共享云桌面20 小时前
智能装备工厂研发部门多设计师共享一台SolidWorks服务器做设备装配建模
运维·服务器·网络·人工智能·3d·自动化·制造
Yyq1302086968221 小时前
3D磁编码应用-带屏按钮-KTH5701
3d
小雨爱测21 小时前
3ds Max 入门到进阶:建模、材质、灯光与渲染全流程指南
3d·材质
FOORIR 客流统计21 小时前
AI 3D客流统计技术拆解:从深度数据到越线计数
人工智能·3d
Jmyd012321 小时前
从 0.02 毫米到 8192 像素:线上 3D 展览的数据链路怎么跑通?
3d·三维数字化·3d展览
OpenVINO 中文社区21 小时前
英特尔 × ADG:从 Agent 落地到 3DGS 重建,GDPS 2026 空间计算实战工作坊技术复盘
人工智能·3d·空间计算
云飞云共享云桌面2 天前
机械制造研发部门:一台SolidWorks云主机替代 10 台传统图形工作站
运维·服务器·网络·3d·自动化·制造
云飞云共享云桌面2 天前
非标自动化工厂研发部门怎么实现一台服务器带10个SolidWorks设计并发
运维·服务器·人工智能·3d·自动化·电脑·制造
坚定信念,勇往无前2 天前
unity-UMA 的完整落地方案(捏脸,换装)
3d
3D阅阅三维模型轻量化及浏览平台2 天前
机加工 / 模具 / 钣金现场审图痛点:不用 UG/SW,手机、网页直接打开 STEP、DXF 轻量化审图工具(3D 阅阅)
人工智能·3d·机加工·钣金加工·模具加工