立体视觉(Stereo Vision)是计算机视觉技术的一个重要模块。当看到一个物体的时候,人类的视觉系统不仅可以识别出这个物体是什么,而且还能估计出这个物体是离我们比较近还是比较远的。那我们赋予机器人视觉系统时,除了能够识别物体外,同样的要能够判断出障碍物距离有多远。人类时靠双眼来估计距离的,因此一句话总结以下立体视觉:立体视觉是一种计算机视觉技术,其目的是从两幅或两幅以上的图像中推理出图像中每个像素点的深度信息。(这里的深度指物体距离相机的距离)

1. 立体视觉原理

立体视觉借鉴了人类双眼的“视差”原理,即左、右眼对于真实世界中某一物体的观测是存在差异的, 我们的大脑正是利用了左、右眼的差异,使得我们能够辨识物体的远近。因此如人类双眼一样,立体视觉系统需要有两个(或者两个以上)摄像头的支持。

1.1 单目系统

单目系统中只有一个相机,如下图所示,O点为相机的光心,π是摄像头的成像平面(注意:实际的成像平面在相机光心的后面,这里画在光心和物体之间方便展示和理解,一般这个称为虚拟成像平面)。

从图中可以看出,如果P点与Q点在同一条直线上,那么他们在图像上的成像点就是同一个点,也就是\(p=q\) ,那么也就看不出来他们在距离上的差异(也就无法知道Q在前还是P在前)

立体视觉_立体视觉

1.2 双目系统

为了改善单目系统的上述缺陷,双目系统中存在两个相机,从而形成一个立体系统,如下图所示。两个相机拍摄同一场景,如果我们可以从拍摄出的两幅图像中找到对应点,就可以模拟人眼的视差原理计算出物体的深度(距离)。

从图中可以很明显的看出,在增加了一个摄像头之后,P与Q在目标面T上的成像不在位于同一个点,而是有自己分别的成像点,也就是\(p^{'}\)和\(q^{'}\) 。

立体视觉_立体视觉_02

1.3 视差和深度计算原理

有了上述的双目系统后,接下来就是通过参考面和目标面计算深度。先看下双目系统中的一些定义,下图中\(O_1 , O_2\)是两个相机的光心,\(I_1\),\(I_2\)是对应的成像平面,\(p_1\),\(p_2\)是物体P在两个相机中的成像点,有下面一些常见定义:

  • 极平面:\(O_1 , O_2 , P\)三个点确定的平面;
  • 极点:\(O_1O_2\)连线与像平面\(I_1\),\(I_2\)的交点\(e_1、e_2\);
  • 基线(baseline):\(O_1O_2\)
  • 极线:极平面与两个像平面之间的交线\(l_1、l_2\)。
    立体视觉_立体视觉_03

简化上面的双目系统,确保两个摄像头的参数是完全一致的,并且两者的位置是平行,让两个成像平面保持水平,如下图所示,我们假设 \(P\)为空间中的一点,\(O_R\)为左边摄像头的光心,\(O_T\)为右边摄像头的光心,摄像头的焦距为\(f\)(光心到成像平面的距离),成像平面在图中用粉色线表示, \(O_RO_T\)表示两个摄像头光心之间的距离,也称为基线,\(P\)在左右两个摄像机成像平面上的成像点分别为\(p\)与\(p^{'}\) , \(X_R\)与 \(X_T\)为成像点的水平方向的距离(通常我们得到的是像素坐标系下的 \(x\)坐标,其单位为像素,因此需要转换为实际的物理长度,涉及到坐标系的转换问题),\(Z\)就是我们需要求的深度。

立体视觉_基线_04

从上图中可以找到一组相似三角形\(\triangle Ppp^{'}\sim \triangle PQ_RQ_T\),根据三角形相似定理,可以得到:


\[\frac{B}{Z} = \frac{pp^{'}}{Z-f}=\frac{B-(X_R-\frac{W}{2})-(\frac{W}{2}-X_T)}{Z-f}=\frac{B-(X_R-X_T)}{Z-f}\]


求解得到:


\[Z =\frac{B*f}{X_R-X_T} = \frac{B*f}{D}\]


上式中的D就是我们通常所说的视差(disparity ),即同一个物体在两幅图像上的像素值差异。(注意:上述表达式中B,f的值为物理单位,D的值为像素单位,实际计算时要将像素单位转化为物理单位后再计算)

关于上面公式的推导,由两点值得说明下:

1. 两个相平面不平行怎么办?

上面推导中我们假设了两个平行的相平面,这是由于双目系统实际安装时都会进行校准,保证两个相机参数完全一致,让相平面尽量平行。如果的确相平面不平行,根据相机转动角度,是可以得到这个倾斜角的,根据角度将倾斜相平面投影到水平,再进行计算

2. 实际相平面在光心后面,不是前面,有影响吗?

关于相机模型中的相平面,参考之前文章https://www.cnblogs.com/silence-cho/p/15023822.html

上述推导中,我们采用了虚拟相平面(光心和成像物体之间的),而实际的相平面是在光心后面的,这个有影响吗?开始我也有这个疑问,后来进行画图推导后,发现最终结果是一样的,只是上面相识三角形的等式会变成下面的形式:


\[\frac{B}{Z} =\frac{B+(X_R-X_T)}{Z+f}\]


求解结果相同:\(Z =\frac{B*f}{X_R-X_T} = \frac{B*f}{D}\)

1.4 视差图(Disparity Map)

上面计算深度的公式中,最终要的就是视差这个概念。一般,将同一空间物理点在不同图像中的映像点对应起来,这个差别,我们称作视差。很多视差点组成的图像称为视差图(Disparity Map)。

立体视觉_基线_05

另外,通过视差计算深度的表达式,可以发现深度和视差成反比,即视差越大,则物体离相机越近,视差越小,物体离相机越远,如下图所示:

立体视觉_像素点_06

下面是一个视差图示例,第一幅图和第二幅图分别是双目相机得到的左图和右图,第三幅图就是视差图。可以很明显的看出来越亮的地方表示视差越大,也就离相机越近,反之离相机也就越远。

立体视觉_立体视觉_07