本文主要参考 : 计算机视觉life, 仅作笔记用
旋转矩阵
旋转矩阵的概念,参考一个视频
在这里 二维向量p 逆时针旋转θ的旋转矩阵为
三维旋转
OpenCV和MATLAB中都有专门的罗德里格斯函数, 对这个公式讲解的很清楚
旋转矩阵有几个重要性质:
- 旋转矩阵R具有正交性,R和R的转置的乘积是单位阵,且行列式值为1
- 旋转矩阵R的逆矩阵表示了一个和R相反的旋转
- 旋转矩阵R通常和平移向量t一起组成齐次的变换矩阵T,描述了欧氏坐标变换
欧拉角
欧拉角遵循的是右手系规则,即大拇指指向坐标轴正方向,四指旋转的方向即为转动的正方向,欧拉角包含三个自由量:yaw(偏航角)、pitch(俯仰角)、roll(翻滚角)。
偏航角:绕z轴旋转, 得到偏航角
俯仰角:绕y轴旋转, 得到俯仰角
翻滚角:绕x轴旋转, 得到翻滚角
欧拉角可以与旋转矩阵相互转换,以最上图片为例:
若是在三维坐标上,假设刚刚是绕z轴旋转,依据“绕谁谁不变”的原则:
同样的:
欧拉角在SLAM中用的很少,原因是它的一个致命缺点:万向锁。也就是在俯仰角为±90°时,第一次和第3次旋转使用的是同一个坐标轴,会丢失一个自由度,引起奇异性。事实上,想要表达三维旋转,至少需要4个变量。
由此便引出四元数。
Eigen 库
Eigen是一个C++开源线性代数库,安装非常方便,Ubuntu下一行代码即可搞定:
sudo apt-get install libeigen3-dev
1、Eigen库不同于一般的库,它只有头文件,没有.so和 .a那样的二进制库文件,所以在CMakeLists.txt里只需要添加头文件路径,并不需要使用 target_link_libraries 将程序链接到库上。
2、Eigen以矩阵为基本数据单元,在Eigen中,所有的矩阵和向量都是Matrix模板类的对象,Matrix一般使用3个参数:数据类型、行数、列数
Eigen::Matrix<typename Scalar, int rowsNum, int colsNum>
而向量只是一种特殊的矩阵(一行或者一列)。同时,Eigen通过typedef 预先定义好了很多内置类型,如下,我们可以看到底层仍然是Eigen::Matrix
typedef Eigen::Matrix<float, 4, 4> Matrix4f;
typedef Eigen::Matrix<float, 3, 1> Vector3f;
3、为了提高效率,对于已知大小的矩阵,使用时需要指定矩阵的大小和类型。如果不确定矩阵的大小,可以使用动态矩阵Eigen::Dynamic
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> matrix_dynamic;
4、Eigen在数据类型方面“很傻很天真”。什么意思呢?就是使用Eigen时操作数据类型必须完全一致,不能进行自动类型提升。比如C++中,float类型加上double类型变量不会报错,编译器会自动将结果提升为double。但是在Eigen中float类型矩阵和double类型矩阵不能直接相加,必须统一为float或者double,否则会报错。
上述四种旋转表达方式是可以相互转化的。在Eigen中它们之间的转化非常的方便。下图是我看的别人总结的旋转矩阵、四元素、旋转向量之间的相互转化图:
Eigen 头文件&头文件中的类的作用