相机成像原理
下图就是相机的成像原理,图像中的被摄点 (x,y),在现实中的位置可以是该点和相机连成的直线上的任意位置。

如果要确定被摄点在现实中的位置,需要两个相机从不同角度同时拍摄,如下图所示,(C1,P1)、(C2,P2) 两条直线相交于 P 点,即被摄点在现实中的位置。

坐标系
相机坐标系 & 世界坐标系
上图中的画出的两个坐标系称为相机坐标系,以相机在现实中的位置 C1、C2 为原点。
P 所处的坐标系称为世界坐标系,原点位置可以任选,例如可以将右相机坐标系当作世界坐标系,以 C2 为原点。
投影坐标系 & 图像坐标系
上图中画出的 P1、P2 所在的平面上的坐标系称为投影坐标系,以物理尺寸为单位;拍摄得到的图像上的坐标系称为图像坐标系,以像素为单位。
图像其实就是数组,数组中的元素就是像素,彩色图用3个整型值描述1个像素,灰度图用1个整型值描述1个像素。

图中 O0 为图像坐标系,原点为图像左上角像素位置;O1 为投影坐标系,原点为像主点 (u0,v0) 位置。
像主点就是相机坐标系原点到成像平面的垂点,即图二中 z 轴与成像平面的交点。
坐标转换
通过被摄点的两个图像坐标得到被摄点的世界坐标,就是立体视觉。
图像 ⇌ 投影
设单个像素对应到相机的感光平面上的物理尺寸为 (dx,dy),像主点在图像坐标系中的坐标为 (u0,v0),则有投影坐标 (x,y) 和图像坐标 (u,v) 间的转换关系如下:
u−u0=dxx
v−v0=dyy
算法中的数学运算一般使用矩阵运算,因此上面的公式等价于:
⎣⎡uv1⎦⎤=⎣⎡dx1000dy10u0v01⎦⎤⎣⎡xy1⎦⎤
由于制造工艺的偏差,dx=dy,像素并不是正方形,而是平行四边形,这里先假设像素是个矩形,后面会提到倾斜因子的问题。
投影 ⇌ 相机
如下图所示,O1 为投影坐标系,O 为相机坐标系,设 P 点在投影坐标系中的坐标为 (x,y),则 P 点在相机坐标系中的坐标为 (x,y,f), f 表示焦距,即 O 点到 O1 点的距离。

由相似三角形原理,可得投影坐标 (x,y) 和相机坐标 (Xc,Yc,Zc) 间的转换关系如下:
Xcx=Ycy=Zcf
同样的,上面的公式等价于:
⎣⎡xy1⎦⎤=⎣⎡Zcf000Zcf000Zc1⎦⎤⎣⎡XcYcZc⎦⎤
这里 x=Zx、y=Zy、f=Zc,但这里没有在公式中把 f 约掉,后面会说明。
相机 ⇌ 世界
上文假设了世界坐标系和左相机坐标系一致,但在相机标定时需要以标定板的角点为世界坐标系原点。3维坐标的转换可以通过旋转和平移实现。

其中 R3×3 为旋转矩阵,T3×1 为平移矩阵,相机坐标 (Xc,Yc,Zc) 和世界坐标 (Xw,Yw,Zw) 间的转换关系如下:
⎣⎡XcYcZc⎦⎤=R3×3⎣⎡XwYwZw⎦⎤+T3×1=[R3×3T3×1]⎣⎡XwYwZw⎦⎤
相机参数
坐标转换中涉及的 (dx,dy)、(u0,v0)、f、R、T 这些都是相机的参数,可以通过相机标定获得。
内参
由图像 ⇌ 投影、投影 ⇌ 相机两个坐标转换关系,可以得出图像 ⇌ 相机的坐标转换关系如下:
⎣⎡uv1⎦⎤=Zc1⎣⎡dxf000dyf0u0v01⎦⎤⎣⎡XcYcZc⎦⎤
其中,dxf、dyf 的含义是将以物理尺寸为单位的焦距 f,转换为以像素为单位的焦距值,记 fx=dxf、fy=dyf。
补上上面提出的 f=Zc 为什么不约掉 f 的问题,因为标定相机得出的是 fx、fy,不约掉更加方便计算。
K=⎣⎡fx00sfy0u0v01⎦⎤
称呼矩阵 K 为相机的内参数,内参数是固定不变的。
补充上面提出的像素为平行四边形的问题,这里的 s 表示像素纵向边界相比于 y 轴的倾斜因子,用于辅助计算。
外参
相机 ⇌ 世界坐标转换关系中的 R、T 矩阵就是相机的外参数,表示世界坐标系到相机坐标系的旋转和平移矩阵,在立体视觉中,我们一般不关心世界坐标系到两个相机坐标的转换关系,而是关心两个相机坐标系间的转换关系。
相机标定能获得左相机的 R1、T1 和右相机的 R2、T2,有了这些就可以计算左相机坐标系到右相机坐标系的旋转和平移矩阵 R、T(这里是以右相机为主视相机,当然也可以反过来)。
立体视觉
通过被摄点的两个图像坐标得到被摄点的世界坐标,就是立体视觉。
结合上文的3个转换关系,设 λ=Zc 我们可以得出图像 ⇌ 世界的坐标转换关系如下:
λ⎣⎡uv1⎦⎤=K3×3[R3×3T3×1]⎣⎡XwYwZw1⎦⎤
设 P=[R3×3T3×1],称为投影矩阵,也就是相机内参和外参的结合体。
λ⎣⎡uv1⎦⎤=P3×4⎣⎡XwYwZw1⎦⎤
上面的方程是单个相机的,最开始已经提过了,方程的解集是一条直线,两个相机对应两个方程,解集是一个点。
End
能求出被摄点的世界坐标,也就能得出被摄点到相机的距离、两个被摄点之间的距离等。写这篇文章的原因是因为自己的毕设需要,之前并没有接触过机器视觉方面的知识,如果有不专业或错误的地方万望指出。
本文并没有提到相机标定和具体代码如何实现,这些会后面再写文章来讲。