这一部分主要讲解相机的标定在matlab中的具体实现方法。
由于特殊原因,现在实现的具体代码找不到了,我会在以后重新补上。
相机矩阵的计算运用了一个很重要的方法,叫做DLT (Direct Linear Transform),即“直接线性变换”。这种方法的核心思维就是将所求矩阵转化成一个列向量,即将AB=0(A,B都是矩阵)转化成A‘b=0,这里b变成了一个向量,但是它储存的信息并没有减少,比如假设B是5x6的矩阵,那么b就是30x1的向量。这种方法的作用是巨大的,简单一点说,DLT的作用就是通过重组方程,得到一种比较好求解的形式。原本要求解AB=0方程中的矩阵B,现在要求解A’b=0中的向量b,即矩阵A’的right null space(零空间)。
补充完方法后,现在进入正题
x=PX即投影方程,我们的目的是从这个方程中解出P,即相机矩阵。PX的运算结果是一个向量,即x,那么我们就可以运用向量的Cross Product(叉积)来构造方程。显然一个向量与自己的叉积是为零的。
接下来,将对应的值代入。注意在三维空间的线性代数中,有一个convention(不成文但大家都遵循的规则),即任意一个向量a,默认其为列向量。所以在PX的展开式中,可以看到,其实p1,p2,p3应该代表行向量,分别表示矩阵P的1,2,3行,它们储存的信息是一行的信息,但是只要用p1来表示一个向量,它就是列向量。所以我们强行要表示行向量的时候,就要用它的transpose(转置),即p1T
接下来对得到的乘积进行重组,得到了上图的结果。注意,这时候p1,p2,p3是列向量,所以Ap=0中的p已经满足了DLT的要求,即变成了一个列向量。
这一步乍一看好像没啥大变化,实际作用是舍去了一个无用的方程。因为方程Ap=0一定是有Non-trivial Solution(即非零解)的,也就是说明矩阵A的所有行之间是Linear Dependent(非线性独立)。换句话说,看似方程Ap=0是由三个方程构成的,其实这三个方程中的任意一个都能用另外两个的Linear Combination(线性组合)来表示出来,所以实际有意义的只有两个方程。换句话说,一组三维与二维点能够提供两个方程,在上一篇文章中讲过,相机矩阵P有11个自由度,所以我们需要11个方程来解P,显然就要拿到6组对应点,但实际上最后一组点只要一个方程就够了。
现在拿到了方程,就剩下解方程了,只要求解矩阵A的right null space,就能拿到向量p。
SVD是线性代数中很重要的一个方法,也是matlab中的一个很基本的函数。这里我们运用SVD方法来求解一个矩阵的null space(零空间)。
关于SVD的具体理论知识我就不讲了,可以参考百度或者Wiki,或者看线性代数的教材。这里只讲如何运用SVD。
SVD可以将一个m x n的矩阵A分解成三个矩阵的乘积,即 A=UDV*
求解矩阵A的null space,即从矩阵V的列向量来构造。
因为方程Ap=0中的矩阵A是一个11x12的矩阵,并且每一行之间都是线性独立的,根据等量关系
Rank (Null (A)) = (Number of columns) - Rank (A)
即一个矩阵对应的零空间的秩等于它的行数减去它本身的秩。
所以可以得到,矩阵A的零空间的秩即为12-11=1,也就是说A的零空间是一个一维的空间。
所以SVD结果中矩阵V的最后一列,一个12x1的列向量,即为矩阵A的零空间的基底。换句话说,如果用V12来表示矩阵V的最后一列的话,aV12(a为任意常数)就可以表示整个A的null space。所以我们只要拿到V12,就能算作一个合理的向量p的解,因为相机矩阵P本身具有scale ambiguity(上篇文章中介绍过,产生的原因是齐次坐标的性质),所以V12乘任意一个常数都是一个合理的解。为了统一解的结果,一般会用Normalization,即将向量p的模化为单位量1,然后重新组合向量p得到相机矩阵P。
这部分的最后再讲解一下SVD更一般化的用法。
SVD求解null space的时候,结果中的矩阵V的最后a个向量(a取决于null space的维数)作为基底张成的空间,即为null space
具体来说,这个问题因为null space是一维的,所以只要取最后一个向量,以它张成的空间,即为所求的null space,这是最简单的情况
在以后求解Relative Pose的时候,会遇到多维的null space。假如null space是二维的,就要用向量Vn(最后一个向量)和Vn-1(倒数第二个向量)作为基底
所求的null space便为 (aVn + bVn-1),这里a和b是两个任意常数,需要用额外的constraint来确定a和b的值。
拿到相机矩阵后,首先求解相机中心C,即在参考坐标中所标定相机的相机中心的空间坐标
这里用到的是一个常识,每一个空间点投影在相机中会对应一个二维点坐标,如果一个相机的中心投影在它本身的平面的上,对应的点即为平面点原点。所以 PC = 0。
这时候我觉得你应该想到怎么求解C了吧,C不就是矩阵P的null space吗,而且矩阵P不是满秩,Rank (P) = 2,那么对应的P的null space就是一维的,也就是最简单的情况。
用SVD求解C是一种线性代数的方案,这里给出了另一种普通代数方案,至于怎么得出的这个解的形式我就不讲了。如果SVD还不太会用的话可以直接套这个公式。
在求解之前,同样,我们先观察一下。
有了这些性质,求解过程就容易一些了。
对于这种情况,需要用到另一个线性代数的方法,RQ-Decomposition。但是matlab中没有这个函数,不过有它的“好朋友”QR-Decomposition
因为这个方法相对较难理解,同理,这里也有简单的代数方案。
相机矩阵P可以表示称上图的形式,因为C已经解出来了,所以M只要通过P的最后一列就能求出,接下来的运算都围绕M展开。
旋转矩阵R也可以分解成x,y和z三个不同的分量
直接套用上图公式,便可求的绕x旋转的分量。同理,Ry和Rz的公式给出在下图
最终旋转矩阵R可以有其三个分量的乘积求出,然后利用下图公式,便可求出内部矩阵
-------------------------------------------------------------------
到此为止相机的标定就结束了,简单小结一下,相机的标定并不是很难,这部分最重要的就是DLT和SVD,这两个方法在后续的学习中会继续使用,一定要融会贯通。
关于具体实现代码,请移步我的Github页面https://github.com/DzReal/Camera-Calibration-MATLAB