Eigen 几何模块深拆:Isometry3d vs Affine3d + 变换矩阵本质详解

文章目录

  • 0 写在前面
  • 1 数学背景对比
  • 2 Eigen 实现差异
  • 3 `Isometry3d` 是不是 4 × 4 矩阵?
  • 4 核心 API 速查
  • 5 实战示例
    • 5.1 SLAM 位姿链:相机点 → 世界点
    • 5.2 体素滤波:各向异性缩放(X/Y → 5 cm,Z → 10 cm)
    • 5.3 把通用 4×4 矩阵 M “正交化”为刚体变换
  • 6 性能与数值建议
  • 7 常见坑 · 排雷
  • 8 Cheat Sheet (贴工位)
  • 9 总结
  • 参考资料


目录

  • 0 写在前面
  • 1 数学背景对比
  • 2 Eigen 实现差异
  • 3 `Isometry3d` 是不是 4 × 4 矩阵?
  • 4 核心 API 速查
  • 5 实战示例
    • 5.1 SLAM 位姿链:相机点 → 世界点
    • 5.2 体素滤波:各向异性缩放(X/Y → 5 cm,Z → 10 cm)
    • 5.3 把通用 4×4 矩阵 M “正交化”为刚体变换
  • 6 性能与数值建议
  • 7 常见坑 · 排雷
  • 8 Cheat Sheet (贴工位)
  • 9 总结
  • 参考资料


0 写在前面

在 vSLAM / VIO / 机器人定位等工程实践中,90 % 的变换只是旋转 + 平移的刚体运动;只有不到 10 % 的场景(点云体素缩放、图像几何映射、CAD 变形等)才会用到带缩放或剪切的仿射变换。Eigen 针对这两类需求提供了

类别Eigen 类型数学对应
刚体变换Eigen::Isometry3dSE(3)
一般仿射Eigen::Affine3dA(3)

本文将从 数学原理 → 内部结构 → 常用 API → 实战示例 → 性能建议 → 易错排查 全方位梳理它们,并回答一个高频疑惑Isometry3d 究竟是不是 4 × 4 矩阵?


1 数学背景对比

刚体变换 SE(3)仿射变换 A(3)
定义保持点间距离不变的变换线性变换 A + 平移 t(可带缩放/剪切)
矩阵结构[Rt01]\displaystyle\begin{bmatrix}R&t\\0&1\end{bmatrix}[R0t1]R∈SO(3)R∈SO(3)RSO(3)[At01]\displaystyle\begin{bmatrix}A&t\\0&1\end{bmatrix}[A0t1]AAA 任意 3 × 3
自由度6 (3 旋转 + 3 平移)≤ 12 (9 线性 + 3 平移)
典型应用传感器外参、SLAM 位姿、TF 广播图像/点云缩放、CAD 模型变形

2 Eigen 实现差异

特性Isometry3dAffine3d
旋转部分强制正交(det = 1)任意 3 × 3
存储封装 4 × 4 矩阵(刚体特化)封装 4 × 4 矩阵
求逆只需 R⊤,−R⊤tR^\top,\,-R^\top tR,Rt通用 4 × 4 逆
内存12 double (9 R + 3 t)16 double
语义保障保证组合后仍为刚体可能引入缩放/剪切

3 Isometry3d 是不是 4 × 4 矩阵?

结论:是!
Isometry3d4 × 4 齐次刚体矩阵的封装类

  • 数学结构

    T=[Rt01],R∈SO(3)T=\begin{bmatrix}R&t\\0&1\end{bmatrix},\;R∈SO(3) T=[R0t1],RSO(3)

  • 代码验证

    Eigen::Isometry3d T = Eigen::Isometry3d::Identity();
    Eigen::Matrix4d  H = T.matrix();   // H 是标准 4x4
    
类型本质维度刚体约束典型用途
Matrix4d纯 4×4 矩阵4×4渲染 / 存盘
Isometry3d刚体 SE(3)4×4 (封装)SLAM / VIO
Affine3d仿射 A(3)4×4 (封装)图像/点云缩放

4 核心 API 速查

