摄像机矩阵的分解,求解内外参矩阵(Matlab实现)

1. 应用背景

根据3D点与对应的2D点,能够求解得到摄像机矩阵P, P = K [ R ∣ t ] \rm{P}=\rm{K}[\rm{R}|\rm{t}] P=K[R∣t]摄像机矩阵由内参矩阵 K \rm{K} K, 外参矩阵(包括旋转 R \rm{R} R和平移 t \rm{t} t)组成,需要利用 P P P矩阵来求解具体的三个分量。

2. 实施原理

定义齐次坐标系下:
X \bf{X} X——世界坐标系下三维点坐标,
X c a m \bf{X_{cam}} Xcam​——相机坐标系下三维点坐标,
x \bf{x} x——像平面坐标系下二维点坐标。
P \rm{P} P—— 3 x 4 3\rm{x}4 3x4齐次摄像机投影矩阵
C \rm{C} C——摄像机中心在世界坐标系中的坐标
在其次坐标下,3D点到2D点的关系为 x = P X \bf{x}=\rm{P}\bf{X} x=PX根据坐标变换关系有 x = K [ I ∣ 0 ] X c a m \bf{x}=\rm{K}[\bf{I}|0]\bf{X_{cam}} x=K[I∣0]Xcam​其中 [ I ∣ 0 ] [\bf{I}|0] [I∣0]表示矩阵分块成一个3x3单位矩阵加上一个零列矢量。
定义非齐次坐标下
X ~ \bf{\tilde{X}} X~——世界坐标系下三维点坐标,
X ~ c a m \bf{\tilde{X}_{cam}} X~cam​——相机坐标系下三维点坐标,
x ~ \bf{\tilde{x}} x~——像平面坐标系下二维点坐标。
C ~ \rm{\tilde{C}} C~——摄像机中心在世界坐标系中的坐标
在非齐次下,世界坐标系下的点 X \bf{X} X要转换到相机坐标系下,需要将原点通过平移 C ~ \rm{\tilde{C}} C~进行对齐,然后旋转 R \rm{R} R来转换,该过程可表示为 X ~ c a m = R ( X ~ − C ~ ) = R X ~ + t \bf{\tilde{X}_{cam}}=\rm{R}(\bf{\tilde{X}}-\rm{\tilde{C}})=\rm{R}\bf{\tilde{X}}+\rm{t} X~cam​=R(X~−C~)=RX~+t其中, R \rm{R} R是3x3的旋转矩阵,平移量 t = − R C ~ \rm{t}=-\rm{R}\rm{\tilde{C}} t=−RC~。该方程在齐次坐标下可以写成 X c a m = [ R − R C ~ 0 1 ] X \bf{X_{cam}}=\begin{bmatrix} \rm{R} & -\rm{R}\rm{\tilde{C}} \\ \bf{0} & 1 \\ \end{bmatrix} \bf{X} Xcam​=[R0​−RC~1​]X 与前式结合为 x = K R [ I ∣ − C ~ ] X \bf{x}=\rm{K}\rm{R}[\rm{I}|-\rm{\tilde{C}}]\bf{X} x=KR[I∣−C~]X因此, P = K R [ I ∣ − C ~ ] \rm{P}=\rm{K}\rm{R}[\rm{I}|-\rm{\tilde{C}}] P=KR[I∣−C~]摄像机矩阵分解的目的就是为了得到其中的参数 K \rm{K} K、 R \rm{R} R和 t \rm{t} t。令 P \rm{P} P左边 3 x 3 3\rm{x}3 3x3的子矩阵为 M \rm{M} M,于是 P = M [ I ∣ M − 1 p 4 ] \rm{P}=\rm{M}[\rm{I}|\rm{M^{-1}}\bf{p_4}] P=M[I∣M−1p4​]其中, p 4 \bf{p_4} p4​是 P \rm{P} P的第4列向量,结合上式, M = K R \rm{M}=\rm{K}\rm{R} M=KR,因为内参数矩阵 K \rm{K} K是一个上三角阵,旋转矩阵 R \rm{R} R是一个正交阵,因此, K \rm{K} K和 R \rm{R} R可以由 M \rm{M} M矩阵通过"RQ分解"来获得。而要得到 t \rm{t} t,需要先计算 C ~ \rm{\tilde{C}} C~。摄像机中心 C \rm{C} C是使得 P C = 0 \rm{PC}=0 PC=0的点,中心点 C = ( x , y , z , ω ) T \rm{C}=(x,y,z,\omega)^T C=(x,y,z,ω)T数值分析上可以通过SVD求解,代数上可以通过下面方法得到 x = d e t ( [ p 2 , p 3 , p 4 ] ) y = − d e t ( [ p 1 , p 3 , p 4 ] ) z = d e t ( [ p 1 , p 2 , p 4 ] ) ω = − d e t ( [ p 1 , p 2 , p 3 ] ) \begin{matrix} x=\rm{det}([\bf{p_2},\bf{p_3},\bf{p_4}]) & y=-\rm{det}([\bf{p_1},\bf{p_3},\bf{p_4}]) \\ z=\rm{det}([\bf{p_1},\bf{p_2},\bf{p_4}]) & \omega=-\rm{det}([\bf{p_1},\bf{p_2},\bf{p_3}])\\ \end{matrix} x=det([p2​,p3​,p4​])z=det([p1​,p2​,p4​])​y=−det([p1​,p3​,p4​])ω=−det([p1​,p2​,p3​])​进而 C ~ = ( x / ω , y / ω , z / x / ω ) \rm{\tilde{C}}=(x/\omega,y/\omega,z/x/\omega) C~=(x/ω,y/ω,z/x/ω)由此,就能计算出平移量 t \rm{t} t。

