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 个不同的姿态,但强烈建议使用更多的姿态。

函数原型

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

运行结果

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]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/63684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day08 接口测试(4)知识点完结!!

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 1、postman读取外部数据文件&#xff08;参数化&#xff09; 1.1 数据文件简介 1.2 导入外部数据文件 1.2.1 csv文件 1.2.2 导入 json文件 1.3 读取数据文件数据 1.4 案例 1.5 生成测试报告 2、小…

linux 安装 Jenkins 教程

前言 Jenkins 是一个开源的自动化服务器&#xff0c;广泛用于持续集成&#xff08;Continuous Integration&#xff0c;CI&#xff09;和持续交付&#xff08;Continuous Delivery&#xff0c;CD&#xff09;领域。它帮助开发者自动化软件构建、测试、部署等过程&#xff0c;从…

IdentityServer4框架、ASP.NET core Identity

OAuth2.0 IdentityServer4 官网 中文官网 ASP.NET Core Identity提供了一个用来管理和存储用户账户的框架. IdentityServer4是基于ASP.NET Core实现的认证和授权框架&#xff0c;是对OpenID Connect和OAuth 2.0协议的实现。 IdentityServer是一个中间件,它可以添加符合OpenID…

ZZCMS2023存在跨站脚本漏洞(CNVD-2024-44822、CVE-2024-44818)

ZZCMS是一款用于搭建招商网站的CMS系统&#xff0c;由PHP语言开发&#xff0c;可快速搭建&#xff1a;医药招商、保健品招商、化妆品招商、农资招商、孕婴童招商、酒类副食类等招商网站。 国家信息安全漏洞共享平台于2024-11-14公布其存在跨站脚本漏洞。 漏洞编号&#xff1a…

使用Kubernetes部署MySQL+WordPress

目录 前提条件 部署MySQL和WordPress 编写yaml文件 应用yaml文件 存在问题及解决方案 创建PV(持久化卷) 创建一个PVC(持久化卷声明) 部署添加PVC 查看PV对应的主机存储 删除资源 查看资源 删除deployment和service 查看主机数据 删除PVC和PV 删除主机数据 前提条…

每日一刷——12.10——学习二叉树解题模式(二)

题目三&#xff1a;填充每个节点的下一个右侧节点指针1 题目描述&#xff1a;116. 填充每个节点的下一个右侧节点指针 - 力扣&#xff08;LeetCode&#xff09; 我的理解&#xff1a; 我的感觉是同父亲还好搞一点&#xff0c;感觉是在遍历到每一个节点的时候&#xff0c;就把…

Spring Cloud Alibaba:一站式微服务解决方案

Spring Cloud Alibaba介绍 在当今的软件开发领域&#xff0c;微服务架构因其灵活性、可扩展性和独立性等优势而备受青睐。Spring Cloud Alibaba 作为一款强大的一站式微服务解决方案&#xff0c;为开发者提供了丰富的工具和组件&#xff0c;帮助他们轻松构建和管理复杂的微服务…

服务器数据恢复—LINUX下各文件系统删除/格式化的数据恢复可行性分析

Linux操作系统是世界上流行的操作系统之一&#xff0c;被广泛用于服务器、个人电脑、移动设备和嵌入式系统。Linux系统下数据被误删除或者误格式化的问题非常普遍。下面北亚企安数据恢复工程师简单聊一下基于linux的文件系统&#xff08;EXT2/EXT3/EXT4/Reiserfs/Xfs&#xff0…

vs打开unity项目 新建文件后无法自动补全

问题 第一次双击c#文件自动打开vs编辑器的时候能自动补全&#xff0c;再一次在unity中新建c#文件后双击打开发现vs不能自动补全了。每次都要重新打开vs编辑器才能自动补全&#xff0c;导致效率很低&#xff0c;后面发现是没有安装扩展&#xff0c;注意扩展和工具的区别。 解决…