#include <Eigen/Geometry>// ── Isometry3d ───────────────────────────
Isometry3d T = Isometry3d::Identity();
T.rotate(q.toRotationMatrix());  // 写入旋转
T.pretranslate(t);               // 左乘平移
Matrix4d H = T.matrix();         // 取 4×4// 组合与逆
Isometry3d Tab  = Ta * Tb;       // 右侧先执行
Isometry3d Tinv = T.inverse();   // 快速刚体逆
Vector3d  pw    = T * pc;        // 点变换// ── Affine3d ────────────────────────────
Affine3d A = Affine3d::Identity();
A.linear() <<0.5, 0,   0,0,   0.5, 0,0,   0,   1;                 // 含缩放
A.translation() = Vector3d(1,2,3);

5 实战示例

5.1 SLAM 位姿链:相机点 → 世界点

// T_w_b :  body 坐标系 → world 坐标系   (车辆/IMU Pose)
Isometry3d T_w_b;     // T_b_c :  camera 坐标系 → body 坐标系   (相机外参)
Isometry3d T_b_c;     // p_c    :  相机坐标系下的点坐标(单位 m)
Vector3d  p_c(0.1, 0.2, 1.0);// 右乘先算:p_c 先映射到 body,再映射到 world
Vector3d  p_w = T_w_b * T_b_c * p_c;  

要点

  • 乘法写成 “外层坐标系 * 内层坐标系 * 点”
  • 代码顺序 = 实际执行的坐标系级联(最右边先计算)

5.2 体素滤波:各向异性缩放(X/Y → 5 cm,Z → 10 cm)

Affine3d voxel = Affine3d::Identity();// 设置线性部分:对 (x,y,z) 轴分别乘以 0.05, 0.05, 0.10
voxel.linear() <<0.05, 0,    0,0,    0.05, 0,0,    0,    0.10;// 若还需平移,可再设置 voxel.translation()// 直接对点或点云做缩放
point = voxel * point;

要点

  • Affine3d,因为含 缩放 ⇒ 非刚体
  • .linear() 修改 3 × 3 线性块,.translation() 负责平移

5.3 把通用 4×4 矩阵 M “正交化”为刚体变换

// ① 读进来时先用 Affine3d 保存,保留所有信息
Affine3d A(M);      // ② 提取线性部分做极分解 / 四元数归一化,得到最接近的正交矩阵
Quaterniond q(A.linear());         // 自动正交化
Matrix3d    R = q.toRotationMatrix();// ③ 重新组装为 Isometry3d(刚体),平移直接拷贝
Isometry3d T;
T.linear()      = R;               // 旋转 (正交)
T.translation() = A.translation(); // 平移

要点

  1. 外部矩阵不保证正交 → 先用 Affine3d 接收
  2. 利用 Quaterniond 把 3 × 3 线性块正交化
  3. 重新封装成 Isometry3d,之后即可安全用于 SLAM 位姿累乘

6 性能与数值建议

场景推荐类型
大量位姿累乘 / 求逆Isometry3d
含尺度 / 剪切Affine3d
不确定线性部分是否正交Affine3d,再正交化
与 Sophus / g2o 联合始终保持 Isometry3d

7 常见坑 · 排雷

  1. 乘法顺序与注释不符
    T_a_b * T_b_c 表示“先 c→b,再 b→a”——注释别写反!
  2. 误往 Isometry3d.linear() 写入非正交矩阵
    写完请确保 R.col(i).norm()==1det≈1
  3. 角度单位
    Eigen 全部使用 弧度,杜绝度→弧度混用。
  4. 存盘丢语义
    T.matrix(),读后用 Isometry3d(H) 恢复。

8 Cheat Sheet (贴工位)

#include <Eigen/Geometry>Isometry3d T = Isometry3d::Identity();
T.rotate(q);              // 写旋转
T.pretranslate(t);        // 写平移
Vector3d p = T * pc;      // 变换点
Matrix4d H = T.matrix();  // 导出 4×4
T = Isometry3d(H);        // 从矩阵恢复

9 总结

类型选它的理由典型任务
Isometry3d强制刚体、逆运算 O(1)SLAM 位姿、外参、TF
Affine3d允许缩放/剪切点云/图像几何、CAD
Matrix4d无语义,最通用统一存盘 / 可视化

