机械臂手眼标定ZED相机——眼在手外python、matlab

news2024/9/22 19:33:46

目录

1.眼在手外原理

2.附上眼在手外求得手眼矩阵的python代码

3.眼在手外标定步骤

1)打印棋盘格

2)得到hand数据

3)得到camera数据

4.运行python得到手眼矩阵



1.眼在手外原理

 

眼在手外所求的手眼矩阵是基坐标到相机的转换矩阵

2.附上眼在手外求得手眼矩阵的python代码

#!/usr/bin/env python
# coding: utf-8
import transforms3d as tfs
import numpy as np
import math


def get_matrix_eular_radu(x, y, z, rx, ry, rz):
    rmat = tfs.euler.euler2mat(math.radians(rx), math.radians(ry), math.radians(rz))
    rmat = tfs.affines.compose(np.squeeze(np.asarray((x, y, z))), rmat, [1, 1, 1])
    return rmat


def skew(v):
    return np.array([[0, -v[2], v[1]],
                     [v[2], 0, -v[0]],
                     [-v[1], v[0], 0]])


def rot2quat_minimal(m):
    quat = tfs.quaternions.mat2quat(m[0:3, 0:3])
    return quat[1:]


def quatMinimal2rot(q):
    p = np.dot(q.T, q)
    w = np.sqrt(np.subtract(1, p[0][0]))
    return tfs.quaternions.quat2mat([w, q[0], q[1], q[2]])


# hand = [1.1988093940033604, -0.42405585264804424, 0.18828251788562061, 151.3390418721659, -18.612399542280507,
#         153.05074895025035,
#         1.1684831621733476, -0.183273375514656, 0.12744868246620855, -161.57083804238462, 9.07159838346732,
#         89.1641128844487,
#         1.1508343174145468, -0.22694301453461405, 0.26625166858469146, 177.8815855486261, 0.8991159570568988,
#         77.67286224959672]
hand = [

    # -0.05448,-0.15018,0.06552,89.61059916,-2.119943842,-1.031324031,
    #     -0.10149,-0.23025,0.04023,96.7725716,6.187944187,5.328507495,
    #     -0.10114,-0.2207,0.04853,97.00175472,5.729577951,1.375098708    毫米单位

# -54.48,	-150.18,	65.52,  89.61059916,    -2.119943842,   -1.031324031,
# -101.49,-230.25,    40.23,  96.7725716,      6.187944187,    5.328507495,
# -101.14,-220.7	,   48.53,  97.00175472,    5.729577951,    1.375098708

# -122.12,	-323.09,	-206.86,	82.62051406,	-7.161972439	,1.948056503,
# -96.54,	-324.53,	-215.59,	83.70913387,	-7.734930234	,7.276563998,
# -116.41,	-325.50,	-202.05,	81.18811957,	-7.505747116	,6.187944187

        # zed
-54.29,	-95.24,	199.74,	80.45,	-5.88,	8.8,
-54.28,	-95.25,	199.73,	80.66,	-6.62,	18.13,
-54.3,	-95.27,	199.75,	81.57,	-0.76,	13.05


 ]

# camera = [-0.16249272227287292, -0.047310635447502136, 0.4077761471271515, -56.98037030812389, -6.16739631361851,
#           -115.84333735802369,
#           0.03955405578017235, -0.013497642241418362, 0.33975949883461, -100.87129330834215, -17.192685528625265,
#           -173.07354634882094,
#           -0.08517949283123016, 0.00957852229475975, 0.46546608209609985, -90.85270962096058, 0.9315977976503153,
#           175.2059707654342]

