社区计算机视觉课程文档

引言

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

介绍

本节解释了立体视觉的工作原理以及如何使用它来找到周围物体的三维结构。立体视觉涉及从不同的位置和视角捕获同一场景的两张或更多图像。这些图像可以使用多个摄像头或通过重新定位同一摄像头获得。

问题陈述

让我们通过理解图像形成的几何原理来理解寻找物体三维结构的问题。如图1所示,我们有一个三维空间中的点P,其坐标为x、y、z。点P通过针孔投影到相机的图像平面上。这也可以看作是将一个三维点投影到一个二维图像平面上。

现在,假设我们给定这个二维图像以及点P在该图像中的像素坐标位置。我们想找到点P的三维坐标。这可能吗?点P是唯一的吗,或者是否有其他三维点也映射到与点P相同的像素坐标?答案是,所有位于连接点P和针孔的线上的三维点都将映射到二维图像平面中的相同像素坐标。

我们的目标是解决确定物体三维结构的问题。在我们的问题陈述中,我们可以将三维物体表示为一组三维点。找到这些点的三维坐标有助于我们确定物体的三维结构。

Figure 1: Image formation using single camera

图1:使用单个相机进行图像形成

解决方案

我们假设给定以下信息:

  1. 场景点P的单张图像
  2. 图像中点P的像素坐标
  3. 用于捕获图像的相机的位置和方向。为了简单起见,我们也可以在针孔位置放置一个XYZ坐标系,Z轴垂直于图像平面,X轴和Y轴平行于图像平面,如图1所示。
  4. 相机的内部参数,例如焦距和主点位置。主点是光轴与图像平面的交点。其在图像平面中的位置通常表示为 (Ox,Oy)。

有了以上信息,我们可以找到一条三维直线,该直线源于点P的像素坐标(点P在图像平面上的投影),穿过针孔,并延伸到无穷远。根据图像形成几何的原理,我们可以得出结论,点P必须存在于这条线上。

  1. 最初(没有图像),点 P 可能存在于三维空间中的任何位置。
  2. 使用单张图像,我们将点 P 的可能位置缩小到三维空间中的一条直线。
  3. 现在,让我们考虑是否可以进一步缩小潜在位置,以精确定位点 P 在这条三维直线上的位置。
  4. 想象将相机移动到不同的位置。让坐标系保持在先前的位置固定。我们发现的三维线也保持不变,点 P 仍然位于这条线上的某个位置。
  5. 从这个新的相机位置,捕获同一场景点P的另一张图像。再次利用这张新图像中点P的像素坐标,并考虑更新后的相机针孔位置,找到点P必须位于其上的三维线。
  6. 现在我们有两条三维线,点 P 位于这两条线上的某个位置。因此,点 P 必然位于这两条线的交点上。

给定三维空间中的两条直线,它们的交点有三种可能性:

  1. 恰好相交于1点
  2. 相交于无限多个点
  3. 不相交

如果两张图像(原始和新相机位置)都包含点P,我们可以得出结论,这两条三维线必须至少相交一次,并且交点就是点P。此外,只有当两条线共线时,我们才能设想有无限个点相交。这种情况发生在新相机位置的针孔位于原始三维线上。对于新相机位置的所有其他位置和方向,这两条三维线必须精确地相交于一个点,即点P所在的位置。

因此,使用同一场景点P的两张图像、已知的相机位置和方向以及已知的相机内部参数,我们可以精确地找到点P在三维空间中的位置。

简化解决方案

由于相机位置和方向有许多不同的选择,我们可以选择一个能使数学更简单、更不复杂、并减少在计算机或嵌入式设备上运行时计算处理的位置。一种流行且常用的配置如图2所示。在此配置中,我们使用2个相机,这相当于使用单个相机从2个不同位置捕获2张图像。

Figure 2: Image formation using 2 cameras

图2:使用2个相机进行图像形成

  1. 坐标系的原点放置在第一个相机(通常是左相机)的针孔处。
  2. 坐标系的Z轴垂直于图像平面。
  3. 坐标系的X轴和Y轴平行于图像平面。
  4. 我们还有一个二维图像中的X和Y方向。X是水平方向,Y是垂直方向。我们将图像平面中的这些方向分别称为u和v。因此,一个点的像素坐标用(u,v)值表示。
  5. 坐标系的X轴定义为图像平面中的u方向/水平方向。
  6. 类似地,坐标系的Y轴定义为图像平面中的v方向/垂直方向。
  7. 第二个相机(更确切地说是第二个相机的针孔)放置在距离第一个相机右侧的x正方向上,距离为b,称为基线。因此,第二个相机针孔的x、y、z坐标为(b,0,0)。
  8. 第二个相机的图像平面与第一个相机的图像平面平行。
  9. 第二/右相机的图像平面中的 u 和 v 方向与第一/左相机的图像平面中的 u 和 v 方向对齐。
  10. 左右相机均假定具有相同的内部参数,例如焦距和主点位置。

