前言
由于摄像机标定中会使用到旋转矩阵以及旋转向量的知识,所以就整理了一下有关与这一部分基础知识的笔记,并进行详细的数学推导。
旋转矩阵

假设坐标系分别绕着x轴旋转ϕ角,绕y轴旋转θ角,绕z轴旋转ψ角,这里旋转的角度就是我们常说的pitch, roll, yaw。设任意某点在旋转前的坐标系中的坐标是(x,y,z),旋转后的坐标是(x′,y′,z′)。
我们可以很容易地推导出这三种情况下的旋转矩阵:
Rx=⎣⎡1000cosϕsinϕ0−sinϕcosϕ⎦⎤
Ry=⎣⎡cosθ0−sinθ010sinθ0cosθ⎦⎤
Rz=⎣⎡cosψsinψ0−sinψcosψ0001⎦⎤
详细步骤我就不列出来了,我以前的博客中有详细的推导步骤,虽然使用场景不同,但是概念都是一样的。(四旋翼姿态解算——基础理论及推导)
如果已经上面的三个角度ϕ、θ、ψ,,我们可以通过将每一步的旋转矩阵相乘得到整个旋转矩阵。
R=Rx∗Ry∗Rz
旋转向量
相机标定中表示旋转的方式,除了使用前面介绍的旋转矩阵之外,还可以使用旋转向量来表示。
我在网上搜索相关资料时,发现大多数都是直接给出了Rodrigue旋转向量的公式,而没有推导过程。如果只是拿来用,那肯定是没问题的,但是不把它的公式推导一遍,心里总是有点不踏实。(好吧,我知道我有点废话)下面我会给出我自己的证明步骤,在最后会给出公式。
补充概念:向量的拉格朗日公式
对于任意向量a(a1,a2,a3),b(b1,b2,b3),c(c1,c2,c3),有如下公式成立:
a×(b×c)=(a⋅c)b−(a⋅b)c
证明如下:
设d=b×c,且可表示为d(d1,d2,d3)。
则有:d=b×c=⎣⎡ib1c1jb2c2kb3c3⎦⎤=i(b2c3−b3c2)−j(b1c3−b3c1)+k(b1c2−b2c1)
对应地就有:d1=b2c3−b3c2、d2=b3c1−b1c3、d3=b1c2−b2c1。
再设e=a×d=a×(b×c),且可表示为e(e1,e2,e3)。
那么:e=a×d=⎣⎡ia1d1ja2d2ka3d3⎦⎤=i(a2d3−a3d2)−j(a1d3−a3d1)+k(a1d2−a2d1)
对应地得到得到:e1=a2d3−a3d2、e2=a1d3−a3d1、e3=a1d2−a2d1
对于e1,代入前面推导出来的d2、d3:
e1=a2d3−a3d2=a2(b1c2−b2c1)−a3(b3c1−b1c3)=b1(a2c2+a3c3)−c1(a3b3+a2b2)=b1(a⋅c−a1c1)−c1(a⋅b−a1b1)=b1(a⋅c)−c1(a⋅b)
同理可得:
e2=b2(a⋅c)−c2(a⋅b)
e3=b3(a⋅c)−c3(a⋅b)
把这三个式子合并,表示成向量形式:
e=b(a⋅c)−c(a⋅b)
证明完毕,后面我们还会用到这个公式。