3. RQ分解

RQ分解就是通过对待分解矩阵乘一系列的矩阵的矩阵后得到一个上三角阵’R’(这里的符号与上节代表的含义不同),然后求解正交矩阵。具体地来说,现在要分解P矩阵的子矩阵M,策略就是M右乘一系列的Givens矩阵来求解形如上三角矩阵的内参矩阵K,然后求正交的旋转矩阵R。
三维的Givens旋转是绕三个坐标轴中的一个轴进行的旋转,这三个Givens旋转分别是 Q x Q_x Qx​, Q y Q_y Qy​, Q z Q_z Qz​
Q x = [ 1 0 0 0 c − s 0 s c ] , Q y = [ c 0 s 0 1 0 − s 0 c ] , Q z = [ c − s 0 s c 0 0 0 1 ] Q_x=\begin{bmatrix} 1&0&0\\0&c&-s\\0&s&c \end{bmatrix}, Q_y=\begin{bmatrix} c&0&s\\0&1&0\\-s&0&c \end{bmatrix}, Q_z=\begin{bmatrix} c&-s&0\\s&c&0\\0&0&1 \end{bmatrix} Qx​=⎣⎡​100​0cs​0−sc​⎦⎤​,Qy​=⎣⎡​c0−s​010​s0c​⎦⎤​,Qz​=⎣⎡​cs0​−sc0​001​⎦⎤​其中, c = cos ⁡ ( θ ) c=\cos(\theta) c=cos(θ), s = sin ⁡ ( θ ) s=\sin(\theta) s=sin(θ)。进行“RQ分解”分为如下三步:
3.1 乘 Q x Q_x Qx​使 m 32 {m_{32}} m32​为零,为了使元素 m 32 {m_{32}} m32​为零,需要使得 c m 32 + s m 33 = 0 cm_{32}+sm_{33}=0 cm32​+sm33​=0, 此方程的解是 c = − m 33 / ( m 32 2 + m 33 2 ) ) c=-m_{33}/\sqrt{(m_{32}^2+m_{33}^2))} c=−m33​/(m322​+m332​)) ​, s = m 32 / ( m 32 2 + m 33 2 ) ) s=m_{32}/\sqrt{(m_{32}^2+m_{33}^2))} s=m32​/(m322​+m332​))
3.2 乘 Q y Q_y Qy​使 m 31 {m_{31}} m31​为零,为了使元素 m 31 {m_{31}} m31​为零,需要使得 c m 31 − s m 33 = 0 cm_{31}-sm_{33}=0 cm31​−sm33​=0, 此方程的解是 c = m 33 / ( m 31 2 + m 33 2 ) ) c=m_{33}/\sqrt{(m_{31}^2+m_{33}^2))} c=m33​/(m312​+m332​)) ​, s = m 31 / ( m 31 2 + m 33 2 ) ) s=m_{31}/\sqrt{(m_{31}^2+m_{33}^2))} s=m31​/(m312​+m332​))
3.3 乘 Q z Q_z Qz​使 m 21 {m_{21}} m21​为零,为了使元素 m 21 {m_{21}} m21​为零,需要使得 c m 21 + s m 22 = 0 cm_{21}+sm_{22}=0 cm21​+sm22​=0, 此方程的解是 c = − m 22 / ( m 21 2 + m 22 2 ) ) c=-m_{22}/\sqrt{(m_{21}^2+m_{22}^2))} c=−m22​/(m212​+m222​)) ​, s = m 21 / ( m 21 2 + m 22 2 ) ) s=m_{21}/\sqrt{(m_{21}^2+m_{22}^2))} s=m21​/(m212​+m222​))
由上述三步,将 M \rm{M} M矩阵的 m 21 , m 31 , m 32 m_{21},m_{31},m_{32} m21​,m31​,m32​元素转换为0,由此得到一个上三角阵 K = M Q x Q y Q z \rm{K}=\rm{M}Q_{x}Q_{y}Q_{z} K=MQx​Qy​Qz​因此, M = K Q z T Q y T Q x T \rm{M}=\rm{K}Q_{z}^TQ_{y}^TQ_{x}^T M=KQzT​QyT​QxT​,那么旋转矩阵 R = Q z T Q y T Q x T \rm{R}=Q_{z}^TQ_{y}^TQ_{x}^T R=QzT​QyT​QxT​进一步的平移向量为 t = − R C ~ \rm{t}=-R\rm{\tilde{C}} t=−RC~

