手眼标定之基本原理

手眼标定之基本原理文章目录一前言二Eye-in-Hand2.1基础知识准备2.2Eye-in-Hand基本原理三跋原文首发于微信公众号【视觉IMAX】。一前言机器人的视觉系统分为固定场景视觉系统和运动的「手-眼」视觉系统。摄像机与机器人的手部末端,构成手眼视觉系统。根据摄像机与机器人相互位置的不同,手眼视觉系统分为Eye-in-Hand系统和Eye-to-Hand系统。Eye-in-Hand…

大家好,又见面了,我是你们的朋友全栈君。

原文首发于微信公众号【3D视觉工坊】。

一 前言

机器人的视觉系统分为固定场景视觉系统和运动的「手-眼」视觉系统。摄像机与机器人的手部末端,构成手眼视觉系统。根据摄像机与机器人相互位置的不同,手眼视觉系统分为Eye-in-Hand系统和Eye-to-Hand系统。Eye-in-Hand系统的摄像机安装在机器人手部末端(end-effector),在机器人工作过程中随机器人一起运动。Eye-to-Hand系统的摄像机安装在机器人本体外的固定位置,在机器人工作工程中不随机器人一起运动。

Eye-in-Hand系统的在工业机器人中应用比较广泛,随着机械手逐渐接近目标,摄像机与目标的距离越来越小,被测物体位置参数的绝对误差会随之降低。在Eye-in-Hand系统中,采用基于图像的视觉控制、基于位置的视觉控制以及结合两者的混合视觉控制,可以快速有效地标定被测物体的坐标。

手眼标定方法通常分为3类:标准手眼标定、基于旋转运动的手眼标定以及在线手眼标定。以上方法是将摄像机标定与手眼标定分开进行,也有的论文采用的是联合标定法。

本文重点讲解Eye-in-Hand的一般方法,重在阐述其基本原理。

二 Eye-in-Hand

2.1 基础知识准备

在研究相机标定时,已较为熟悉,在本公众号「视觉IMAX」里已有几篇文章做过总结,如:
a) 一分钟详解OpenCV之相机标定函数calibrateCamera()
b) 一分钟详解「本质矩阵」推导过程
c) 计算机视觉基本原理——RANSAC
d) 再谈「相机标定」

此处就不详细展开叙述了。

2.2 Eye-in-Hand基本原理

对目标点的空间三维坐标进行变换的过程中,首先遇到的问题是机器人末端关节坐标系与摄像机坐标系之间的位置变换关系,也就是机器人的手眼位置关系,该关系用符号X表示,具体可以用方程AX=XB求解。其中A表示相邻两次运动时机器人末端关节的变换关系;B表示相邻两次运动时摄像机坐标的相对运动。

下面,简单介绍一下本问题模型中为何会引入AX=XB模型。
如图1所示,为眼在手上,也即eye-in-hand。(本篇文章重点讨论的是双目,所以此处仅是为了演示效果图,而非真实的实验场景)。相机固定在机械臂末端,会随着机械臂的运动而运动。

图1 眼在手上


图1 眼在手上

我们会得到一堆坐标系和坐标变换关系:

  • A:机器人末端在机械臂坐标系下的位姿,这其实就是机器人运动学正解的问题。(已知)。

  • B:相机在机器人末端坐标系下的位姿,这个变换是固定的,只要知道这个变换,我们就可以随时计算相机的实际位置,所以这就是我们想求的东西。(未知,待求)

  • C:相机在标定板坐标系下的位姿,这个其实就是求解相机的外参(已知)。

  • D:相机在机器人基坐标系下的位姿。实际使用过程中标定板并不存在,所以这个变换关系我们不关心。

所以,只要我们能计算得到B变换,那么相机在机器人坐标系下的位姿D也就自然得到了。

如图2所示,我们让机械臂运动两个位置,保证这两个位置下都可以看到标定板,然后构建空间变换回路:
图2 机械臂运动到两个位置,构建变换回路

在这里插入图片描述

图3 谷歌学术搜索

在谷歌学术用关键词「AX=XB」搜索便可以得到各种求解办法,见图3所示。

以上图中的几篇论文,都很详细地给出了推导过程,按照它们写程序基本没问题。

这样,我们便有了A、B和C,就能直接求解得到我们想要的手眼标定结果D了。

前面主要是为了理清思路,对于每个部分的细节都给省略掉了,接下来进行详细说明。

1)变换A: 它是机械臂末端在机器人基座坐标系下的位姿,其实就是机器人学里面最基础的运动学正解。如图4所示。
图4 机器人运动学正解模型
用DH矩阵等方法来计算机器人运动学正解。可以参看熊有伦主编的《机器人技术基础》这本书。在实际操作中,根据机器人的示教器读出欧拉角,即可换算出机械手爪坐标系到机械臂基座的转换矩阵。

