【Eigen】Eigen库基础语法

news2024/9/21 22:40:56

这里是Eigen库的一些基础语法,摘自《视觉SLAM十四讲》,修改了书中代码的一些bug,部分地方添加了一些自己的理解。

头文件相关

#include <Eigen/Core>	// Eigen 核心部分
#include <Eigen/Dense>	// 稠密矩阵的代数运算(逆,特征值等)
#include <Eigen/Geometry>	// 提供了各种旋转和平移的表示

CMake注意事项

include_directories("/usr/include/eigen3")

定义相关

定义一个 2 × 3 2\times 3 2×3float矩阵:

Eigen::Matrix<float, 2, 3> matrix_23;

定义一个3维的double向量:

Eigen::Vector3d v_3d;
// 等价于:Matrix<double, 3, 1> vd_3d;

定义一个 3 × 3 3\times 3 3×3double矩阵,同时初始化为0:

Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero();;

定义一个大小不定的矩阵:

// 方式1
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> matrix_dynamic;
// 方式2
Eigen::MatrixXd matrix_x;

初始化方法

// 输入数据(初始化)
matrix_23 << 1, 2, 3, 4, 5, 6;
// 输出
cout << "matrix 2x3 from 1 to 6: \n" << matrix_23 << endl;

输出:

matrix 2x3 from 1 to 6: 
1 2 3
4 5 6

初始化为随机数:

matrix_33 = Eigen::Matrix3d::Random();

访问矩阵元素

用括号来访问矩阵第i行,第j列的元素(i, j起始均为0):

matrix_23(i, j)

显式类型转换

Eigen不允许两种不同类型的矩阵相乘,必须要做显式类型转换,如:

Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;

一些矩阵操作

转置:

matrix_33.transpose()

求各元素和:

matrix_33.sum()

求迹:

matrix_33.trace()

求逆矩阵:

matrix_33.inverse()

求行列式:

matrix_33.determinant()

求特征值和特征向量:

// 实对称矩阵可以保证对角化成功
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver(matrix_33.transpose() * matrix_33);
// 特征值
cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl;
// 特征向量
cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl;

解方程

目标:求解matrix_NN * x = v_Nd这个方程

// 首先定义matrix_NN
Eigen::Matrix<double, 50, 50> matrix_NN = Eigen::MatrixXd::Random(50, 50);
// 然后定义x
Eigen::Matrix<double, 50, 1> x

解法1:直接求逆(慢)

// 直接求逆
x = matrix_NN.inverse() * v_Nd;

解法2:QR分解(快)

x = matrix_NN.colPivHouseholderQr().solve(v_Nd);

解法3:cholesky分解(快,要求正定矩阵)

x = matrix_NN.ldlt().solve(v_Nd);

旋转矩阵

定义一个 3 × 3 3\times 3 3×3double旋转矩阵,同时初始化为单位阵:

Eigen::Matrix3d rotation_matrix = Eigen::Matrix3d::Identity();

旋转向量

定义一个绕z轴旋转45°的旋转向量:

Eigen::AngleAxisd rotation_vector(M_PI / 4, Eigen::Vector3d(0, 0, 1));

注意:旋转向量的底层不直接是Matrix,但运算时可以当作旋转矩阵(因为重载了运算符)

Eigen::Vector3d v(1, 0, 0);
Eigen::Vector3d v_rotated = rotation_vector * v;

matrix()toRotationMatrix()可以转换成旋转矩阵:

rotation_matrix = rotation_vector.matrix()
rotation_matrix = rotation_vector.toRotationMatrix();

旋转矩阵转欧拉角

Eigen::Vector3d euler_angles = rotation_matrix.eulerAngles(2, 1, 0); 
// (2, 1, 0)分别对应(X, Y, Z),说明按ZYX顺序旋转

欧式变换、仿射变换、射影变换

在这里插入图片描述
定义一个 4 × 4 4\times 4 4×4 欧氏变换矩阵,同时初始化为单位阵:

// 虽然说是3d,实际上是4×4的矩阵
Eigen::Isometry3d T = Eigen::Isometry3d::Identity();
// 按照rotation_vector进行旋转
T.rotate(rotation_vector);
// 把平移向量设成(1,3,4)
T.pretranslate(Vector3d(1, 3, 4));

定义一个 4 × 4 4\times 4 4×4 仿射变换矩阵:Eigen::Affine3d,其余操作与Eigen::Isometry3d一致。有的时候会用Eigen::Affine3d来代替Eigen::Isometry3d

定义一个 4 × 4 4\times 4 4×4 射影变换矩阵:Eigen::Projective3d,其余操作与Eigen::Isometry3d一致。 A \boldsymbol{A} A t \boldsymbol{t} t 的赋值方式与Eigen::Isometry3d一致,尚不知道如何赋值 a T \boldsymbol{a}^T aT。实际上也不怎么常用。