网络安全-态势感知

0x00 定义&#xff1a; 态势感知&#xff08;Situation Awareness&#xff0c;SA&#xff09;能够检测出超过20大类的云上安全风险&#xff0c;包括DDoS攻击、暴力破解、Web攻击、后门木马、僵尸主机、异常行为、漏洞攻击、命令与控制等。利用大数据分析技术&#xff0c;态势感…

命令模式的理解和实践

在软件开发中&#xff0c;设计模式是开发者们经过长期实践总结出来的、可复用的解决方案&#xff0c;用于解决常见的设计问题。命令模式&#xff08;Command Pattern&#xff09;是行为型设计模式之一&#xff0c;它通过将一个请求封装成一个对象&#xff0c;从而允许用户用不同…

SpringBoot3整合SpringMVC

一、实现过程: (1).创建程序 (2).引入依赖: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"…

【优选算法篇】剥洋葱式探索:用二分查找精准定位答案(下篇)

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

若依集成更好用的easyexcel

背景 若依使用的是apach poi并在此基础上进行封装apach poi的原生的api是很复杂的&#xff0c;若依简化了了此操作apach poi的上传速率和下载速率都是没有优化的&#xff0c;依赖于文件大小的限制在此前提下&#xff0c;如果没法满足客户的需求&#xff08;超大型文件的上传&am…

在Ubuntu上使用docker compose安装N卡GPU的Ollama服务

在现代计算环境中,利用 GPU 进行计算加速变得越来越重要。下面将讲解如何在Ubuntu上使用docker compose安装N卡GPU的Ollama服务。 1、安装 NVIDIA 容器工具 首先,需要确保你的系统已经安装了 NVIDIA 容器工具 nvidia-container-toolkit。这是让 Docker 容器访问 GPU 的关键…

MySQL语句学习第三篇_数据库

MySQL语句学习第三篇_数据库 专栏记录MySQL的学习&#xff0c;感谢大家观看。 本章的专栏&#x1f4da;➡️MySQL语法学习 本博客前一章节指向➡️MySQL语句学习第二篇 本人的博客➡️:如烟花般绚烂却又稍纵即逝的主页 文章目录 MySQL的基础操作&#xff08;改与查&#xff0…

windows将文件推给Android真机/实机

记录一下 因为以前只试过从真机实机中将文件推给windows 但是从windows只简单复制粘贴的话会一直报错。 1.电脑安装adb 2.手机开启开发者模式 usb调试 3.usb连接选择文件传输 4.推送命令adb push 文件路径 /sdcard/download 步骤1和2和3不作赘述&#xff0c;可以搜相关配置教程…

C语言——验证“哥德巴赫猜想”

问题描述&#xff1a; 验证"哥德巴赫猜想" 任何一个大于2的偶数都可以表示为两个质数之和。例如&#xff0c;4可以表示为22&#xff0c;6可以表示为33&#xff0c;8可以表示为35等 //验证"哥德巴赫猜想" //任何一个大于2的偶数都可以表示为两个质数之和…

利用 360 安全卫士极速版关闭电脑开机自启动软件教程

在使用电脑的过程中&#xff0c;过多的开机自启动软件会严重拖慢电脑的开机速度&#xff0c;影响我们的使用体验。本教程中简鹿办公将详细介绍如何使用 360 安全卫士极速版关闭电脑开机自启动软件&#xff0c;让您的电脑开机更加迅速流畅。 一、打开 360 安全卫士极速版 在电…

分布式搜索引擎之elasticsearch基本使用2

分布式搜索引擎之elasticsearch基本使用2 在分布式搜索引擎之elasticsearch基本使用1中&#xff0c;我们已经导入了大量数据到elasticsearch中&#xff0c;实现了elasticsearch的数据存储功能。但elasticsearch最擅长的还是搜索和数据分析。 所以j接下来&#xff0c;我们研究下…