机械臂手眼标定ZED相机——眼在手外python、matlab
目录
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 mathdef 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 rmatdef 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 += 1Hgij = 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 += 1MA = 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得到手眼矩阵
相关文章:
机械臂手眼标定ZED相机——眼在手外python、matlab
目录 1.眼在手外原理 2.附上眼在手外求得手眼矩阵的python代码 3.眼在手外标定步骤 1)打印棋盘格 2)得到hand数据 3)得到camera数据 4.运行python得到手眼矩阵 1.眼在手外原理 眼在手外所求的手眼矩阵是基坐标到相机的转换矩阵 2.附上…...
前端实现动态路由(前端控制全部路由,后端返回用户角色)
优缺点 优点: 不用后端帮助,路由表维护在前端逻辑相对比较简单,比较容易上手权限少的系统用前端鉴权更加方便 缺点: 线上版本每次修改权限页面,都需要重新打包项目大型项目不适用如果需要在页面中增加角色并且控制可以访问的页…...
Spring5学习笔记—Spring事务处理
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Spring专栏 ✨特色专栏: M…...
如何增长LLM推理token,从直觉到数学
背景: 最近大模型输入上文长度增长技术点的研究很火。为何要增长token长度,为何大家如此热衷于增长输入token的长度呢?其实你如果是大模型比价频繁的使用者,这个问题应该不难回答。增长了输入token的长度,那需要多次出入才能得到…...
《穷爸爸与富爸爸》时间是最宝贵的资产,只有它对所有人都是公平的
《穷爸爸与富爸爸》时间是最宝贵的资产,只有它对所有人都是公平的 罗伯特清崎,日裔美国人,投资家、教育家、企业家。 萧明 译 文章目录 《穷爸爸与富爸爸》时间是最宝贵的资产,只有它对所有人都是公平的[toc]摘录各阶层现金流图支…...
Git结合Gitee的企业开发模拟
本系列有两篇文章: 一是另外一篇《快速使用Git完整开发》,主要说明了关于Git工具的基础使用,包含三板斧(git add、git commit、git push)、Git基本配置、版本回退、分支管理、公钥与私钥、远端仓库和远端分支、忽略文…...
WEBGL(2):绘制单个点
代码如下: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevi…...
C# task多线程创建,暂停,继续,结束使用
1、多线程任务创建 private void button1_Click(object sender, EventArgs e) //创建线程{CancellationToken cancellationToken tokensource.Token;Task.Run(() > //模拟耗时任务{for (int i 0; i < 100; i){if (cancellationToken.IsCancellationRequested){return;…...
界面控件DevExpress WinForms(v23.2)下半年发展路线图
本文主要概述了官方在下半年(v23.2)中一些与DevExpress WinForms相关的开发计划,重点关注的领域将是可访问性支持和支持.NET 8。 DevExpress WinForms有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。同时能…...
vue实现按需加载的多种方式
1.import动态导入 const Home () > import( /* webpackChunkName: "Home" */ /views/Home.vue); 2.使用vue异步组件resolve 这种方式没有成功 //const 组件名 resolve > require([‘组件路径’],resolve) //(这种情况下一个组件生成一个js文件…...
el-switch组件在分页情况下的使用
1.需求: 系统使用者在点击发布状态的开关后,可以对应的发布或者取消发布试卷 2.前端代码: html代码(这里不贴其他表单项的代码了,直接贴el-Switch组件的代码): <!-- qwy: 使用Switch组件,设置发布状态,业务逻辑:在页面初始渲染的时候应该查询发布状态,以根据状…...
【100天精通python】Day49:python web编程_web框架,Flask的使用
目录 1 Web 框架 2 python 中常用的web框架 3 Flask 框架的使用 3.1 Flask框架安装 3.2 第一个Flask程序 3.3 路由 3.3.1 基本路由 3.3.2 动态路由 3.3.3 HTTP 方法 3.3.4 多个路由绑定到一个视图函数 3.3.5 访问URL 参数的路由 3.3.6 带默认值的动态路由 3.3.7 带…...
sql 查重以及删除重复
查重 select count(1),content from t_mall_longping group by content having count(1)>1 稳重删除重复(技术来源于 百度文心一言,好屌呀) CREATE TABLE tmp_duplicates ( hxid INT PRIMARY KEY );INSERT INTO tmp_duplicates SEL…...
Flux语言 -- InfluxDB笔记二
1. 基础概念理解 1.1 语序和MySQL不一样,像净水一样通过管道一层层过滤 1.2 不同版本FluxDB的语法也不太一样 2. 基本表达式 import "array" s 10 * 3 // 浮点型只能与浮点型进行运算 s1 9.0 / 3.0 s2 10.0 % 3.0 // 等于 1 s3 10.0 ^ 3.0 // 等于…...
18.Oauth2-微服务认证
1.Oauth2 OAuth 2.0授权框架支持第三方支持访问有限的HTTP服务,通过在资源所有者和HTTP服务之间进行一个批准交互来代表资源者去访问这些资源,或者通过允许第三方应用程序以自己的名义获取访问权限。 为了方便理解,可以想象OAuth2.0就是在用…...
vue和node使用websocket实现数据推送,实时聊天
需求:node做后端根据websocket,连接数据库,数据库的字段改变后,前端不用刷新页面也能更新到数据,前端也可以发送消息给后端,后端接受后把前端消息做处理再推送给前端展示 1.初始化node,生成pac…...
汽车电子笔记之:基于AUTOSAR的多核监控机制
目录 1、概述 2、系统监控的目标 2.1、任务的状态机 2.2、任务服务函数 2.3、任务周期性事件 2.4、时间监控的指标 2.5、时间监控的原理 2.6、CPU负载率监控原理 2.6.1、设计思路 2.6.2、监控方法的评价 3、基于WDGM模块热舞时序监控方法 3.1、活跃监督 3.2、截至时…...
GDB 源码分析 -- 断点源码解析
文章目录 一、断点简介1.1 硬件断点1.2 软件断点 二、断点源码分析2.1 断点相关结构体2.1.1 struct breakpoint2.1.2 struct bp_location 2.2 断点源码简介2.3 break设置断点2.4 enable break2.5 disable breakpoint2.6 delete breakpoint2.7 info break 命令源码解析 三、Linu…...
SpringMVC概述与简单使用
1.SpringMVC简介 SpringMVC也叫做Spring web mvc,是 Spring 框架的一部分,是在 Spring3.0 后发布的。 2.SpringMVC优点 1.基于 MVC 架构 基于 MVC 架构,功能分工明确。解耦合, 2.容易理解,上手快;使用简单。 就可以…...
传输层—UDP原理详解
目录 前言 1.netstat 2.pidof 3.UDP协议格式 4.UDP的特点 5.面向数据报 6.UDP的缓冲区 7.UDP使用注意事项 8.基于UDP的应用层协议 总结 前言 在之前的文章中为大家介绍了关于网络协议栈第一层就是应用层,包含套接字的使用,在应用层编码实现服务…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