在上述配置下,我们有以下方程式将三维空间中的点映射到二维图像平面。

  1. 左相机
    1. u_left=f_xxz+O_xu\_left = f\_x * \frac{x}{z} + O\_x
    2. v_left=f_yyz+O_yv\_left = f\_y * \frac{y}{z} + O\_y
  2. 右相机
    1. u_right=f_xxbz+O_xu\_right = f\_x * \frac{x-b}{z} + O\_x
    2. v_right=f_yyz+O_yv\_right = f\_y * \frac{y}{z} + O\_y

上述方程中使用的不同符号定义如下:

  • u_leftu\_left,v_leftv\_left指点P在左图中的像素坐标。
  • u_rightu\_right, v_rightv\_right指点P在右图中的像素坐标。
  • f_xf\_x指在X方向上的焦距(以像素为单位),f_yf\_y指的是Y方向上的焦距(以像素为单位)。实际上,相机只有一个焦距,它是针孔(透镜的光学中心)到图像平面的距离。然而,像素可能是矩形的,而不是完美的正方形,这导致当我们以像素表示f时,fx和fy的值不同。
  • x、y、z 是点 P 的三维坐标(可以使用任何单位,如厘米、英尺等)。
  • O_xO\_xO_yO\_y指主点的像素坐标。
  • b 称为基线,指左右相机之间的距离。b 和 x,y,z 坐标使用相同的单位(任何单位,如厘米、英尺等)。

我们有上面4个方程和3个未知数——3D点P的x、y、z坐标。内参相机参数——焦距和主点被认为是已知的。方程1.2和2.2表明,左右图像中的v坐标值是相同的。

  1. v_left=v_rightv\_left = v\_right

使用公式1.1、1.2和2.1,我们可以推导出点P的x、y、z坐标。

  1. x=b(u_leftO_x)u_leftu_rightx = \frac{b * (u\_left - O\_x)}{u\_left - u\_right}
  2. y=bf_x(v_leftO_y)f_y(u_leftu_right)y = \frac{b * f\_x * (v\_left - O\_y)}{ f\_y * (u\_left - u\_right)}
  3. z=bf_xu_leftu_rightz = \frac{b * f\_x}{u\_left - u\_right}

请注意,由于坐标系原点与左相机对齐,因此上述 x 和 y 值与左相机相关。上述方程式表明,我们可以使用从两个不同相机位置捕获的点 P 的两张图像来找到其三维坐标。z 值也称为深度值。通过这种技术,我们可以找到图像中不同像素的深度值以及它们在真实世界中的 x 和 y 坐标。我们还可以找到图像中不同点之间的真实世界距离。

演示

设置

我们将通过一个例子进行操作,捕获一些图像,并进行一些计算,以确定我们的假设和数学是否成立!为了捕获图像,我们将使用名为 OAK-D Lite(OAK 代表 OpenCV AI Kit)的硬件设备。该设备有3个摄像头——左右单色(黑白)和中央彩色摄像头。我们将使用左右单色摄像头进行实验。普通的智能手机摄像头也可以使用,但 OAK-D Lite 具有以下优势。

  • OAK-D Lite 的相机内部参数,如焦距和主点位置是已知的,因为该设备出厂前已预校准,并且这些参数可以通过其 Python API 读取。对于智能手机相机,内部参数需要确定,可以通过相机校准或有时存在于智能手机捕获图像的元数据中。
  • 上述主要假设之一是左右相机的位置和方向是已知的。使用智能手机相机,可能难以确定此信息或需要额外的校准。另一方面,对于 OAK-D Lite 设备,左右相机的位置和方向是固定的、已知的、预校准的,并且与上述简化解决方案的几何形状非常相似。尽管如此,仍需要对原始图像进行一些后处理/图像校正,详见下文。

原始左右图像

OAK-D Lite 中的左右摄像头定向与上述简化解决方案的几何结构相似。左右摄像头之间的基线距离为 7.5 厘米。使用该设备捕获的场景左右图像如下所示。图中还显示了这些图像水平堆叠,并绘制了一条恒定高度(即 v 值恒定)的红线。我们将水平 x 轴称为 u,垂直 y 轴称为 v。

原始左图

Raw Left Image

原始右图

Raw Right Image

原始堆叠左右图像

Raw Stacked Left and Right Images

让我们关注一个点——笔记本电脑的左上角。根据上述公式 3,v_left=v_rightv\_left = v\_right左右图像中的相同点。但是,请注意,红色线条(其 v 值恒定)在左图像中触及笔记本电脑的左上角,但在右图像中却偏离该点几个像素。造成这种差异的原因有两个:

  • 左右相机的固有参数不同。左相机的主点位于 (319.13, 233.86),而右相机的主点位于 (298.85, 245.52)。左相机的焦距为 450.9,而右相机的焦距为 452.9。左右相机的 fx 值都等于 fy。这些固有参数是从设备通过其 Python API 读取的,不同的 OAK-D Lite 设备可能有所不同。
  • 左右相机方向与上述简化方案的几何形状略有不同。