用变换矩阵进行坐标变换

Eigen::Vector3d v_transformed = T * v; 	// 相当于R * v + t

四元数

用旋转向量来初始化四元数(反之亦可):

Eigen::Quaterniond q = Eigen::Quaterniond(rotation_vector);

用旋转矩阵来初始化四元数(反之亦可):

q = Eigen::Quaterniond(rotation_matrix);

普通初始化四元数的方法:

// (w, x, y, z)
Eigen::Quaterniond(0, 1, 0, 0)

cout四元数的方法:

// (x, y, z, w)
cout << q.coeffs().transpose() << endl;

注意:

  • coeffs的顺序是 ( x , y , z , w ) (x,y,z,w) (x,y,z,w) w w w为实部,前三者为虚部。这个顺序也是内部存储和运算的顺序。
  • 利用Quaterniond()初始化的顺序为 ( w , x , y , z ) (w,x,y,z) (w,x,y,z),顺序是不一样的。

共轭四元数:

// (w, -x, -y, -z)
q.conjugate()

用四元数来旋转一个向量(乘法被重载了,这里的乘法不表示四元数乘法):

// 表示旋转的四元数要归一化
q.normalize();
// 使用四元数旋转一个向量
v_rotated = q * v; // 注意数学上是q * Quaterniond(0, 1, 0, 0) * q共轭

出处:
在这里插入图片描述

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

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

相关文章

Java - 通过反射进行赋值以及函数调用

Java - 通过反射进行赋值以及函数调用前言一. 通过反射进行赋值1.1 测试1.2 总结二. 通过反射进行函数调用前言 说来惭愧&#xff0c;虽然反射在Java中是非常重要和常见的一种机制。但是&#xff0c;每当自己去写这方面的代码的时候&#xff0c;总是容易愣住。还得想一想代码怎…

题库API搭建接口

题库API搭建接口 本平台优点&#xff1a;免费查题接口搭建 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a;题库后台http://daili.jueguangzhe.cn/ 题库后台…

社招前端vue面试题汇总

用过pinia吗&#xff1f;有什么优点&#xff1f; 1. pinia是什么&#xff1f; 在Vue3中&#xff0c;可以使用传统的Vuex来实现状态管理&#xff0c;也可以使用最新的pinia来实现状态管理&#xff0c;我们来看看官网如何解释pinia的&#xff1a;Pinia 是 Vue 的存储库&#xff…

机器学习数据不均衡处理教程

机器学习数据不均衡处理教程 学习对数据进行过采样和欠采样、应用 SMOTE、集成方法和成本敏感型学习假设 课程英文名&#xff1a;Machine Learning with Imbalanced Data 此视频教程共13.5小时&#xff0c;中英双语字幕&#xff0c;画质清晰无水印&#xff0c;源码附件全 下…

Apriori算法及例题

一&#xff1a;Apriori算法介绍 关联规则挖掘是数据挖掘中最活跃的研究方法之一 。最早是由 Agrawal 等人提出的1993最初提出的动机是针对购物篮分析问题提出的&#xff0c;其目的是为了发现交易数据库中不同商品之间的联系规则。这些规则刻画了顾客购买行为模式&#xff0c;可…

Java去除文档阴影

Java去除文档阴影 一、前言 文稿扫描大家用的都比较频繁、想是各种证件、文件都可以通过扫描文稿功能保存到手机。相比直接拍照&#xff0c;在扫描文稿时&#xff0c;程序会对图像进行一些矫正。比如去除阴影、修正倾斜、旋转矫正等。进行这些处理后的图片要更加容易识别。今…

学习下c++原来它和Java有很多相似的地方

Java和CJava和C区别简单学习下C语法C 是什么&#xff1f;C工作原理&#xff1a;C标识符C基本数据类型C关键字封装&#xff0c;继承&#xff0c;多态简单回顾下Java语法Java的基础语法&#xff1a;Java注释Java标识符Java修饰符Java 接口和继承Java8 新增的特性Java和C区别 Java…

VTK-vtkPointInterpolator/vtkInterpolatorKernel

欢迎大家加入社区&#xff0c;雪易VTK社区-CSDN社区云 前言&#xff1a;目前在做模型的ReMesh&#xff0c;在研究这个接口&#xff0c;希望能有所帮助。 vtkPointInterpolator 描述&#xff1a; 变量&#xff1a; Strategy&#xff1a;MASK_POINTS, NULL_VALUE, CLOSEST_POI…

【css遇到的问题】vue中使用select下拉框,数据绑定但是默认不显示问题

