视觉SLAM-Eigen学习实践

2023-05-16

1.Eigen库介绍

Eigen是一个 C++ 开源线性代数库。它提供了快速的有关矩阵的线性代数运算,还包括解方程等功能。

可以通过sudo apt install libeigen3-dev命令进行安装,也可以去官网下载需要的版本进行安装。

若出现错误:Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable) E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?

依次输入以下命令,操作成功没有显示,重新进行安装即可。

sudo rm /var/lib/dpkg/lock-frontend       
sudo rm /var/lib/dpkg/lock
sudo apt install libeigen3-dev

Eigen 头文件的默认位置在“/usr/include/eigen3/” 中,因此在程序中导入包的时候,应该是eigen3/Eigen

2.Eigen矩阵定义及初始化

 Eigen库的引用

#include <eigen3/Eigen/Core>

#include <eigen3/Eigen/Dense>

Eigen 以矩阵为基本数据单元。它是一个模板类。它的前三个参数为:数据类型,行,列,Eigen 通过 typedef 提供了许多内置类型,还有int,double等等,例如声明一个 2*3 float 矩阵。

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

还有Vector3d类型,它 实质上是 Eigen::Matrix<double, 3, 1>

Eigen::Vector3d v_3d;

矩阵的初始化操作:

Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); //初始化为零

不明确矩阵大小时,采用动态初始化:

Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > matrix_dynamic;

3.Eigen矩阵常见操作

数据填充:

  输入数据(初始化)
 

matrix_23 << 1, 2, 3, 4, 5, 6;

输出 

cout << "matrix 2x3 from 1 to 6: \n" << matrix_23 << endl;

 

  for循环打印矩阵中的元素

  cout << "print matrix 2x3: " << endl;
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) cout << matrix_23(i, j) << "\t";
    cout << endl;
  }

矩阵乘法: 

 
 Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;
  cout << "[1,2,3;4,5,6]*[3,2,1]=" << result.transpose() << endl;

  Matrix<float, 2, 1> result2 = matrix_23 * vd_3d;
  cout << "[1,2,3;4,5,6]*[4,5,6]: " << result2.transpose() << endl;

随机数矩阵相关运算:
  matrix_33 = Matrix3d::Random();      // 随机数矩阵
  cout << "random matrix: \n" << matrix_33 << endl;
  cout << "transpose: \n" << matrix_33.transpose() << endl;      // 转置
  cout << "sum: " << matrix_33.sum() << endl;            // 各元素和
  cout << "trace: " << matrix_33.trace() << endl;          // 迹
  cout << "times 10: \n" << 10 * matrix_33 << endl;               // 数乘
  cout << "inverse: \n" << matrix_33.inverse() << endl;        // 逆
  cout << "det: " << matrix_33.determinant() << endl;    // 行列式

 

特征值与特征向量: 

SelfAdjointEigenSolver<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<double, MATRIX_SIZE, MATRIX_SIZE> matrix_NN
      = MatrixXd::Random(MATRIX_SIZE, MATRIX_SIZE);
  matrix_NN = matrix_NN * matrix_NN.transpose();  // 保证半正定
  Matrix<double, MATRIX_SIZE, 1> v_Nd = MatrixXd::Random(MATRIX_SIZE, 1);

①直接求逆(简单明了,但计算量大)

  clock_t time_stt = clock(); // 计时
  // 直接求逆
  Matrix<double, MATRIX_SIZE, 1> x = matrix_NN.inverse() * v_Nd;
  cout << "time of normal inverse is "
       << 1000 * (clock() - time_stt) / (double) CLOCKS_PER_SEC << "ms" << endl;
  cout << "x = " << x.transpose() << endl;

 ②矩阵分解来求,例如QR分解,速度会快很多

 time_stt = clock();
  x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
  cout << "time of Qr decomposition is "
       << 1000 * (clock() - time_stt) / (double) CLOCKS_PER_SEC << "ms" << endl;
  cout << "x = " << x.transpose() << endl;