2)变换C: 它是相机在标定板坐标系下的位姿。其实就是相机的外参。如图5所示,其中的R,T 即为相机在标定板下的位姿。
图5 相机在标定板板坐标系下的位姿
在这里插入图片描述
图6 相机模型

相机模型有了,我们要做的就是先确定内参矩阵,然后根据不同时刻拍摄的标定板图片来求取外参矩阵:也即相机在世界坐标系下的变换关系C

目前来说,要解决这个问题,基本上都是采用张正友老师的方法。这个在之前的相机标定过程中,已经实现。

3)求解AX=XB。

关于这个公式的求解,对应着多种不同的解法,此处推荐一篇文章,如下:

  1. Daniilidis, Konstantinos. “Hand-eye calibration using dual quaternions.” The International Journal of Robotics Research 18.3 (1999): 286-298.

注: 在公众号【视觉IMAX】后台回复「解AX=XB」,即可获得下载上述文章的下载链接。

得到X也即手眼关系,最后得到相机坐标系到机器人基座的坐标变换关系:D=A*X。
式中A代表:机器人手抓到机器人基座坐标变换;X表示相机到机器人手抓的坐标变换。
在这里插入图片描述

以上手眼标定流程,大体可以总结如图7所示:
图7 手眼标定流程示意图

手眼标定的基本原理如上所述,至于正确性,仍需由实验进一步验证。

三 跋

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/131366.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Ubuntu根分区使用Lvm扩容

    Ubuntu根分区使用Lvm扩容ubuntu根分区剩余空间不足,影响工作,因此通过lvm工具对根文件系统进行扩容系统版本:ubuntu-14.04LTS1.使用新硬盘扩展根文件系统 新建一块硬盘并进行分区: fdisk/dev/sde 依次键入n,创建新分区;然后分区类型选择p;其他默认输入即可。 图1:创建新分区 分区创建完成后,修改分区类型为lvm: 图2:修改分区类型 新建的分区类型不能为扩展分区,否则不能更改分区类型,目前还不清楚原因,需要继续查找其他资料,..

    2022年6月20日
    37
  • 编程实现盗版QQ「建议收藏」

    编程实现盗版QQ「建议收藏」源码下载(附件1 )一、思路分析  (一) 数据包的角度 (二) 钩子角度 1. 钩子简介 2. 程序流程 ;二、 实现过程   (一) 定义宏   (二) 枚举进程找到QQ.exe   (三) 枚举所有窗口,找属于QQ.exe的窗口   (四) 获取用户名、密码、登陆按钮的句柄   (五) 创建钩子用的DLL   (六) 安装钩子  一直以来我对盗QQ这种技术都比较的好奇,最近为了练

    2022年7月20日
    14
  • 链表的基本操作_简单链表

    链表的基本操作_简单链表链表的基本操作这里写目录标题链表的基本操作一:单链表的基础知识二:单链表的建立头插法尾插法三:单链表的遍历四:单链表结点数目判断五:单链表的插入链表头插入任意结点插入链表尾部插入六:单链表的删除七:单链表的查询一:单链表的基础知识为什么需要链表?我们在使用数组存放数据是非常方便,但是由于数组的长度是固定的,所以当存储不同的元素数量时,就很容易出现问题。如果向数组中添加的数量大于数组大小时候,信息无法完全被保存。所以我们需要另一种存储方式来存储数据,其中存储的元素的个数不受限制。这种存储方式就是链

    2025年6月20日
    2
  • 动态路由协议及分类

    动态路由协议及分类3 动态路由协议及分类前面已经为大家介绍了路由器对于直连路由的发现过程 以及静态路由的概念和部署要点 对于一个小型网络 静态路由或许已经能够满足需求 但是在大中型网络中 由于网段数量特别多 网络拓扑复杂等原因 仅仅使用静态路由来实现数据互通显然是不太现实的 配置及维护工作量都太大 再者静态路由无法动态地响应网络拓扑变更 此时就需要考虑另一种方案 动态路由协议 DynamicRouti 了 当我们在路由器上激活了动态路由协议后 就相当于激活了路由器的某种能力 路由器之间就

    2025年7月20日
    4
  • ThreadLocal底层原理「建议收藏」

    ThreadLocal底层原理「建议收藏」ThreadLocal作用:提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂性。package com.mupack;public class App{ private String content; public void setContent(String content) { this.content = content; } public Stri

    2022年8月9日
    6
  • SpringCloud(七)—OpenFeign访问带有参数的控制器

    SpringCloud(七)—OpenFeign访问带有参数的控制器

    2020年11月12日
    236

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号