上图摘自维基百科。假设我们在任意空间中有任意一个向量v,k是某个单位向量。现在,我们将向量v以单位向量k为轴,旋转任意角度θ,得到旋转后的向量vrot如图中所示。在图中,我们将v关于k做正交分解(高中物理),会得到两个新的向量:v⊥和v∥。
很明显:v⊥与k相互垂直,v∥与k共线(平行),且还有v=v⊥+v∥。
因为v∥与k共线,且k是一个单位向量,所以:
v∥=∥v∥∥⋅k=∥k∥v⋅k⋅k=(v⋅k)⋅k
接下来求v⊥,由我们前面推导的向量的拉格朗日定理:a×(b×c)=(a⋅c)b−(a⋅b)c,有:
k×(k×v)=(k⋅v)⋅k−(k⋅k)⋅v=(k⋅v)⋅k−v
然后,我们就可以推出:
v⊥=v−v∥=−k×(k×v)
我们可以根据前面给出的示意图来直观地理解这些式子:k×v可以看作是v⊥绕着k逆时针旋转90度得到的,即图中的w=k×v;对于k×(k×v)=k×w,在图中观察发现,这个式子的结果其实就是v⊥绕着k逆时针旋转180度得到的结果,共线且夹角为180度,正好对应推导出的结果:v⊥=−k×(k×v)。
还是根据这幅图来看,旋转过程中v∥的大小始终不变,因为它是v在k方向上的投影,就在旋转轴上,自然不会变。所以有:vrot,∥=v∥。
接下来看vrot,⊥的变化:
首先,可以肯定的是旋转过程中矢量的模长不变,只会改变方向,所以:∥vrot,⊥∥=∥v⊥∥。
我们可以由v⊥和k方向的投影,组合得到vrot,⊥:
vrot,⊥=v⊥cosθ+∥v⊥∥sinθ∥w∥w
前面有:w=k×v可以看作是v⊥绕着k逆时针旋转90度得到的。那么有:∥v⊥∥=∥w∥。
上式可以化简为:
vrot,⊥=v⊥cosθ+sinθw=v⊥cosθ+sinθ(k×v)
将vrot,⊥和vrot,∥相加,即可得到vrot:
vrot=vrot,⊥+vrot,∥=v∥+v⊥cosθ+sinθ(k×v)=v∥+(v−v∥)cosθ+sinθ(k×v)=vcosθ+(1−cosθ)v∥+sinθ(k×v)
前面推出来了:v∥=∥v∥∥⋅k=∥k∥v⋅k⋅k=(v⋅k)⋅k,直接把那个结论代入这里。
vrot=vcosθ+(1−cosθ)(v⋅k)⋅k+sinθ(k×v)
现在我们已经推导出了旋转向量公示了,我们可以套用这个公式来表示任意旋转。
接下来要进一步整理成矩阵形式:
对于k×v,用矩阵形式来表示:(无非就是向量叉乘,拆成三个轴上的分量来表示)
⎣⎢⎡(k×v)x(k×v)y(k×v)z⎦⎥⎤=⎣⎡kyvz−kzvykzvx−kxvzkxvy−kyvx⎦⎤=⎣⎡0kz−ky−kz0kxky−kx0⎦⎤⋅⎣⎡vxvyvz⎦⎤
使用一个大写的K来表示:
K=⎣⎡0kz−ky−kz0kxky−kx0⎦⎤
那么有:Kv=k×v
还有:K(Kv)=K2v=K(k×v)=k×(Kv)=k×(k×v)
公式可以进一步化简为:
vrot=vcosθ+(1−cosθ)(v⋅k)⋅k+sinθ(k×v)=vcosθ+(1−cosθ)(v+k×(k×v))+sinθ(k×v)=v+(1−cosθ)K2v+sinθKv
给出旋转矩阵R有:vrot=Rv
那么消去v:$R = I + (1-\cos\theta)K^2 + sin\theta K $
Rodrigue旋转向量公式
已知单位向量k=(kx,ky,kz),向量v绕着它旋转θ角。旋转后的向量vrot可以通过如下公式求得:
vrot=vcosθ+(1−cosθ)(v⋅k)⋅k+sinθ(k×v)
我们可以把v提取出来,就得到了:
vrot=Rv=(I⋅cosθ+(1−cosθ)k⋅k+sinθK)v
其中:
K=⎣⎡0kz−ky−kz0kxky−kx0⎦⎤
根据上面这个式子,我们可以给出Rodrigue旋转公式:
对于旋转向量r=(rx,ry,rz):

θ为向量r的模长,而且要保证向量r是一个单位向量。
反变换也可以很容易求出:

注:在opencv中有相关的实现(Rodrigues2函数)
当然还有一种写法:
vrot=Rv=I⋅v+(1−cosθ)K2⋅v+sinθK⋅v
对应的旋转矩阵:(我们可以用这个公式来求旋转矩阵)
R=I+(1−cosθ)K2+sinθK
其中:
K=⎣⎡0kz−ky−kz0kxky−kx0⎦⎤
参考链接:
-
http://blog.sina.com.cn/s/blog_5fb3f125010100hp.html
-
https://www.cnblogs.com/xpvincent/archive/2013/02/15/2912836.html
-
Rodrigues旋转向量维基百科
-
http://blog.****.net/tl_tj/article/details/47006007
-
http://wiki.opencv.org.cn/index.php/Cv照相机定标和三维重建#Rodrigues2