我们平常接触到的世界是3维的,但是计算机视觉的研究中,感知到的信息都是二维的图像。从三维的世界到二维的图像的转换通过相机投影完成。这是3d点到2d点映射的过程。
相机模型
设映射前的点为
X
=
[
X
1
,
X
2
,
X
3
]
T
X=[X_1,X_2,X_3]^T
X=[X1,X2,X3]T,得到的图像中的点的像素坐标为
x
=
[
x
1
,
x
2
]
T
x=[x_1,x_2]^T
x=[x1,x2]T。则有
x
=
F
(
X
)
x=F(X)
x=F(X)
F即为相机的成像模型。
常见的相机模型有针孔模型(pinhole camera),全景模型(omnidirectional,即我们一般所说的鱼眼相机)。前者是计算机视觉中应用最广泛的模型,目前的大多数设备可以使用这一模型进行近似,因此这里只介绍针孔相机模型。
针孔相机模型
针孔相机使用小孔成像的原理,模型如图所示。
图中M为世界坐标系一点,R为像面。C为相机光心。成像的过程可以近似的看成从M向C发出一条光线,落在像面的过程。需要注意,这里的像面其实是为了简化模型人为规定的一个平面,通常假设它的到相机的距离为1,称为归一化平面。
按照图中的投影过程,为得到世界坐标系一点 X w X_w Xw在图像上的坐标 x x x,我们需要先得到它在相机坐标系中的坐标
X c = R c w ∗ X w + t c w X_c = Rcw * X_w + tcw Xc=Rcw∗Xw+tcw
通过简单的相似三角形知识,我们可以得到得到 X c X_c Xc在归一化平面上的坐标
X n = X c / X c ( 2 ) X_n = X_c/X_c^{(2)} Xn=Xc/Xc(2)
为将归一化平面上的坐标转换为像素,我们需要使用相机的内参。
相机内参的形式如下
K = [ f x 0 c x 0 f y c y 0 0 1 ] K = \begin{bmatrix} fx & 0 & cx \\ 0 & fy & cy \\ 0 & 0 & 1 \end{bmatrix} K=⎣⎡fx000fy0cxcy1⎦⎤
其中fx,fy是焦距,表征了物理尺寸到像素距离的映射。在相机坐标系中一般认为光心在原点,而在图像中坐标系原点在左上角,因此在这里需要进行一个变换。我们使用cx,cy表示光心在图像中的偏移。
相机内参一般通过标定获得或者预先从摄像头厂家获得,给定相机内参,我们可以算出 X n X_n Xn对应的图像中的位置 X i m g = K X n X_{img} = KX_n Ximg=KXn,这是一个三维向量,我们通常使用的 x = ( u , v ) = X i m g [ 0 : 2 ] x = (u,v) = X_{img}[0:2] x=(u,v)=Ximg[0:2]
由此我们得到了相机的投影模型。原则上可以将这几步合并起来得到一个表达式,读者可以自行推导。
像差
实际情况中我们使用的并非针孔而是透镜进行投影成像。也由此引入了各种误差。由这些误差在成像上的表现被称为像差,在颜色上的误差成为色差。
常见的像差包括球差、 彗差、 像散、 场曲、 畸变。反应到具体应用中我们一般只关心畸变。下图是常见的畸变形式
通过对相机进行标定,我们可以有效去除这些畸变。具体的方法这里不再赘述。
有几个人私聊我催更SLAM系列,我本来是想写的,但是看了下得先讲相机模型,再讲对极几何和点的跟踪,然后才能讲SLAM中的前端部分。