camera = [

    # -0.0794887,-0.0812433,0.0246,0.0008,0.0033,0.0182,
    #       -0.078034,-0.0879632,0.4881494,-0.1085,0.0925,-0.1569,
    #       -0.1086702,-0.0881681,0.4240367,-0.1052,0.1251,-0.1124,

# -79.4887,	-81.2433,	24.6,        0.0008,     0.0033,     0.0182,
# -78.034,	-87.9632,	488.1494,    -0.1085,    0.0925,     -0.1569,
# -108.6702,	-88.1681,	424.0367,    -0.1052,    0.1251,     -0.1124,

#     23.22020448 ,-69.45610195    ,370.5620915    ,0.2530 ,-0.0707, -1.5724,
#     46.8704669 ,-60.19912413    ,263.9729574    ,0.1473 ,-0.1117 ,-1.6090,
#     53.92881454 ,-39.52795178    ,453.4331562     ,0.2702 ,-0.1256, -1.6270,
-174.01022,	1797.687613,	2425.313638,	    1.2710,    0.1238,    0.0033,
-175.3384083,	260.4775862,	1349.136325,	    1.5191,    0.0664,    0.0058,
123.6753385,	-109.6917624,	695.5448714	,    0.4651,   -0.1328,   -0.2488



]

Hgs, Hcs = [], []
for i in range(0, len(hand), 6):
    Hgs.append(get_matrix_eular_radu(hand[i], hand[i + 1], hand[i + 2], hand[i + 3], hand[i + 4], hand[i + 5],))
    Hcs.append(
        get_matrix_eular_radu(camera[i], camera[i + 1], camera[i + 2], camera[i + 3], camera[i + 4], camera[i + 5]))

Hgijs = []
Hcijs = []
A = []
B = []
size = 0
for i in range(len(Hgs)):
    for j in range(i + 1, len(Hgs)):
        size += 1
        Hgij = np.dot(np.linalg.inv(Hgs[j]), Hgs[i])
        Hgijs.append(Hgij)
        Pgij = np.dot(2, rot2quat_minimal(Hgij))

        Hcij = np.dot(Hcs[j], np.linalg.inv(Hcs[i]))
        Hcijs.append(Hcij)
        Pcij = np.dot(2, rot2quat_minimal(Hcij))

        A.append(skew(np.add(Pgij, Pcij)))
        B.append(np.subtract(Pcij, Pgij))
MA = np.asarray(A).reshape(size * 3, 3)
MB = np.asarray(B).reshape(size * 3, 1)
Pcg_ = np.dot(np.linalg.pinv(MA), MB)
pcg_norm = np.dot(np.conjugate(Pcg_).T, Pcg_)
Pcg = np.sqrt(np.add(1, np.dot(Pcg_.T, Pcg_)))
Pcg = np.dot(np.dot(2, Pcg_), np.linalg.inv(Pcg))
Rcg = quatMinimal2rot(np.divide(Pcg, 2)).reshape(3, 3)

A = []
B = []
id = 0
for i in range(len(Hgs)):
    for j in range(i + 1, len(Hgs)):
        Hgij = Hgijs[id]
        Hcij = Hcijs[id]
        A.append(np.subtract(Hgij[0:3, 0:3], np.eye(3, 3)))
        B.append(np.subtract(np.dot(Rcg, Hcij[0:3, 3:4]), Hgij[0:3, 3:4]))
        id += 1

MA = np.asarray(A).reshape(size * 3, 3)
MB = np.asarray(B).reshape(size * 3, 1)
Tcg = np.dot(np.linalg.pinv(MA), MB).reshape(3, )
print(tfs.affines.compose(Tcg, np.squeeze(Rcg), [1, 1, 1]))

其中:

        hand为基坐标系下抓夹的位姿,一般从示教器上获取,我用的是ur5机械臂,注意单位mm和rad,三行为三组数据,hand=(x,y,z,rx,ry,rz),同时应将弧度制rad转为角度制°

        camera为相机中标定板的位姿,为相机的外参(平移矩阵、旋转矩阵),三行为三组数据,camera=(x,y,z,rx,ry,rz),同时应将弧度制转为角度制

3.眼在手外标定步骤

1)打印棋盘格

为了使标定精度更加准确,棋盘格精度越高越好;角点数越多越好;尽量减少相机中心到标定板的距离(适当小的标定板)等