③对于正定矩阵,还可以用cholesky分解来解方程 

 time_stt = clock();
  x = matrix_NN.ldlt().solve(v_Nd);
  cout << "time of ldlt decomposition is "
       << 1000 * (clock() - time_stt) / (double) CLOCKS_PER_SEC << "ms" << endl;
       //
  cout << "x = " << x.transpose() << endl;

 
4.Eigen几何模块
 
  // 3D 旋转矩阵直接使用 Matrix3d 或 Matrix3f
  Matrix3d rotation_matrix = Matrix3d::Identity();
  // 旋转向量使用 AngleAxis, 它底层不直接是Matrix,但运算可以当作矩阵(因为重载了运算符)
  AngleAxisd rotation_vector(M_PI / 4, Vector3d(0, 0, 1));     //沿 Z 轴旋转 45 度
  cout.precision(3);
  cout << "rotation matrix =\n" << rotation_vector.matrix() << endl;   //用matrix()转换成矩阵
  // 也可以直接赋值
  rotation_matrix = rotation_vector.toRotationMatrix();
  // 用 AngleAxis 可以进行坐标变换
  Vector3d v(1, 0, 0);
  Vector3d v_rotated = rotation_vector * v;
  cout << "(1,0,0) after rotation (by angle axis) = " << v_rotated.transpose() << endl;
  // 或者用旋转矩阵
  v_rotated = rotation_matrix * v;
  cout << "(1,0,0) after rotation (by matrix) = " << v_rotated.transpose() << endl;

  // 欧拉角: 可以将旋转矩阵直接转换成欧拉角
  Vector3d euler_angles = rotation_matrix.eulerAngles(2, 1, 0); // ZYX顺序,即yaw-pitch-roll顺序
  cout << "yaw pitch roll = " << euler_angles.transpose() << endl;

  // 欧氏变换矩阵使用 Eigen::Isometry
  Isometry3d T = Isometry3d::Identity();                // 虽然称为3d,实质上是4*4的矩阵
  T.rotate(rotation_vector);                                     // 按照rotation_vector进行旋转
  T.pretranslate(Vector3d(1, 3, 4));                     // 把平移向量设成(1,3,4)
  cout << "Transform matrix = \n" << T.matrix() << endl;

  // 用变换矩阵进行坐标变换
  Vector3d v_transformed = T * v;                              // 相当于R*v+t
  cout << "v tranformed = " << v_transformed.transpose() << endl;

  // 对于仿射和射影变换,使用 Eigen::Affine3d 和 Eigen::Projective3d 即可,略

  // 四元数
  // 可以直接把AngleAxis赋值给四元数,反之亦然
  Quaterniond q = Quaterniond(rotation_vector);
  cout << "quaternion from rotation vector = " << q.coeffs().transpose()
       << endl;   // 请注意coeffs的顺序是(x,y,z,w),w为实部,前三者为虚部
  // 也可以把旋转矩阵赋给它
  q = Quaterniond(rotation_matrix);
  cout << "quaternion from rotation matrix = " << q.coeffs().transpose() << endl;
  // 使用四元数旋转一个向量,使用重载的乘法即可
  v_rotated = q * v; // 注意数学上是qvq^{-1}
  cout << "(1,0,0) after rotation = " << v_rotated.transpose() << endl;
  // 用常规向量乘法表示,则应该如下计算
  cout << "should be equal to " << (q * Quaterniond(0, 1, 0, 0) * q.inverse()).coeffs().transpose() << endl;

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

