机械臂手眼标定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的应用层协议 总结 前言 在之前的文章中为大家介绍了关于网络协议栈第一层就是应用层,包含套接字的使用,在应用层编码实现服务…...
别再只用箱线图了!用R语言ggplot2绘制高颜值小提琴图,让你的SCI图表更专业
科研数据可视化进阶:用R语言打造专业级小提琴图 在生物医学领域的科研论文中,数据可视化是展示研究成果的关键环节。许多研究者习惯性地使用箱线图来呈现数据分布,却忽略了这种传统方法可能掩盖的重要信息细节。当面对复杂的数据分布模式时&…...
通过 Taotoken CLI 工具一键配置开发环境中的多模型访问密钥
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 通过 Taotoken CLI 工具一键配置开发环境中的多模型访问密钥 在接入多个大模型服务时,开发者通常需要为不同的工具&…...
3步轻松延长JetBrains IDE评估期:开源工具让你的开发体验永不停歇
3步轻松延长JetBrains IDE评估期:开源工具让你的开发体验永不停歇 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 还在为JetBrains IDE评估期结束而烦恼吗?作为开发者,我们经常…...
从ColorDialog到FontDialog:手把手教你定制WinForm功能对话框,打造个性化桌面应用
从ColorDialog到FontDialog:WinForm功能对话框的深度定制与用户体验优化 在桌面应用开发中,对话框不仅是功能实现的工具,更是用户体验的重要组成部分。想象一下,当用户在使用你的文本编辑器时,能够像专业软件那样流畅地…...
UP Squared 6000工业级创客板:边缘AIoT开发与部署实战指南
1. 项目概述:UP Squared 6000,一块能“扛事”的工业级创客板在工业自动化和边缘AIoT项目里摸爬滚打这么多年,我经手过不少开发板,从早期的树莓派到各种国产派,再到工业级的工控机。很多时候,我们面临一个尴…...
RK3568开发板TB-96AI-3568CE深度评测:从核心接口到AI应用实战
1. 从芯片到板卡:TB-96AI-3568CE的设计哲学当一块芯片从图纸走向现实,成为一块可以握在手中的开发板时,这中间的路程远不止是简单的引脚引出和电源接通。我接触过不少基于RK3568的方案,但拿到贝启科技这块TB-96AI-3568CE时&#x…...
从U-Net到DocUNet:一个图像分割经典架构如何“跨界”解决文档矫正难题?
从U-Net到DocUNet:经典分割架构如何重塑文档图像矫正技术 当你在咖啡馆随手拍下一张皱巴巴的收据时,是否想过手机镜头捕捉的二维图像如何还原成平整的文档?这个看似简单的需求背后,隐藏着计算机视觉领域一个极具挑战性的几何变换问…...
JDK 17 + Hadoop 3.3.5 + Spark 3.3.2 集群搭建保姆级避坑指南(CentOS 8.5 + VMware)
JDK 17 Hadoop 3.3.5 Spark 3.3.2 集群搭建实战避坑手册 当你第一次尝试在本地环境搭建大数据集群时,是否曾被各种兼容性问题、配置错误和莫名其妙的报错折磨得焦头烂额?本文将带你完整走一遍从零开始搭建基于JDK 17、Hadoop 3.3.5和Spark 3.3.2的集群…...
Vivado 2022.1里Floating-point IP核的隐藏技巧:如何优化开方运算的延迟与资源消耗
Vivado 2022.1浮点开方IP核深度调优:从参数配置到硬件实现的黄金法则 在FPGA信号处理系统中,浮点运算单元往往是性能瓶颈所在。当设计一个实时性要求极高的雷达信号处理链路时,我曾在某型号的Xilinx UltraScale器件上遭遇过这样的困境&#x…...
【亲测免费】 探索U-Net多类别图像分割:基于PyTorch的开源利器
探索U-Net多类别图像分割:基于PyTorch的开源利器 【下载地址】U-Net多类别训练代码基于PyTorch 本仓库提供了一个基于PyTorch实现的U-Net模型代码,适用于多类别图像分割任务。你可以使用该代码训练自己的数据集,实现对图像中不同类别的精确分…...