参考资料:

手眼标定,我的结果显示手和眼相距上千米!手眼标定结果准确率如何提高?_提高手眼标定精度_鱼香ROS的博客-CSDN博客

这里我选择4*4的棋盘格

2)得到hand数据

示教器右侧为hand数据,记录五组,并转化为角度制

3)得到camera数据

将相机固定在距离机械臂基坐标的一定距离的地方,固定相机,记住距离

将棋盘格粘贴在机械臂末端执行器上,用相机拍摄五组棋盘格图片,使用matlab计算相机外参TR,将得到的TR转换为欧拉角

(matlab工具箱使用单目标定,其中得到的T为translationvectors,R为rotationvectors)

 (不知道这个棋盘格不正会不会有影响)

matlab标定得到的是旋转向量/旋转矩阵,得到的数据转化为欧拉角,参考下面的链接手眼标定必备——旋转向量转换为旋转矩阵python——罗德里格斯公式Rodrigues_python rodrigues_邸笠佘司的博客-CSDN博客

手眼标定中旋转矩阵转欧拉角——matlab_邸笠佘司的博客-CSDN博客

 

4.运行python得到手眼矩阵

 

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

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

相关文章

软件设计师学习笔记6-存储系统

1.层次化存储体系 1.1层次化存储结构 局部性原理是层次化存储结构的支持 时空局部性:刚被访问的内容,立即又被访问(eg: 循环体 ) 空间局部性:刚被访问的内容,临近的空间很快被访问(eg:数组) 1.2层次化存储结构的分类 DRAM&…

基于Tkinter的PanedWindow组件进行窗口布局

在用Tkinter进行可视化界面开发中,界面布局是最需要最先考虑的,哪些组件放在什么地方都需要优先规划,我们可以用place或者pack进行边开发边布局,这需要人为的去对齐,费时费力。在Tkinter中有个组件PanedWindow可以帮助…

手把手教你搭建一个盲盒小程序,轻松掌握开发技巧

在当今社交媒体时代,微信公众号已成为企业、个人传播和推广的重要工具。而微信公众号盲盒小程序则是一个更为创新和互动的方式,能够吸引更多用户的关注和参与。下面,我们将为大家介绍一下微信公众号盲盒小程序的制作完全攻略。 1. 注册登录【…

区分什么是Java内存模型(JMM)和 JVM运行时数据区

文章目录 一、概念区分1、什么是内存模型?什么是(内存区域)运行时数据区?2、为什么要有Java内存模型?2.1、硬件的效率与一致性2.2、 CPU和缓存的一致性2.2.1、为什么需要CPU cache?2.2.2、三级缓存&#xf…

ASEMI快恢复二极管APT80DQ60BG特点应用