视觉SLAM-Eigen学习实践 的相关文章

  • LeetCode-搜索插入位置

    给定一个排序数组和一个目标值 xff0c 在数组中找到目标值 xff0c 并返回其索引 如果目标值不存在于数组中 xff0c 返回它将会被按顺序插入的位置 你可以假设数组中无重复元素 示例 1 输入 1 3 5 6 5 输出 2 示例 2
  • Github快速查找资源常用筛选命令

    1 按项目名称 仓库名称搜索 xff08 不区分大小写 xff09 命令 in name xxx 示范 xff1a in name tensorflow 2 按照readme搜索 xff08 不区分大小写 xff09 命令 in readm
  • STM32F407-定时器中断

    1 通用定时器工作流程 2 时钟来源 定时器有4个时钟源 xff0c 分别为 xff1a 内部时钟 CK INT 外部时钟模式1 xff1a 外部输入脚 TIx 外部时钟模式2 xff1a 外部触发输入 ETR 仅适用TIM2 3 4 内部
  • STM32F407-获取GPIO电平状态

    判断STM32 GPIO输入口的输入状态 xff08 高电平或低电平 xff09 以PE2和PE4为例 xff1a 判断单个端口是否为高电平 xff1a if GPIOE gt IDR amp GPIO IDR IDR2 函数体 xff1b
  • STM32F407-限位金属传感器限制步进电机

    一 硬件 1 硬件准备 xff1a 57步进电机 xff08 型号57CM18 xff09 xff0c 42步进电机 xff0c 驱动器TB6600 xff0c 开发板STM32F407ZGT6 xff0c SN 4NDO限位金属传感器 x
  • MobileNet学习记录-概念篇

    MobileNet 1 网络简介 MobileNet模型是Google公司近年来提出的一种轻量级深度神经网络 xff0c 主要用于移动和嵌入式平台开发使用 MobileNets主要是从最初引入的深度可分离卷积构建的 xff0c 并随后用于I
  • Node将JS与Puppeteer打包成exe使用

    pkg pkg是一个可以将nodejs代码打包封装成可执行文件的工具 xff0c 安装命令如下 xff1a npm install g pkg 打包命令如 xff1a 默认会打包三个平台的可执行文件 xff0c win mac linux
  • Ubuntu 连接 wifi -亲测可用

    连接wifi 修改 etc network interfaces 文件 这个文件是定义网络配置的 sudo vim etc network interfaces interfaces 修改后文件内容如下 xff1a auto eth0 if
  • 卷积神经网络CNN学习记录-概念篇

    卷积神经网络CNN 1 网络简介 卷积神经网络 xff08 Convolutional Neural Network xff09 是人工神经网络与深度学习相结合 xff0c 它是一种具有卷积计算并且具有深度结构的前馈神经网络经 xff0c
  • 卷积神经网络CNN学习记录-实战篇(Minst手写数据集识别)

    from tensorflow examples tutorials mnist import input data import tensorflow as tf minst 61 input data read data sets 34
  • 卷积神经网络CNN学习记录-CNN实现语义分割(Encoder-Decoder结构)

    1 Encoder from keras layers import def Conv Encoder input height 61 416 input width 61 416 Img In 61 Input shape 61 inpu
  • MobileNet学习记录-基于MobileNetV1的自动驾驶图像语义分割实现

    1 MobileNet基础及架构 Mobielnet学习记录 概念篇 2 实现思路 为了便于实现 xff0c 还是采用了Encoder Decoder结构 xff0c 利用MobileNet来进行特征提取 xff0c 相较于CNN的卷积操作
  • STM32F407-SPI通信接口

    1 SPI概念 SPI xff0c 是一种高速的 xff0c 全双工 xff0c 同步的通信总线 xff0c 并且在芯片的管脚上只占用四根线 xff0c 节约了芯片的管脚 xff0c 同时为PCB的布局上节省空间 xff0c 提供方便 xf
  • Python学习-变量类型

    1 单变量赋值 等号 xff08 61 xff09 用来赋值 xff0c 左边是一个变量名 xff0c 右边是存储在变量中的值 xff0c 定义变量不需要声明类型 xff0c 可以直接赋值使用 例 xff1a temp1 61 100 赋值
  • Python学习-条件循环

    1 while循环 while循环的语句格式为 xff1a while condition statements 当判断条件为真时 xff0c 就会执行循环中的语句 xff0c 当条件为假时退出循环 xff0c 若条件为一个永真式 xff0
  • Python学习-函数模块

    1 函数定义 定义规则 xff1a 函数代码块以 def 关键词开头 xff0c 后接函数标识符名称和圆括号 任何传入参数和自变量必须放在圆括号中间 圆括号之间可以用于定义参数 函数的第一行语句可以选择性地使用文档字符串 用于存放函数说明
  • STM32F407控制42,57两个步进电机用传感器限制位置

    功夫不负有心人 xff0c 终于把这个做出来了 xff0c 本项目为控制42 57两个步进电机 xff0c 带动齿轮 xff0c 进行上下左右转动 xff0c 四个限位金属传感器限制位置 传感器配置过程 步进电机配置过程 记录一下一个问题
  • Python学习-多线程

    1 线程 首先区分线程和进程两个概念 xff1a 进程是资源 xff08 CPU 内存等 xff09 分配的基本单位 xff0c 它是程序执行时的一个实例 程序运行时系统就会创建一个进程 xff0c 并为它分配资源 xff0c 然后把该进程
  • Spring MVC controller出错后进入了不该进入的拦截器

    拦截器对一些接口进行了排除 xff0c 使这些接口不用进入拦截器的验证 xff0c 但是出现了一个现象 xff0c 例如 api v1 auth register 这个接口 xff0c 如果因为某些原因 xff0c 出现异常了 xff0c
  • Git学习-本地仓库与版本管理

    一 创建仓库 1 创建空仓库 在合适的位置创建一个新目录 xff0c Git Bash支持的是linux命令操作 第一种方法 xff1a mkdir mygit cd mygit pwd 用mkdir创建目录 xff0c pwd查看当前路径