4. Matlab实现

%摄像机矩阵分解
clc;clear;close all
p1 = [3.53553e2; -1.03528e2; 7.07107e-1];
p2 = [3.39645e2; 2.33212e1; -3.53553e-1];
p3 = [2.77744e2; 4.59607e2; 6.12372e-1];
p4 = [-1.44946e6; -6.32525e5 ;-9.18559e2];
P = [p1,p2,p3,p4];

x = det([p2,p3,p4]); 
y = -det([p1,p3,p4]);
z = det([p1,p2,p4]);
w = -det([p1,p2,p3]);
C = [x/w;y/w;z/w];
M = P(1:3,1:3);
if det(M) ~= 0
    %乘Qx,使M(3,2)为0
    c = -M(3,3)/sqrt(M(3,2)*M(3,2)+M(3,3)*M(3,3));
    s = M(3,2)/sqrt(M(3,2)*M(3,2)+M(3,3)*M(3,3));
    Qx = [1,0,0; 0,c,-s; 0,s,c];
    M = M*Qx
    %乘Qy,使M(3,1)为0,并且不改变M(3,2)
    c = M(3,3)/sqrt(M(3,1)*M(3,1)+M(3,3)*M(3,3));
    s = M(3,1)/sqrt(M(3,1)*M(3,1)+M(3,3)*M(3,3));
    Qy = [c,0,s; 0,1,0; -s,0,c];
    M = M*Qy
    %乘Qz,使M(2,1)为0,并且不改变M(3,2),M(3,1)
    c = -M(2,2)/sqrt(M(2,1)*M(2,1)+M(2,2)*M(2,2));
    s = M(2,1)/sqrt(M(2,1)*M(2,1)+M(2,2)*M(2,2));
    Qz = [c,-s,0; s,c,0; 0,0,1];
    M = M*Qz
    %上三角阵R=M*Qx*Qy*Qz,正交阵Q=Qz^T*Qy^T*Qx^T
    K = M
    R = Qz'*Qy'*Qx'
end
t = -R*C
上一篇:接口测试平台代码实现33:接口调试


下一篇:【李宏毅2020 ML/DL】P26-33 Explainable ML