视觉SLAM十四讲(三)——三维空间刚体运动(下)
理论部分请看 :三维空间刚体运动
一、Eigen的使用
首先安装 Eigen:
sudo apt-get install libeigen3-dev
一般都安装在
/usr/include/eigen3/
中
代码:
#include <iostream>
#include <ctime>
using namespace std;
//Eigen 部分
#include <Eigen/Core>
//稠密矩阵的代数运算
#include <Eigen/Dense>
#define MATRIX_SIZE 50
//本程序演示了 Eigen 基本类型的使用
int main(int argc,char** argv){
//声明一个 2×3 的 float 矩阵
Eigen::Matrix<float,2,3> matrix_23;
//Eigen 通过 typedef 提供了许多内置类型,不过底层仍然是 Eigen::Matrix
//例如 Vector3d 实质上是 Eigen::Matrix<double,3,1>
Eigen::Vector3d v_3d;
//Matrix3d 实质上是 Eigen::Matrix<double,3,3>
Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero();
//如果不确定矩阵大小,可以使用动态大小的矩阵
Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> matrix_dynamic;
//更简单的
Eigen::MatrixXd matrix_x;
//矩阵操作
//输入数据
matrix_23 << 1,2,3,4,5,6;
//输出
cout<<"2*3矩阵 "<<matrix_23<<endl;
//用()访问矩阵中的元素
for(int i = 0;i<1;i++)
for(int j = 0;j<2;j++)
cout<<"矩阵元素: "<<matrix_23(i,j)<<endl;
v_3d << 3,2,1;
//矩阵和向量相乘
//Eigen::Matrix<double,2,1> result_wrong_type = matrix_23 * v_3d; 混合两种不同类型的矩阵,这是错误的
//应该这样显示转换
Eigen::Matrix<double,2,1> result = matrix_23.cast<double>() * v_3d;
cout<<"和向量相乘:"<<result<<endl;
//同样不能搞错矩阵的维度
//试着取消下面的注释,看看会报什么错
//Eigen::Matrix<double,2,3> result_wrong_dimension = matrix_23.cast<double>() * v_3d;
//一些矩阵运算
matrix_33 = Eigen::Matrix3d::Random();
cout<<"矩阵运算:"<<matrix_33<<endl<<endl;
cout<<"转置:"<<matrix_33.transpose()<<endl; //转置
cout<<"各元素和:"<<matrix_33.sum()<<endl; //各元素和
cout<<"迹:"<<matrix_33.trace()<<endl; //迹
cout<<"数乘:"<<10 * matrix_33<<endl; //数乘
cout<<"逆:"<<matrix_33.inverse()<<endl; //逆
cout<<"行列式:"<<matrix_33.determinant()<<endl; //行列式
//特征值
//实对称矩阵可以保证对角化成功
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver (matrix_33.transpose() * matrix_33);
cout<<"Eigen values = "<<eigen_solver.eigenvalues()<<endl;
cout<<"Eigen vectors = "<<eigen_solver.eigenvectors()<<endl;
//解方程
//求解 matrix_NN * x = v_Nd 这个方程
//N 的大小在上卖弄宏里定义,矩阵由随机数生成
//直接求逆是最直接的,但是运算量大
Eigen::Matrix<double,MATRIX_SIZE,MATRIX_SIZE> matrix_NN;
matrix_NN = Eigen::MatrixXd::Random(MATRIX_SIZE,MATRIX_SIZE);
Eigen::Matrix<double,MATRIX_SIZE,1> v_Nd;
v_Nd = Eigen::MatrixXd::Random(MATRIX_SIZE,1);
clock_t time_stt = clock(); //计时
//直接求逆
Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse() * v_Nd;
cout<<"time use in normal inverse is "<<1000 * (clock() - time_stt) / (double)CLOCKS_PER_SEC <<" ms"<<endl;
//通常用矩阵分解来求,例如 QR 分解,速度会快很多
time_stt = clock();
x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
cout<<"time use in Qr composition is "<<1000 * (clock() - time_stt) / (double) CLOCKS_PER_SEC<<" ms"<<endl;
return 0;
}
编译方法为:
在源代码所在文件夹再创建一个 CMakeLists.txt,写入:
cmake_minimum_required (VERSION 2.8)
include_directories("/usr/include/eigen3")
project(EigenMatrix)
add_executable(eigenMatrix eigenMatrix.cpp)
然后
cmake .
make
再运行就可以了
./eigenMatrix
程序中已经给出较详细注释,这里就不在解释了
二、Eigen 几何模块
代码:
#include <iostream>
#include <cmath>
using namespace std;
#include <Eigen/Core>
#include <Eigen/Geometry>
int main(int argc,char** argv){
Eigen::Matrix3d rotation_matrix = Eigen::Matrix3d::Identity();
//旋转向量使用 AngleAxis,它底层不直接是 Matrix3d,但运算可以当做矩阵(因为重载了运算符)
Eigen::AngleAxisd rotation_vector (M_PI/4,Eigen::Vector3d(0,0,1)); //沿Z轴旋转45度
cout .precision(3);
cout<<"rotation matrix = \n"<<rotation_vector.matrix()<<endl; //用 matrix() 转换成矩阵
//也可以直接赋值
rotation_matrix = rotation_vector.toRotationMatrix();
//用 AngleAxis 可以进行坐标变换
Eigen::Vector3d v(1,0,0);
Eigen::Vector3d v_rotated = rotation_vector *v;
cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;
//或者用旋转矩阵
v_rotated = rotation_matrix *v;
cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;
//欧拉角:可以将旋转矩阵直接转换成欧拉角
Eigen::Vector3d euler_angles = rotation_matrix.eulerAngles(2,1,0); //ZYX 顺序,即yaw pitch roll 顺序
cout<<"yaw pitch roll = "<<euler_angles.transpose()<<endl;
//欧式变换矩阵使用 Eigen::Isometry
Eigen::Isometry3d T = Eigen::Isometry3d::Identity(); //虽然称为3d,实质上是4×4矩阵
T.rotate(rotation_vector); //按照rotation_vector 进行旋转
T.pretranslate(Eigen::Vector3d(1,3,4)); //把平移向量设成(1,3,4)
cout<<"Transform matrix = \n"<<T.matrix()<<endl;
//用变换矩阵进行坐标变换
Eigen::Vector3d v_transformed = T*v; //相当于 R*v + t
cout<<"v transformed = "<<v_transformed.transpose()<<endl;
//相对于仿射和射影变换,使用 Eigen::Affine3d 和Eigen::Projective3d 即可,略
//四元数
//可以直接把 AngleAxis 赋值给四元数,反之亦然
Eigen::Quaterniond q = Eigen::Quaterniond (rotation_vector);
cout<<"quaternion = \n"<<q.coeffs()<<endl; //注意 coeffs 的顺序是 (x,y,z,w) ,w 为实部,前三者为虚部
//也可以把旋转矩阵赋值给它
q = Eigen::Quaterniond(rotation_matrix);
cout<<"quaternion = \n"<<q.coeffs()<<endl;
//使用四元数旋转一个向量,使用重载的乘法即可
v_rotated = q * v; //数学上是 qvq^{-1}
cout<<"(1,0,0) after rotation = "<<v_rotated.transpose()<<endl;
return 0;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
include_directories("/usr/include/eigen3")
project(UseGeometry)
add_executable(useGeometry useGeometry.cpp)
编译运行方法同上。
视觉SLAM十四讲(三)——三维空间刚体运动(下)的更多相关文章
- 高博-《视觉SLAM十四讲》
0 讲座 (1)SLAM定义 对比雷达传感器和视觉传感器的优缺点(主要介绍视觉SLAM) 单目:不知道尺度信息 双目:知道尺度信息,但测量范围根据预定的基线相关 RGBD:知道深度信息,但是深度信息对 ...
- 《视觉SLAM十四讲》第2讲
目录 一 视觉SLAM中的传感器 二 经典视觉SLAM框架 三 SLAM问题的数学表述 注:原创不易,转载请务必注明原作者和出处,感谢支持! 本讲主要内容: (1) 视觉SLAM中的传感器 (2) 经 ...
- 视觉slam十四讲第七章课后习题6
版权声明:本文为博主原创文章,转载请注明出处: http://www.cnblogs.com/newneul/p/8545450.html 6.在PnP优化中,将第一个相机的观测也考虑进来,程序应如何 ...
- 视觉slam十四讲第七章课后习题7
版权声明:本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/newneul/p/8544369.html 7.题目要求:在ICP程序中,将空间点也作为优化变量考虑进来 ...
- 浅读《视觉SLAM十四讲:从理论到实践》--操作1--初识SLAM
下载<视觉SLAM十四讲:从理论到实践>源码:https://github.com/gaoxiang12/slambook 第二讲:初识SLAM 2.4.2 Hello SLAM(书本P2 ...
- 《视觉SLAM十四讲》第1讲
目录 一 视觉SLAM 注:原创不易,转载请务必注明原作者和出处,感谢支持! 一 视觉SLAM 什么是视觉SLAM? SLAM是Simultaneous Localization and Mappin ...
- 视觉SLAM十四讲:从理论到实践 两版 PDF和源码
视觉SLAM十四讲:从理论到实践 第一版电子版PDF 链接:https://pan.baidu.com/s/1SuuSpavo_fj7xqTYtgHBfw提取码:lr4t 源码github链接:htt ...
- 高翔《视觉SLAM十四讲》从理论到实践
目录 第1讲 前言:本书讲什么:如何使用本书: 第2讲 初始SLAM:引子-小萝卜的例子:经典视觉SLAM框架:SLAM问题的数学表述:实践-编程基础: 第3讲 三维空间刚体运动 旋转矩阵:实践-Ei ...
- 《视觉SLAM十四讲》学习日志(一)——预备知识
SLAM简介 : SLAM是 Simultaneous Localization and Mapping 的缩写,中文译作 " 同时定位与地图构建 ".它是指搭载特定传感器的主题, ...
随机推荐
- win10环境下,让所有程序都以管理员身份运行的办法
记录下,备查! 打开gpedit.msc组策略编辑. 左侧依次找到:计算机配置->Window设置->安全设置->本地策略->安全选项 然后再右侧找到:用户账户控制:以管理员批 ...
- C#-Json-抽象类的反序列化
引用: using System; using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Lin ...
- 一、Windows docker入门篇
win7.win8 等需要利用 docker toolbox 来安装,国内可以使用阿里云的镜像来下载,下载地址:http://mirrors.aliyun.com/docker-toolbox/win ...
- [JZOJ5281]钦点题解--瞎搞+链表
[JZOJ5281]钦点题解--瞎搞+链表 题目链接 于 暴 力 过
- 【转载】为什么我的网站加www是打不开的呢
在访问网站的过程中,我们发现有些网站访问不带www的主域名可以正常访问,反而访问加www的域名打不开,那为什么有的网站加www是打不开的呢?此情况很大可能是因为没有解析带www的域名记录或者主机Web ...
- DBShop前台RCE
前言 处理重装系统的Controller在判断是否有锁文件后用的是重定向而不是exit,这样后面的逻辑代码还是会执行,导致了数据库重装漏洞和RCE. 正文 InstallController.php中 ...
- SVN限制IP访问
转自:https://www.cnblogs.com/wjlkingwjl/p/4630764.html 需求 SVN是放在公网的,需要特别指定公司的IP才能获取操作. 操作 在安装完Visual S ...
- ipv4与ipv6 Inet4Address类和Inet6Address类
在设置本地IP地址的时候,一些人会疑惑IPv4与IPv6的区别是什么?下面由学习啦小编为你分享ipv4与ipv6的区别的相关内容,希望对大家有所帮助. ipv4与ipv6的区别 在windows 7以 ...
- ubuntu18.04 为应用程序添加桌面图标
一.桌面图标位置 Lniux下桌面图标储存路径为:/usr/share/applications 二.桌面图标格式 所有桌面图标格式均为desktop,即名为XXX.desktop 三.编辑内容(常用 ...
- poi 读取word 遍历表格和单元格中的图片
背景 项目需要解析word表格 需要批量导入系统,并保存每行信息到数据库 并且要保存word中的图片, 并保持每条信息和图片的对应关系 一行数据可能有多条图片 解决办法 没有找到现成的代码,怎么办呐? ...