编辑-Z APT80DQ60BG参数描述: 型号:APT80DQ60BG 最大峰值反向电压(VRRM):600V 最大直流阻断电压VR(DC):600V 平均整流正向电流(IF):80A 非重复峰值浪涌电流(IFSM):600A 工作接点温度和储存温度(TJ, …

基于社会群体算法优化的BP神经网络(预测应用) - 附代码

基于社会群体算法优化的BP神经网络(预测应用) - 附代码 文章目录 基于社会群体算法优化的BP神经网络(预测应用) - 附代码1.数据介绍2.社会群体优化BP神经网络2.1 BP神经网络参数设置2.2 社会群体算法应用 4.测试结果:5…

C#_特性反射详解

特性是什么? 为程序元素额外添加声明信息的一种方式。 字面理解:相当于把额外信息写在干胶标签上,然后将其贴在程序集上。 反射是什么? 反射是一种能力,运行时获取程序集中的元数据。 字面理解:程序运行…

入门必看!亚马逊新品上架如何快速提升产品排名?

对于有经验的亚马逊卖家来说,各种套路已经玩的出神入化,但对于新手卖家来说,可能并不清楚亚马逊新品上架时应该去冲产品排名,更不知道怎么提升产品排名。所以今天,大白就为亚马逊新手卖家带来了亚马逊新品上架该如何提…

VR/AR/眼镜投屏充电方案(LDR6020)

VR眼镜即VR头显,也称虚拟现实头戴式显示设备,随着元宇宙概念的传播,VR眼镜的热度一直只增不减,但是头戴设备的续航一直被人诟病,如果增大电池就会让头显变得笨重影响体验,所以目前最佳的解决方案还是使用VR…

富士施乐S1810 放大或缩小复印方法

1、放置原稿 将原稿放置在稿台玻璃上。(A3纸横向平铺) 2、设置原稿尺寸 按下“原稿尺寸”键,将显示区调整为横向A3,如图: (请务必确认是否与外观图的原稿尺寸显示区所显示的原稿尺寸和方向匹配。&#xf…

直播小程序源码有用的协议知识:MQTT协议

MQTT协议分析: MQTT协议中文全称为消息队列遥测传输协议,是一种实时通信协议,适用于物联网场景中。MQTT协议被应用到直播小程序源码平台中,确保了直播小程序源码平台音视频流的传输高效、低延迟,为直播小程序源码平台…

Springboot_Redis

Springboot默认使用lettuce操作redis,底层是netty jdeis并发差些 Redis的Template 分为两种, 一种是StringRedisTemplate,另一种是RedisTemplate 根据不同的数据类型,大致的操作也分为这5种,以StringRedisTemplate为例 stringRedisTempla…

Linux 终端命令之文件目录操作,对比Dos相关命令

目录 前言 基础命令(文件目录相关的) cd命令 【英文帮助】 【对应Dos命令】 pwd命令 【英文帮助】 【对应Dos命令】 ls命令 【英文帮助】 【对应Dos命令】 tree命令 【英文帮助】 【对应Dos命令】 mkdir命令 【英文帮助】 【对应Dos命令…

Linux下的Shell基础——文本处理工具(五)

前言: Linux Shell是一种基本功,由于怪异的语法加之较差的可读性,通常被Python等脚本代替。既然是基本功,那就需要掌握,毕竟学习Shell脚本的过程中,还是能了解到很多Linux系统的内容。 Linux脚本大师不是…

Android View动画之LayoutAnimation的使用

接前篇 Android View动画整理 ,本篇介绍 LayoutAnimation 的使用。 参考《安卓开发艺术探索》。 View 动画作用于 View 。 LayoutAnimation 则作用于 ViewGroup , 为 ViewGoup 指定一个动画,ViewGoup 的子 View 出场时就具体动画效果。 简言…

YOLO目标检测——真实和人工智能生成的合成图像数据集下载分享

YOLO真实和人工智能生成的合成图像数据集,真实场景的高质量图片数据,图片格式为jpg,数据场景丰富。可用于检测图像是真实的还是由人工智能生成。 数据集点击下载:YOLO真实和人工智能生成的合成图像数据集120000图片数据说明.rar

【MYSQL8.0从入门到精通】

文章目录 MySQL 8.0一.MySQL的多表操作1.外键约束(一对多)2.外键约束(多对多) MySQL 8.0 一.MySQL的多表操作 1.外键约束(一对多) 方式1 在创建表的同时创建外键约束 -- 1.创建主表 create table if no…

聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化

聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化 目录 聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 聚类分析 | MATLAB实现基于LP拉普拉斯映射的聚类可视化,聚类结果可视化,MATLAB程…

【GAMES 101】图形学入门——向量与变换(Vector Transform)

一、向量(Vector) 点乘(Dot Product) 定义:计算两个单位向量的夹角用途: 描述两个向量是否足够接近 叉乘(Cross Product) 定义:用于判断法向量的防线,一…

C语言:指针和数组(看完拿捏指针和数组)

目录 数组名的理解: 一维数组: 解析: 字符数组: 解析: 解析: 字符串数组: 解析: 解析: 一级指针: 解析: 解析: 二维数组&a…