在一个多视点计算机视觉系统里,系统输入除了多个视角的图像外,一般还需要输入对应视角下相机的内外参数。其中,相机内参数决定了图像坐标系和相机三维坐标系的映射关系,而相机外参数则决定了相机三维坐标系和世界坐标系的对应关系。这两组对应关系描述了多视几何的数学基础。
先明确三个概念:1. 图像坐标:像素值的坐标x,y,最多附带一个原点平移(左上角–>图像中心);2. 相机三维坐标系:以图像二维坐标系扩到三维,其中垂直图像外面向外的为z轴,通常以光心作为原点;3. 世界坐标系:每个视点都有自己的独立坐标系,需要投射到同一个坐标系,即世界坐标系。
我们可以通过“小孔成像”原理轻松求解出利用相机内参数求解图像坐标和相机三维坐标系的映射关系,详情可戳《【AI数学】相机成像之内参数》。本文主要讲解相机外参数的作用,即相机坐标系对世界坐标系对映射关系。
图片来自(https://ftp.cs.toronto.edu/pub/psala/VM/camera-parameters.pdf)
现在有两个坐标系 A A A和 B B B,空间上有一个点 P P P, P P P在坐标系 A A A和坐标系 B B B上都有一个坐标。假如 P P P在坐标系 A A A中点的坐标为 P A = ( x A , y A , z A ) \bold{P_A}=(x_A,y_A,z_A) PA=(xA,yA,zA),在坐标系 B B B中的坐标为 P B = ( x B , y B , z B ) \bold{P_B}=(x_B,y_B,z_B) PB=(xB,yB,zB)。那么 P A \bold{P_A} PA和 P B \bold{P_B} PB满足什么关系呢?
所谓坐标系,无非就是一组正交基。假如坐标系 A A A的单位正交基为 ( a 1 ⃗ , a 2 ⃗ , a 3 ⃗ ) (\vec{a_1}, \vec{a_2}, \vec{a_3}) (a1,a2,a3),坐标系 B B B的单位正交基为 ( b 1 ⃗ , b 2 ⃗ , b 3 ⃗ ) (\vec{b_1}, \vec{b_2}, \vec{b_3}) (b1,b2,b3)。这些单位正交基,都可以在同一个坐标系表示出来,只需选定一个确切的坐标系即可,我们无论选坐标系 A A A、坐标系 B B B或者其他坐标系都是可以的,被选定的坐标系我们通常称为“世界坐标系”。由此,我们可以发现,我们选来表示其他坐标系的单位正交基的公用坐标系就是世界坐标系。
那么,空间中一点
P
P
P的向量可以表示为:
[
a
1
⃗
,
a
2
⃗
,
a
3
⃗
]
⋅
[
x
A
y
A
z
A
]
\begin{bmatrix} \vec{a_1} , \vec{a_2} , \vec{a_3} \end{bmatrix} \cdot {\begin{bmatrix} x_A \\ y_A \\ z_A \end{bmatrix}}
[a1,a2,a3]⋅
xAyAzA
也可以表示为:
[
b
1
⃗
,
b
2
⃗
,
b
3
⃗
]
⋅
[
x
B
y
B
z
B
]
\begin{bmatrix} \vec{b_1} , \vec{b_2} , \vec{b_3} \end{bmatrix} \cdot {\begin{bmatrix} x_B \\ y_B \\ z_B \end{bmatrix}}
[b1,b2,b3]⋅
xByBzB
二者有相等(假设两个坐标系原点重合)关系。
[
a
1
⃗
,
a
2
⃗
,
a
3
⃗
]
⋅
[
x
A
y
A
z
A
]
=
[
b
1
⃗
,
b
2
⃗
,
b
3
⃗
]
⋅
[
x
B
y
B
z
B
]
(1)
\begin{bmatrix} \vec{a_1} , \vec{a_2} , \vec{a_3} \end{bmatrix} \cdot {\begin{bmatrix} x_A \\ y_A \\ z_A \end{bmatrix}}=\begin{bmatrix} \vec{b_1} , \vec{b_2} , \vec{b_3} \end{bmatrix} \cdot {\begin{bmatrix} x_B \\ y_B \\ z_B \end{bmatrix}}\tag{1}
[a1,a2,a3]⋅
xAyAzA
=[b1,b2,b3]⋅
xByBzB
(1)
对公示(1)两边同时左乘
[
a
1
T
⃗
a
2
T
⃗
a
3
T
⃗
]
\begin{bmatrix} \vec{a^T_1} \\ \vec{a^T_2} \\ \vec{a^T_3} \end{bmatrix}
a1Ta2Ta3T
,则可以将左边的系数化为单位矩阵,变换可得:
[
x
A
y
A
z
A
]
=
[
a
1
T
⃗
b
1
⃗
a
1
T
⃗
b
2
⃗
a
1
T
⃗
b
3
⃗
a
2
T
⃗
b
1
⃗
a
2
T
⃗
b
2
⃗
a
2
T
⃗
b
3
⃗
a
3
T
⃗
b
1
⃗
a
3
T
⃗
b
2
⃗
a
3
T
⃗
b
3
⃗
]
[
x
B
y
B
z
B
]
(2)
\begin{bmatrix} x_A \\ y_A \\ z_A \end{bmatrix}=\begin{bmatrix} \vec{a^T_1}\vec{b_1} & \vec{a^T_1}\vec{b_2} & \vec{a^T_1}\vec{b_3} \\ \vec{a^T_2}\vec{b_1} & \vec{a^T_2}\vec{b_2} & \vec{a^T_2}\vec{b_3} \\ \vec{a^T_3}\vec{b_1} & \vec{a^T_3}\vec{b_2} & \vec{a^T_3}\vec{b_3} \end{bmatrix} \begin{bmatrix} x_B \\ y_B \\ z_B \end{bmatrix}\tag{2}
xAyAzA
=
a1Tb1a2Tb1a3Tb1a1Tb2a2Tb2a3Tb2a1Tb3a2Tb3a3Tb3
xByBzB
(2)
我们用字母来代替公式(2),可得:
P
A
=
R
P
B
(3)
\bold{P_A}=\bold{R}\bold{P_B}\tag{3}
PA=RPB(3)
公式(3)中的
R
\bold{R}
R被称为旋转矩阵。旋转矩阵
R
\bold{R}
R是一个行列式为1的正交矩阵,满足
R
−
1
=
R
T
\bold{R^{-1}}=\bold{R^T}
R−1=RT。所以有
P
B
=
R
−
1
P
A
=
R
T
P
A
(4)
\bold{P_B}=\bold{R^{-1}}\bold{P_A}=\bold{R^T}\bold{P_A}\tag{4}
PB=R−1PA=RTPA(4)
R
\bold{R}
R只定义了旋转,公式(3)满足两个坐标系原点相同的情况下的坐标换算。假设两个坐标系的原点并不重合,我们则需要对其进行平移。加一个三维的平移矩阵
T
\bold{T}
T即可:
P
B
=
R
T
P
A
+
T
(5)
\bold{P_B}=\bold{R^T}\bold{P_A}+\bold{T}\tag{5}
PB=RTPA+T(5)
公式(5)完成的是,两个坐标系(
A
A
A和
B
B
B)换算,我们称为相对位姿换算。如果把任意坐标系转换为世界坐标系,我们就称为绝对位姿换算。我们不难推出绝对位姿的换算方法,首先,我们把世界坐标系原点平移到相机坐标系:
P
w
^
=
P
w
−
C
(6)
\bold{\hat{P_w}=P_w -C}\tag{6}
Pw^=Pw−C(6)
其中,
C
\bold{C}
C为两个坐标系原点的偏移量。根据公式(3)我们可以得到:
P
c
a
m
=
R
P
w
^
=
R
(
P
w
−
C
)
=
R
P
w
−
R
C
=
R
P
w
+
T
(7)
\bold{P_{cam}} = \bold{R\hat{P_w}}=\bold{R(P_w - C)}=\bold{RP_w}-\bold{RC}=\bold{RP_w}+\bold{T}\tag{7}
Pcam=RPw^=R(Pw−C)=RPw−RC=RPw+T(7)
公式(7)就是本文的精髓:从世界坐标系中算出相机坐标系的坐标。其中
T
=
−
R
C
(8)
\bold{T}=-\bold{R}\bold{C}\tag{8}
T=−RC(8)
C
=
−
R
T
T
(9)
\bold{C}=-\bold{R^TT}\tag{9}
C=−RTT(9)
通过公式(7),我们就可以将相机坐标系中的点换算到世界坐标系了。这里的
R
\bold{R}
R和
T
\bold{T}
T就是我们的相机外参数了。通常表示为一个
3
×
4
3\times4
3×4的矩阵:
E
=
(
R
T
)
(10)
\bold{E}=(\bold{R} \ \bold{T})\tag{10}
E=(R T)(10)
如果需要从相机坐标系换算出世界坐标系,可依照
P
w
=
R
T
(
P
c
a
m
−
T
)
(11)
\bold{P_w=R^T(P_{cam}-T)}\tag{11}
Pw=RT(Pcam−T)(11)
本文全部公式为皆为手动推理,若有疑问或指教可留言交流~
实验
一个小实验,帮助理解公式(10)中的 T \bold{T} T。
取一组外参数,改变平移参数的值,实现效果:
代码如下(横向移动):
for i in trange(0, 30):
pose = torch.Tensor([[1, 0, 0, 0.0+(i / 100)],
[0, .5, -0.86603, -3.4641],
[0, 0.86603, .5, 2 ],
[0, 0, 0, 1]])
注意看,代码里改变的是哪个数值。
同理,我们可以用下列代码:
for i in trange(0, 30):
pose = torch.Tensor([[1, 0, 0, 0.0],
[0, .5, -0.86603, -3.4641+(i / 100)],
[0, 0.86603, .5, 2 ],
[0, 0, 0, 1]])
实现:(前后移动)
用下列代码实现上下移动:文章来源:https://www.toymoban.com/news/detail-486763.html
for i in trange(0, 30):
pose = torch.Tensor([[1, 0, 0, 0.0],
[0, .5, -0.86603, -3.4641,
[0, 0.86603, .5, 2+(i / 100)]],
[0, 0, 0, 1]])
效果:
文章来源地址https://www.toymoban.com/news/detail-486763.html
到了这里,关于【AI数学】相机成像之外参数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!