当前位置: 首页 > news >正文

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)的姿态来计算基座相对于世界的姿态以及末端执行器相对于相机的姿态。

函数原型

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。

代码示例


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

运行结果

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]
http://www.lryc.cn/news/501440.html

相关文章:

  • 计算机网络ENSP课设--三层架构企业网络
  • 【openwrt】openwrt-21.02 基于IP地址使用ipset实现策略路由操作说明
  • Git:常用命令
  • 【2025最新版】搭建个人博客教程
  • 微信小程序实现联动删除输入验证码框
  • 数据库中decimal、float 和 double区别
  • 网络编程01
  • el-dialog修改其样式不生效加deep也没用
  • 三天精通一算法之快速排序
  • 互联网、物联网的相关标准
  • Linux题库及答案
  • Android 镜像模式和扩展模式区别探讨-Android14
  • 深度学习笔记之BERT(五)TinyBERT
  • 【时间序列预测】基于PyTorch实现CNN_BiLSTM算法
  • 联想Y7000 2024版本笔记本 RTX4060安装ubuntu22.04双系统及深度学习环境配置
  • VuePress学习
  • 一次“okhttp访问间隔60秒,提示unexpected end of stream“的问题排查过程
  • SQL最佳实践:避免使用COUNT=0
  • PG与ORACLE的差距
  • 树莓派3B+驱动开发(2)- LED驱动(传统模式)
  • 超详细搭建PhpStorm+PhpStudy开发环境
  • 分析比对vuex和store模式
  • C# 网络编程--基础核心内容
  • 【C++游戏程序】easyX图形库还原游戏《贪吃蛇大作战》(三)
  • uni-app H5端使用注意事项 【跨端开发系列】
  • SpringBoot中的@Configuration注解
  • 十二、路由、生命周期函数
  • 【蓝桥杯每日一题】X 进制减法
  • 《蓝桥杯比赛规划》
  • C++算法练习day70——53.最大子序和