牢记 “右乘先算,左乘决定结果坐标系”,你的姿态链将稳固无坑。祝开发顺利!


参考资料

  • Eigen 官方文档:https://eigen.tuxfamily.org/dox/group__Geometry__Module.html
  • 《视觉 SLAM 十四讲》第 3 章

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

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

相关文章

python的病例管理系统

前端开发框架:vue.js 数据库 mysql 版本不限 后端语言框架支持&#xff1a; 1 java(SSM/springboot)-idea/eclipse 2.NodejsVue.js -vscode 3.python(flask/django)–pycharm/vscode 4.php(thinkphp/laravel)-hbuilderx 数据库工具&#xff1a;Navicat/SQLyog等都可以 随着医疗…

博客系统开发全流程解析(前端+后端+数据库)与 AI 协作初体验

一、前言&#xff1a;为什么选择博客系统作为全栈入门&#xff1f; 对于初入编程世界的开发者来说&#xff0c;“全栈” 似乎是一个庞大而遥远的概念。前端、后端、数据库、部署运维… 知识体系繁杂&#xff0c;令人望而生畏。选择一个目标明确、功能完整且贴近实际应用的项目…

Xavier公式的原理

数学原理&#xff1a; (1) 前向传播的方差一致性 假设输入 x 的均值为 0&#xff0c;方差为 σx2σ_x^2σx2​&#xff0c;权重 W的均值为 0&#xff0c;方差为 σW2σ_W^2σW2​&#xff0c;则输出 zWxzWxzWx的方差为&#xff1a; Var(z)nin⋅Var(W)⋅Var(x) Var(z)n_{in}⋅Va…

pytorch学习笔记(二)-- pytorch模型开发步骤详解

简介&#xff1a; 本章主要是针对Pytorch神经网络的开发步骤做一个详细的总结&#xff0c;对每一步的前世今生做一个了解&#xff0c;下面先列一下开发需要的步骤有哪些&#xff1a; 模型构建&#xff0c;主要是前向传递函数的确认确认损失函数以及学习步频&#xff08;learni…

consul 的安装与服务发现

1. helm 安装 consul 到 k8s 安装放在这里了&#xff1a;https://github.com/lianan2/installation/tree/master/consul-helm consul 的常用命令&#xff1a; # 查看集群状态 kubectl -n consul exec -it consul-server-0 -- consul operator raft list-peers kubectl -n con…

ros topic和service的使用

在做ldiar slam的时候&#xff0c;最常用的当属topic&#xff0c;偶尔也会用一下service&#xff0c;action则很少使用。现在一块来看一下topic的使用。一、topic的使用topic的消息订阅和发布#include<ros/ros.h> #include<rosbag/bag.h> #include<rosbag/view.…

【TCP/IP】18. 因特网服务质量

18. 因特网服务质量18. 因特网服务质量18.1 服务质量&#xff08;QoS&#xff09;18.2 实时传输协议&#xff08;RTP&#xff09;18.3 实时传输控制协议&#xff08;RTCP&#xff09;18.4 集成业务&#xff08;IntServ&#xff09;18.5 区分业务&#xff08;DiffServ&#xff0…

数据集相关类代码回顾理解 | StratifiedShuffleSplit\transforms.ToTensor\Counter

【PyTorch】图像多分类项目 目录 StratifiedShuffleSplit transforms.ToTensor Counter StratifiedShuffleSplit sss StratifiedShuffleSplit(n_splits1, test_size0.2, random_state0) 创建StratifiedShuffleSplit对象&#xff0c;用于将数据集划分为训练集和测试集。 …

【环境配置】KAG - Windows 安装部署

前言 本博客将介绍如何在 Windows 系统上 部署运行 KAG 项目&#xff0c;将使用 WSL 和 Docker 和 Vscode 帮助我们之后利用 KAG 开发个人知识库问答项目。 KAG&#xff08;Knowledge-Augmented Generation&#xff09;知识增强生成系统 是一个融合知识图谱与大语言模型能力的…

《探索电脑麦克风声音采集多窗口实时可视化技术》

引言在当今数字化信息飞速发展的时代&#xff0c;声音作为一种重要的信息载体&#xff0c;其处理和分析技术日益受到广泛关注。声音可视化技术&#xff0c;作为声音处理领域的关键技术之一&#xff0c;具有极为重要的价值。它能够将抽象的声音信号转化为直观的视觉图像&#xf…

