本文主要参考 : 计算机视觉life, 仅作笔记用

旋转矩阵

旋转矩阵的概念,参考一个视频

opencv水平翻转_矩阵


opencv水平翻转_旋转矩阵_02


在这里 二维向量p 逆时针旋转θ的旋转矩阵为

opencv水平翻转_旋转矩阵_03

三维旋转

opencv水平翻转_opencv水平翻转_04


OpenCV和MATLAB中都有专门的罗德里格斯函数, 对这个公式讲解的很清楚

旋转矩阵有几个重要性质:

  • 旋转矩阵R具有正交性,R和R的转置的乘积是单位阵,且行列式值为1
  • 旋转矩阵R的逆矩阵表示了一个和R相反的旋转
  • 旋转矩阵R通常和平移向量t一起组成齐次的变换矩阵T,描述了欧氏坐标变换

欧拉角

欧拉角遵循的是右手系规则,即大拇指指向坐标轴正方向,四指旋转的方向即为转动的正方向,欧拉角包含三个自由量:yaw(偏航角)、pitch(俯仰角)、roll(翻滚角)。
偏航角:绕z轴旋转, 得到偏航角
俯仰角:绕y轴旋转, 得到俯仰角
翻滚角:绕x轴旋转, 得到翻滚角

欧拉角可以与旋转矩阵相互转换,以最上图片为例:

opencv水平翻转_旋转矩阵_05


若是在三维坐标上,假设刚刚是绕z轴旋转,依据“绕谁谁不变”的原则:

opencv水平翻转_旋转矩阵_06


同样的:

opencv水平翻转_线性代数_07


欧拉角在SLAM中用的很少,原因是它的一个致命缺点:万向锁。也就是在俯仰角为±90°时,第一次和第3次旋转使用的是同一个坐标轴,会丢失一个自由度,引起奇异性。事实上,想要表达三维旋转,至少需要4个变量。

由此便引出四元数。

opencv水平翻转_线性代数_08

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中它们之间的转化非常的方便。下图是我看的别人总结的旋转矩阵、四元素、旋转向量之间的相互转化图:

opencv水平翻转_旋转矩阵_09

Eigen 头文件&头文件中的类的作用

opencv水平翻转_线性代数_10