文章目录问题描述原因分析问题描述 在vue中使用原生的select下拉框的时候&#xff0c;绑定数据内容但是发现其中默认显示第一条的并不显示 需求实现效果 实际实现效果 循环出select内的数据以后&#xff0c;发现原本默认显示第一条的select框变成了空白&#xff0c;要选择后…

【Mysql】事务

文章目录一.什么是事务1.1. 事物的属性1.2. 事务的版本支持1.3. 事务的提交方式1.4. 事务常见操作证明事务的回滚事务崩溃情况下验证回滚结论二.事务隔离级别2.1. 如何理解隔离性2.2. 隔离性级别2.3. 脏读,幻读,不可重复读2.4. 查看,设置隔离级别2.5. 隔离性验证三.一致性(Cons…

T046基于51单片机无线蓝牙控制8位LED灯亮灭proteus仿真原理图PCB

功能&#xff1a; 0.本项目采用STC89C52作为单片机系统的控制MCU 1.通过蓝牙发送指令控制LED灯 2.通过手机APP可以控制8路LED灯的亮灭&#xff0c;可以全亮全灭。 3.通过手机APP可以控制8路LED灯的亮度。每个灯的亮度有3档。具体控制指令如下 a)发送Ox&#xff0c;开启指定LED灯…

日常学习之:Yaml 和 Json 有什么区别

安装 json 是 python 内置 yaml 需要安装 pip install pyyaml格式 对于同样一段数据&#xff1a; test_data {"金山中学":{"101班":{"王宁": {"语文":33,"数学":22,"英语":18}}}}我们用下面的代码分别存入 ya…

ALE的基本介绍、使用与配置

本文将介绍ale插件的基本使用与配置&#xff0c;将从linter的介绍到具体插件的使用与bug的修复~ 本文仅仅时抛砖引玉&#xff0c;更多的使用技巧与功能可以查看项目介绍 ALE的基本介绍、使用与配置ale的介绍ale的基本配置与使用查看你可用的linter安装iverilog——for windowal…

Redisson之lock()和tryLock()的区别

Redisson之lock()和tryLock()的区别和原理解析 在Redisson中 lock() 方法 与 tryLock() 方法是有区别的&#xff01; 我们先来阐述两者的区别&#xff0c;再分析它们的源码。 lock() 与 tryLock() 的区别 &#xff08;1&#xff09;返回值&#xff1a; lock() 是没有返回值…

Vue中的diff算法深度解析

模板tamplate经过parse&#xff0c;optimize&#xff0c;generate等一些列操作之后&#xff0c;把AST转为render function code进而生成虚拟VNode,模板编译阶段基本已经完成了&#xff0c;那么这一章&#xff0c;我们来探讨一下Vue中的一个算法策略–dom diff 首先来介绍下什么…

Java8 遍历List 使用stream().parallel()并发安全

1. parallelStream是什么&#xff1a; java 8引入了并行流的概念来进行并行处理&#xff0c;而并行流(Parallel Stream)利用所有可用CPU内核的优势&#xff0c;并行处理任务。其原理(Parallel Stream)是可以把大任务分成多个小任务执行, 最后再把执行结果进行合并, ForkJoinPoo…

数仓DWS层之旁路缓存优化

优化原因&#xff1a; 外部数据源的查询常常是流式计算的性能瓶颈。以本程序为例&#xff0c;每次查询都要连接 Hbase&#xff0c;数据传输需要做序列化、反序列化&#xff0c;还有网络传输&#xff0c;严重影响时效性。可以通过旁路缓存对查询进行优化。 旁路缓存模式是一种非…

利用Python海龟绘图画一个世界杯的足球

利用Python海龟绘图画一个世界杯的足球 花有重开日 人无再少年 四年一次的世界杯快要结束&#xff0c;为了纪念此次世界杯&#xff0c;特意用Python画了一个足球。 1.设计思路以及实现效果 世界杯足球实现思路&#xff1a; 首先使用海龟画一个圆形作为足球的外边框。然后在足…

3天带你走向实战!阿里顶配版Spring全家桶面试进阶笔记有多强?

Spring框架自从诞生以来就一直备受开发者青睐&#xff0c;它涵盖了Spring、Springboot、SpringCloud等诸多解决方案&#xff0c;一般我们都会统称为Spring全家桶&#xff01;出于Spring框架在Java开发者心中中的统治地位&#xff0c;所以不管是面试还是工作&#xff0c;Spring都…

夜神模拟器+fiddler抓包(抓取APPhttps请求,删除sll证书校验)

1.安装fiddler https://telerik-fiddler.s3.amazonaws.com/fiddler/FiddlerSetup.exe &#xff08;下载不了直接去官网找&#xff09; 2.配置 开启https请求抓取&#xff0c;不抓https可忽略2.修改或查看端口&#xff08;使用默认8888端口&#xff0c;要自定义端口可修改&#…