加工进化论:SPL 一键加速日志转指标

作者&#xff1a;劳贵泓&#xff08;泓逸&#xff09; 1. 背景 日志服务的 SPL&#xff08;Search Processing Language&#xff09;自推出以来&#xff0c;凭借其强大的数据处理能力&#xff0c;已经成为众多开发者和企业实现高效数据分析的首选工具。随着业务场景的不断拓展…

Web 应用防火墙:守护应用安全的核心屏障

当你在调试 Web 应用时&#xff0c;是否遇到过这样的情况&#xff1a;刚修复的 XSS 漏洞又被绕过&#xff0c;数据库日志里突然出现诡异的 SQL 语句&#xff0c;或者用户反馈登录后信息被篡改&#xff1f;这些问题的背后&#xff0c;往往是 Web 应用面临的持续安全威胁。据 OWA…

Python 网络爬虫的基本流程及 robots 协议详解

数据驱动的时代,网络爬虫作为高效获取互联网信息的工具,其规范化开发离不开对基本流程的掌握和对 robots 协议的遵守。本文将系统梳理 Python 网络爬虫的核心流程,并深入解读 robots 协议的重要性及实践规范。 一、Python 网络爬虫的基本流程 Python 网络爬虫的工作过程可…

字节二面(狠狠拷打系列):什么是http1.1,2.0,3.0,分别在什么场景里面用的多

文章目录从单行到新纪元&#xff1a;HTTP/0.9、1.0、1.1、2.0与3.0的核心区别HTTP/0.9&#xff1a;协议的黎明 (1991)HTTP/1.0&#xff1a;功能扩展与标准化 (1996)HTTP/1.1&#xff1a;持久连接与性能优化 (1997)HTTP/2.0&#xff1a;二进制与多路复用 (2015)HTTP/3.0&#xf…

Java教程:JavaWeb ---MySQL高级

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;大数据开发、.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_…

Audio笔试和面试题型解析

本专栏预计更新90期左右。当前第27期-音频部分. 音频硬件在消费电子(手机、电脑、耳机、智能音箱)、汽车、专业音响等领域是用户体验的关键组成部分。大厂(如苹果、三星、Google、华为、小米、各种汽车Tier 1供应商等)的硬件工程师在设计和优化音频系统时,需要对喇叭(扬…

DeepSeek俄罗斯方块网页版HTML5(附源码)

用DeepSeek生成一个俄罗斯方块游戏网页版的&#xff0c;基于HTML5&#xff0c;效果很棒。 提示词prompt 帮我做一个俄罗斯方块 网页版的 基于HTML5游戏功能说明 基本功能&#xff1a; 完整的俄罗斯方块游戏逻辑 7种不同形状的方块 分数计算系统 等级提升系统(速度会随等级提高)…

企业电商平台搭建:ZKmall开源商城服务器部署与容灾方案

企业级电商平台最核心的诉求&#xff0c;就是得让 “业务一直在线”—— 不管是平时运营要稳如磐石&#xff0c;还是突然出故障了能火速恢复&#xff0c;都离不开靠谱的服务器部署架构和周全的容灾方案。ZKmall 开源商城攒了 6000 多家企业客户的实战经验&#xff0c;琢磨出一套…

【软件运维】前后端部署启动的几种方式

.sh启动 #!/bin/bash# 解析软链接&#xff0c;获取真实脚本目录 SOURCE"${BASH_SOURCE[0]}" while [ -L "$SOURCE" ]; doDIR"$( cd -P "$( dirname "$SOURCE" )" && pwd )"SOURCE"$(readlink "$SOURCE&q…

[爬虫知识] DrissionPage:强大的自动化工具

相关爬虫实战案例&#xff1a;[爬虫实战] 使用 DrissionPage 自动化采集小红书笔记 相关爬虫专栏&#xff1a;JS逆向爬虫实战 爬虫知识点合集 爬虫实战案例 逆向知识点合集 前言&#xff1a; 在当今数据驱动的世界里&#xff0c;网络爬虫和自动化测试扮演着越来越重要的角…