相机坐标变换
世界坐标系指的是系统的绝对坐标,原点是固定的。
相机坐标就是世界坐标根据相机的当前位姿(pos) 变换到相机坐标系下的结果。这个相机位姿包含了旋转矩阵 R R R 和平移向量 t t t。相机位姿 R R R , t t t 称为相机外参。
像素坐标与成像平面的区别就是,像素坐标的原点在图像的左上角,它与成像平面之间相差了一个缩放和一个原点的平移。
再说相机内参,只需要知道它是一组参数 ( f x , f y , c x , c y ) (f_x, f_y, c_x, c_y) (fx,fy,cx,cy),其中 f x , f y , c x , c y f_x, f_y, c_x, c_y fx,fy,cx,cy单位都是像素,具体什么意义后面解释。
相机外参由于是相机的位姿,它会随着相机的运动而改变,但是相机内参是不变的。相机外参的估计可以用视觉里程计,相机内参在相机出厂之后是固定的,有的生产厂商会告诉你相机内参,有时需要自己标定(如棋盘格标定法)。
下面以针孔模型相机来说明上面这些概念的关系。
上面的
P
P
P 是相机坐标系下的坐标
(
X
,
Y
,
Z
)
(X, Y, Z)
(X,Y,Z)。
经过小孔
O
O
O 投影之后到成像平面
O
’
−
x
’
−
y
’
O’-x’-y’
O’−x’−y’上的点
P
’
P’
P’ ,
P
’
P’
P’ 的坐标为
[
X
’
,
Y
’
,
Z
’
]
[X’, Y’, Z’]
[X’,Y’,Z’]。
小孔成的是倒像,所以
Z
f
=
−
X
X
′
=
−
Y
Y
′
\frac{Z}{f} = -\frac{X}{X^{\prime}} = -\frac{Y}{Y^{\prime}}
fZ=−X′X=−Y′Y ,其中
f
f
f 表示焦距。因为实际相机得到的图像并不是倒像,把负号去掉,得到
Z
f
=
X
X
′
=
Y
Y
′
\frac{Z}{f} = \frac{X}{X'} = \frac{Y}{Y'}
fZ=X′X=Y′Y,整理一下,得到
X
′
=
f
X
Z
,
Y
′
=
f
Y
Z
X'=f\frac XZ ,\quad Y'=f\frac YZ
X′=fZX,Y′=fZY
(
X
,
Y
,
Z
)
(X, Y, Z)
(X,Y,Z) 和
(
X
’
,
Y
’
)
(X’, Y’)
(X’,Y’) 这俩坐标的单位可以理解为米,
不过在相机中我们最终获得的是一个个的像素,
所以成像平面上固定着一个像素平面 o − u − v o-u-v o−u−v, 像素坐标用 [ u , v ] [u, v] [u,v] 表示,成像平面上是 [ X ’ , Y ’ ] [X’, Y’] [X’,Y’]。
像素坐标系的原点在图像的左上角, u u u 轴与 x x x 轴平行, v v v 轴与 y y y 轴平行,像素坐标与成像平面之间,相差了一个缩放和一个原点的平移,设在 u u u 轴上缩放了 α \alpha α 倍, v v v 轴上缩放了 β \beta β 倍,所以呢,得到 u = α X ′ + c x , v = β Y ′ + c y u=\alpha X'+c_x ,\quad v=\beta Y'+c_y u=αX′+cx,v=βY′+cy
把上面(1)式代进来,同时,令
f
x
=
α
f
f
y
=
β
f
f_{x}=\alpha f\quad f_{y}=\beta f
fx=αffy=βf , 得到
u
=
f
x
X
Z
+
c
x
,
v
=
f
y
Y
Z
+
c
y
u=f_x\frac{X}{Z} +c_x ,\quad v=f_y\frac{Y}{Z} +c_y
u=fxZX+cx,v=fyZY+cy
好了,这个式子足够用了,其中
(
f
x
,
f
y
,
c
x
,
c
y
)
(f_x, f_y, c_x, c_y)
(fx,fy,cx,cy) 就是相机内参。当你知道一个点的三维坐标(相机坐标系下,
Z
Z
Z 是深度),用上面的(2)式就可以求出它在图像中的像素坐标。
那相机外参 ( R , t ) (R,t) (R,t) 有什么用呢,举个例子吧,现在有相机1 ( R 1 , t 1 ) (R_1, t_1) (R1,t1) 拍下的图像 I 1 I_1 I1,然后有一个不同视角的相机2 ( R 2 , t 2 ) (R_2,t_2) (R2,t2) 拍下了图像 I 2 I_2 I2,已知 $I_1 $ 中的一个特征点 p 1 p_1 p1,那这个 p p p 应该对应 I 2 I_2 I2 的哪个点呢(怎么找到 p 2 p_2 p2)。
首先利用 ( R 1 , t 1 ) (R_1,t_1) (R1,t1) 把 p 1 p_1 p1 转到世界坐标系,再用 ( R 2 , t 2 ) (R_2, t_2) (R2,t2) 把世界坐标转为相机2下的 p 2 p_2 p2 坐标。
有的相机位姿并没有给 R R R ,而是 ( q w , q x , q y , q z , t x , t y , t z ) (q_w, q_x, q_y, q_z, t_x, t_y, t_z) (qw,qx,qy,qz,tx,ty,tz) 的形式,这就需要把四元数 ( q w , q x , q y , q z ) (q_w, q_x, q_y, q_z) (qw,qx,qy,qz) 转为 R R R,再由 ( R , t ) (R,t) (R,t) 得到转换矩阵 T T T。
整体思路:
- p 1 p_1 p1 在图片 I 1 I_1 I1 上,是像素坐标系,根据camera1的内参把它转到camera1的相机坐标系,得到 ( x c 1 , y c 1 , z c 1 ) (x_{c1}, y_{c1}, z_{c1}) (xc1,yc1,zc1),
- 根据camera1的外参把 ( x c 1 , y c 1 , z c 1 ) (x_{c1}, y_{c1}, z_{c1}) (xc1,yc1,zc1) 转到 世界坐标系,得到上图中的P点坐标 ( x w 1 , y w 1 , z w 1 ) (x_{w1}, y_{w1}, z_{w1}) (xw1,yw1,zw1),
- 根据camera2的外参把P点 ( x w 1 , y w 1 , z w 1 ) (x_{w1}, y_{w1}, z_{w1}) (xw1,yw1,zw1) 转到camera2的相机坐标系,得到 ( x c 2 , y c 2 , z c 2 ) (x_{c2}, y_{c2}, z_{c2}) (xc2,yc2,zc2) .
- 最后根据camera2的内参 把 ( x c 2 , y c 2 , z c 2 ) (x_{c2}, y_{c2}, z_{c2}) (xc2,yc2,zc2) 转到像素坐标系,得到图像 I 2 I_2 I2 上的 p 2 p_2 p2 点坐标 ( x 2 , y 2 ) (x_2, y_2) (x2,y2).
整个坐标系的转换关系:像素1 -> 相机1 -> 世界 -> 相机2 -> 像素2
其中,像素坐标系为2D,其他都是3D。
具体步骤:
(1). p1 像素坐标 --> 相机1 坐标
这两个坐标系的关系由相机内参决定,相机内参
(
f
x
,
f
y
,
c
x
,
c
y
)
(f_x, f_y, c_x, c_y)
(fx,fy,cx,cy),假设像素坐标为
(
x
1
,
y
1
)
(x_1, y_1)
(x1,y1), 相机1坐标为
(
x
c
1
,
y
c
1
,
z
c
1
)
(x_{c1}, y_{c1}, z_{c1})
(xc1,yc1,zc1) , 其中
z
c
1
z_{c1}
zc1 为
I
1
I_1
I1 的深度图
(
x
c
1
,
y
c
1
)
(x_{c1}, y_{c1})
(xc1,yc1) 处的值,那么
x
1
=
f
x
x
c
1
z
c
1
+
c
x
,
y
1
=
f
y
y
c
1
z
c
1
+
c
y
x_1 = f_x \frac{x_{c1}}{z_{c1}} + c_x ,\quad y_1 = f_y \frac{y_{c1}}{z_{c1}} + c_y
x1=fxzc1xc1+cx,y1=fyzc1yc1+cy
现在要求
x
c
1
x_{c1}
xc1 和
y
c
1
y_{c1}
yc1, 由(3)得到
x
c
1
=
(
x
1
−
c
x
)
∗
z
c
1
/
f
x
y
c
1
=
(
y
1
−
c
y
)
∗
z
c
1
/
f
y
x_{c1}=(x_1-c_x)*z_{c1}/f_x\quad y_{c1}=(y_1-c_y)*z_{c1}/f_y
xc1=(x1−cx)∗zc1/fxyc1=(y1−cy)∗zc1/fy
(2). p1 的相机1 坐标 --> 世界坐标
转换关系: 相机坐标 = T * 世界坐标, 世界坐标 = T-1 * 相机坐标,其中 T 为world -> camera的转换矩阵。
如何求得转换矩阵 T ?先从概念介绍开始,
旋转矩阵R :3 * 3矩阵
平移向量 t : 3 * 1矩阵
把R 和 t 拼成转换矩阵 T :4 * 4矩阵, T = [ R t 0 T 1 ] T=\begin{bmatrix}R&&t\\0^T&&1\end{bmatrix} T=[R0Tt1]
顺便提一下李群李代数,T是SE(3), R是SO(3).
话题回到坐标, ( x c 1 , y c 1 , z c 1 ) (x_{c1}, y_{c1}, z_{c1}) (xc1,yc1,zc1) 为相机1坐标, ( x w , y w , z w ) (x_w, y_w, z_w) (xw,yw,zw) 为世界坐标,那么世界坐标转相机坐标为:
[
x
c
1
y
c
1
z
c
1
1
]
=
T
⋅
[
x
w
y
w
z
w
1
]
\left[\begin{array}{c}x_{c1}\\y_{c1}\\z_{c1}\\1\end{array}\right]=T\cdot\left[\begin{array}{c}x_w\\y_w\\z_w\\1\end{array}\right]
xc1yc1zc11
=T⋅
xwywzw1
你肯定很好奇,为什么要加一维呢?
如果 T T T 不加最后一行的 [ 0 T 1 ] \begin{bmatrix}0^T&1\end{bmatrix} [0T1],坐标也不加最后一维的 1 1 1,直接 T = [ R t ] T=\begin{bmatrix}R&t\end{bmatrix} T=[Rt] 也能计算,为什么一定要加一维? [ x c y c z c ] = T ⋅ [ x w y w z w ] \begin{bmatrix}x_c\\y_c\\z_c\end{bmatrix}=T\cdot\begin{bmatrix}x_w\\y_w\\z_w\end{bmatrix} xcyczc =T⋅ xwywzw , 这里 T = [ R t ] T=\begin{bmatrix}R&t\end{bmatrix} T=[Rt]
是这样的,现在是从 世界坐标 转 相机1坐标 ,如果要把 相机1坐标 转 世界坐标 呢?(我们现在要做的就是把 p 1 p_1 p1 的 相机1坐标 转到 世界坐标。)
那就需要这么计算了,
[ x w y w z w ] = T − 1 ⋅ [ x c y c z c ] \begin{bmatrix}x_w\\y_w\\z_w\end{bmatrix}=T^{-1}\cdot\begin{bmatrix}x_c\\y_c\\z_c\end{bmatrix} xwywzw =T−1⋅ xcyczc ,这里 T = [ R t ] T=\begin{bmatrix}R&t\end{bmatrix} T=[Rt],无法求逆矩阵
求 T T T 的逆矩阵, T T T 必须是square(行数 = 列数)的,不能是3 * 4, 必须是4 * 4的。
所以加上一行,凑成 4 * 4 矩阵$ T=\begin{bmatrix}R&&t\0^T&&1\end{bmatrix}$
那么 相机坐标 --> 世界坐标 就变为:
[
x
w
y
w
z
w
1
]
=
T
−
1
⋅
[
x
c
y
c
z
c
1
]
\begin{bmatrix}x_w\\y_w\\z_w\\1\end{bmatrix}=T^{-1}\cdot\begin{bmatrix}x_c\\y_c\\z_c\\1\end{bmatrix}
xwywzw1
=T−1⋅
xcyczc1
有的程序中会使用
T
w
c
T_{wc}
Twc,
T
w
c
T_{wc}
Twc 这样的称呼,这里
w
w
w 指world, 是世界坐标,
c
c
c 指camera, 是相机坐标。
T
T
T 表示转换矩阵,至于
T
w
c
T_{wc}
Twc 是world转camera 还是camera转world, 需要根据实际情况而定(每个开发者习惯不一样)。
实际中,到了这里估计还是不知如何计算 T T T,问题在哪呢?
我们拿到的 相机外参 一般会是一个四元数+平移向量的形式,其中并没有 R R R 矩阵。相机外参: ( q w , q x , q y , q z , t x , t y , t z ) (q_w, q_x, q_y, q_z, t_x, t_y, t_z) (qw,qx,qy,qz,tx,ty,tz), (这个顺序要根据实际情况而定,有的相机顺序并不是这样)。这里用四元数 q = ( q w , q x , q y , q z ) q = (q_w, q_x, q_y, q_z) q=(qw,qx,qy,qz) 代替了 R R R 矩阵,原因在于 R R R 是3 * 3矩阵,有9个量,而一次旋转只有3个自由度,这种表达方式是冗余的,四元数的表达更紧凑。
上面是涉及到的相关概念,现在开始计算 T T T。
现在要先把 q q q 转为 R R R,再由 ( R , t ) (R,t) (R,t) 得到 T T T。 q = ( q w , q x , q y , q z ) q = (q_w, q_x, q_y, q_z) q=(qw,qx,qy,qz), (一定是 q w , q x , q y , q z q_w, q_x, q_y ,q_z qw,qx,qy,qz 的顺序,不是的先调整到这个顺序)
t = ( t x , t y , t z ) t = (t_x, t_y, t_z) t=(tx,ty,tz), 这里要注意 t t t 的单位,如果是mm, 需要 / 1000.0.
直接计算的话,由四元数
q
q
q 到旋转矩阵
R
R
R 的公式为:
R
=
[
1
−
2
q
2
2
−
2
q
3
2
2
q
1
q
2
−
2
q
0
q
3
2
q
1
q
3
+
2
q
0
q
2
2
q
1
q
2
+
2
q
0
q
3
1
−
2
q
1
2
−
2
q
3
2
2
q
2
q
3
−
2
q
0
q
1
2
q
1
q
3
−
2
q
0
q
2
2
q
2
q
3
+
2
q
0
q
1
1
−
2
q
1
2
−
2
q
2
2
]
\mathbf{R}=\begin{bmatrix}1-2q_2^2-2q_3^2&2q_1q_2-2q_0q_3&2q_1q_3+2q_0q_2\\2q_1q_2+2q_0q_3&1-2q_1^2-2q_3^2&2q_2q_3-2q_0q_1\\2q_1q_3-2q_0q_2&2q_2q_3+2q_0q_1 & 1-2q_1^2-2q_2^2\end{bmatrix}
R=
1−2q22−2q322q1q2+2q0q32q1q3−2q0q22q1q2−2q0q31−2q12−2q322q2q3+2q0q12q1q3+2q0q22q2q3−2q0q11−2q12−2q22
这里 q 0 , q 1 , q 2 , q 3 q_0, q_1, q_2, q_3 q0,q1,q2,q3 分别对应 q w , q x , q y , q z q_w, q_x, q_y, q_z qw,qx,qy,qz,结合 ( t x , t y , t z ) (t_x, t_y, t_z) (tx,ty,tz), 下面再加一行 [ 0 T 1 ] \begin{bmatrix}0^T&1\end{bmatrix} [0T1],得到 T 1 T_1 T1 (由相机1的外参得到)。
已经得到了T1,下面可把相机坐标转为世界坐标
[
x
w
y
w
z
w
1
]
=
T
1
−
1
⋅
[
x
c
1
y
c
1
z
c
1
1
]
\begin{bmatrix}x_w\\y_w\\z_w\\1\end{bmatrix}=T_1^{-1}\cdot\begin{bmatrix}x_{c1}\\y_{c1}\\z_{c1}\\1\end{bmatrix}
xwywzw1
=T1−1⋅
xc1yc1zc11
(3). 世界坐标 --> 相机2坐标
上面已经说明了如何由 世界坐标 转 相机坐标。注意上面求的
T
1
T_1
T1 是由相机1的外参得到,这里要用到相机2的外参,camera2: $ (q_{w2}, q_{x2}, q_{y2}, q_{z2}, t_{x2}, t_{y2}, t_{z2})$,求得
T
2
T_2
T2 后,由下式得到
P
P
P 的相机2坐标
[
x
c
2
y
c
2
z
c
2
1
]
=
T
2
⋅
[
x
w
y
w
z
w
1
]
\left[\begin{array}{c}x_{c2}\\y_{c2}\\z_{c2}\\1\end{array}\right]=T_2\cdot\left[\begin{array}{c}x_w\\y_w\\z_w\\1\end{array}\right]
xc2yc2zc21
=T2⋅
xwywzw1
(4) 相机2坐标 --> 像素坐标2
相机内参
(
f
x
,
f
y
,
c
x
,
c
y
)
(f_x, f_y, c_x, c_y)
(fx,fy,cx,cy)
x
2
=
f
x
x
c
2
z
c
2
+
c
x
,
y
2
=
f
y
y
c
2
z
c
2
+
c
y
x_2 = f_x \frac{x_{c2}}{z_{c2}} + c_x ,\quad y_2 = f_y \frac{y_{c2}}{z_{c2}} + c_y
x2=fxzc2xc2+cx,y2=fyzc2yc2+cy
这样就得到了图像
I
2
I_2
I2 上的映射点
p
2
p_2
p2 的坐标。