随机推荐

  • STM32F407用wk2124芯片编写SPI转四路串口驱动

    目录 引言 一 SPI通信配置 1 GPIO初始化设置 2 SPI参数配置 3 读写函数 4 速度设置 二 WK2124逻辑代码编写 1 片选初始化 2 写寄存器函数 3 读寄存器函数 4 写FIFO函数 5 读FIFO函数 6 WK212
  • Git学习-远程仓库

    创建远程仓库 本地现在有一个仓库git xff0c 同时可以在github上创建一个同名的git仓库 xff0c 可以供自己和他人协同操作 1 在github电机new repository创建一个新仓库 xff0c 名称保持与本地一致 R
  • Python学习-SQLite

    SQLite是一种嵌入式数据库 xff0c 它的数据库就是一个文件 由于SQLite本身是C写的 xff0c 而且体积很小 xff0c 所以 xff0c 经常被集成到各种应用程序中 xff0c 甚至在iOS和Android的App中都可以集
  • Python学习-TCP网络编程

    1 客户端 Socket是网络编程的一个抽象概念 通常我们用一个Socket表示 打开了一个网络链接 xff0c 而打开一个Socket需要知道目标计算机的IP地址和端口号 xff0c 再指定协议类型即可 大多数连接都是可靠的TCP连接 创
  • Git学习-分支

    在Git里 xff0c 主分支为master分支 HEAD也不是指向提交 xff0c 而是指向master xff0c master才是指向提交的 xff0c 所以 xff0c HEAD指向的就是当前分支 一开始的时候 xff0c mast
  • Matplotlib绘制各类图像(折线图,曲线图...)-画图的神

    Matplotlib简介 Matplotlib是一个Python工具箱 xff0c 用于科学计算的数据可视化 借助它 xff0c Python可以绘制如Matlab和Octave多种多样的数据图形 最初是模仿了Matlab图形命令 但是与M
  • STM32F407多路串口通信进行数据收发

    一直被说是就不能把几个串口放在一起 xff0c 写个标准例程直接用 xff0c 非要每次用哪个串口才现场改程序 xff0c 被迫把usart1 usart2 usart3进行了资源整合 xff0c 挂在这以备不时之需 功能简述 xff1a
  • 基于Keras实现电影评论文本分类与RNN实现

    notebook使用评论文本将影评分为积极 xff08 positive xff09 或消极 xff08 nagetive xff09 两类 这是一个二元 xff08 binary xff09 或者二分类问题 xff0c 一种重要且应用广泛
  • 基于STM32F407的七要素气象站(气象传感器)CR-WS数据处理实现

    一 七要素气象站介绍 1 七要素气象站介绍 开发板还是采用STM32F407 485连线 xff1a 如果买了变送器就按照下图连线 xff1a 没有买变送器的话 xff0c 直接从气象站上拉线 xff0c 红正黑负 xff0c 黄485 A
  • MyBatis Plus 分页查询,total字段为0,分页未生效

    1 未配置 MybatisPlusInterceptor 64 Bean public MybatisPlusInterceptor mybatisPlusInterceptor MybatisPlusInterceptor interce
  • JavaSE学习记录-整数逆序+数组删除元素

    数组定义方法 int arr 61 new int 10 定义同时进行赋值 xff1a int arr 61 new int 1 2 3 4 5 数组打印方法 1 for循环打印 for int i 61 0 i lt arr length
  • FAFTS文件系统常用函数学习

    一 FATFS文件系统基础知识 1 简介 文件系统可以从官网进行下载 官网地址 xff1a http elm chan org fsw ff 00index e html FATFS是一个完全免费开源的FAT 文件系统模块 xff0c Fa
  • Leetcode-旋转数组+最后一个单词长度

    给定一个数组 xff0c 将数组中的元素向右移动 k 个位置 xff0c 其中 k 是非负数 示例 1 输入 1 2 3 4 5 6 7 和 k 61 3 输出 5 6 7 1 2 3 4 解释 向右旋转 1 步 7 1 2 3 4 5 6
  • Leetcode-最短路径和+最大子串和(动态规划)

    给定一个包含非负整数的 m x n 网格 xff0c 请找出一条从左上角到右下角的路径 xff0c 使得路径上的数字总和为最小 说明 xff1a 每次只能向下或者向右移动一步 示例 输入 1 3 1 1 5 1 4 2 1 输出 7 解释
  • LeetCode-二进制串和+宝石与石头

    给你两个二进制字符串 xff0c 返回它们的和 xff08 用二进制表示 xff09 输入为 非空 字符串且只包含数字 1 和 0 示例 1 输入 a 61 34 11 34 b 61 34 1 34 输出 34 100 34 示例 2 输
  • JavaSE数组练习-句子翻转+字符替换+打印特殊三角

    1 句子翻转 要求 xff1a 给定字符串如 34 hello i am a student 34 xff0c 对英语句子进行翻转 xff0c 并保持英语单词的顺序不变 xff0c 对标点符号当成字母处理 代码实现 xff1a import
  • 视觉SLAM学习--基础篇(SLAM框架及相机模型)

    一 例子 如上图的小萝卜机器人 xff0c 要使其具有自主运动能力至少需要两个条件 xff1a 1 我在什么地方 xff1f 定位 2 周围环境是什么样 xff1f 建图 因此它既需要知道自身的状态 位置 xff0c 也要了解所在的环境 地
  • Linux各类软件安装配置问题记录

    1 Ubuntu侧边栏和顶部栏消失不见 解决方法 xff1a 鼠标右键或者快捷键打开终端输入命令 dconf reset f org compiz 输入命令 setsid unity 一般到这一步侧边栏就会出现了 xff0c 如果没有出现就
  • 代码模拟确定有限自动机(DFA)执行过程

    一个确定有限自动机 xff08 DFA xff09 M是一个五元组 xff1a M 61 xff08 K xff0c xff0c f xff0c S xff0c Z xff09 其中 K是一个有穷集 xff0c 它的每个元素称为一个状态 x
  • 视觉SLAM-Eigen学习实践

    1 Eigen库介绍 Eigen 是一个 C 43 43 开源线性代数库 它提供了快速的有关矩阵的线性代数运算 xff0c 还包括解方程等功能 可以通过sudo apt install libeigen3 dev命令进行安装 xff0c 也