校正后的左右图像

我们可以进行图像校正/后处理来纠正左右相机固有参数和方向的差异。这个过程涉及执行 3x3 矩阵变换。在 OAK-D Lite API 中,立体节点执行这些计算并输出校正后的左右图像。详细信息和源代码可以在此处查看。在此特定实现中,固有参数的校正使用固有相机矩阵执行,方向的校正使用左右相机的旋转矩阵(校准参数的一部分)执行。校正后的左图像被变换,就好像左相机具有与右相机相同的固有参数一样。因此,在我们随后的所有计算中,我们将使用右相机的固有参数,即焦距 452.9,主点位于 (298.85, 245.52)。在下面的校正和堆叠图像中,请注意恒定 v 处的红线同时触及左右图像中笔记本电脑的左上角。

校正后的左图像

Rectified Left Image

校正后的右图像

Rectified Right Image

校正并堆叠后的左右图像

Rectified and Stacked Left and Right Images

我们再将校正后的左右图像叠加,看看它们之间的差异。我们可以看到,左右图像中不同点的 v 值基本保持不变。但是,u 值发生了变化,这种 u 值的差异有助于我们根据上述公式 6 找到场景中不同点的深度信息。这种“u”值的差异u_leftu_rightu\_left - u\_right被称为视差,我们可以注意到,相机附近点的视差比远处的点更大。深度 z 和视差u_leftu_rightu\_left - u\_right如公式 6 所示,它们成反比。

校正和重叠的左右图像

Rectified and Overlapped Left and Right Images

带注释的左右校正图像

我们来找出场景中某些点的三维坐标。如图所示,一些点被选中并手动标注了它们的 (u,v) 值。除了手动标注,我们还可以使用基于模板的匹配、SIFT 等特征检测算法来查找左右图像中的对应点。

带注释的左图像

Annotated Left Image

带注释的右图像

Annotated Right Image

3D 坐标计算

选择了场景中的十二个点,并在下表中列出了它们在左右图像中的 (u,v) 值。使用公式4、5和6,这些点的 (x,y,z) 坐标也已计算并列在下表中。X和Y坐标与左相机有关,原点位于左相机的针孔(或透镜的光学中心)处。因此,针孔左侧和上方的3D点分别具有负的X和Y值。

u_leftu\_left v_leftv\_left u_rightu\_right v_rightv\_right 深度/z(厘米) x_wrt_leftx\_wrt\_left y_wrt_lefty\_wrt\_left
点1 138 219 102 219 94.36 -33.51 -5.53
点2 264 216 234 217 113.23 -8.72 -7.38
点3 137 320 101 321 94.36 -33.72 15.52
点4 263 303 233 302 113.23 -8.97 14.37
点5 307 211 280 211 125.81 2.26 -9.59
点6 367 212 339 212 121.32 18.25 -8.98
点7 305 298 278 298 125.81 1.71 14.58
点8 365 299 338 299 125.81 18.37 14.86
点9 466 225 415 225 66.61 24.58 -3.02
点10 581 225 530 226 66.61 41.49 -3.02
点11 464 387 413 388 66.61 24.29 20.81
点12 579 388 528 390 66.61 41.2 20.95

尺寸计算和精度

我们还可以使用公式计算不同点之间的三维距离:distance=(x_2x_1)2+(y_2y_1)2+(z_2z_1)2distance = \sqrt{(x\_2 - x\_1)^2 + (y\_2 - y\_1)^2 + (z\_2 - z\_1)^2}. 下表列出了计算出的某些点之间的距离以及它们的实际测量值。百分比误差((actualmeasured)100actual( \frac{(actual-measured) * 100}{actual}) 也已计算并列出。请注意,计算值与实际值非常吻合,百分比误差为 1.2% 或更小。

维度 计算值 (厘米) 实际值 (厘米) % 误差
d1(1-2) 31.2 31.2 0
d2(1-3) 21.1 21.3 0.94
d3(5-6) 16.6 16.7 0.6
d4(5-7) 24.2 24 0.83
d5(9-10) 16.9 16.7 1.2
d6(9-11) 23.8 24 0.83

计算尺寸结果
Calculated Dimension Results

结论

  1. 总而言之,我们学习了立体视觉的工作原理,用于找到给定点 P 的两个不同视角图像的真实世界坐标 (x, y, z) 的方程,并将理论值与实验结果进行了比较。
  2. 我们假设相机内部参数——焦距和主点——以及它们的位置和方向信息都是已知的。这也被称为校准立体视觉。
  3. 有趣的是,即使相机的位置和方向未知,也可以找到点P的三维坐标。实际上,相机之间相对位置和方向可以通过图像本身来确定。这被称为未校准立体视觉!

参考文献

  1. 三维重建 - 多视角 Coursera
  2. 使用OpenCV AI Kit进行立体视觉和深度估计 LearnOpenCV
  3. OAK-D Lite Luxonics
< > 在 GitHub 上更新