激光雷达成本高,用廉价的立体视觉替代它可行吗?

作者:Jeremy Cohen
编译:McGL
公众号:PyVision(欢迎关注,专注CV,偶尔CS)

Pseudo-LiDAR — Stereo Vision for Self-Driving Cars

https://medium.com/think-autonomous/pseudo-lidar-stereo-vision-for-self-driving-cars-41fa1ac42fc9

深度学习和计算机视觉在自主系统中已经疯狂地流行起来,现在到处都在使用。计算机视觉,尤其是目标检测,在过去的十年中发展迅速。
像 YOLO 或 RetinaNet 这样的障碍物检测算法提供了2D的边界框,边界框给出了障碍物在图像中的位置。今天,大多数的目标检测算法都是基于单目 RGB 摄像头,不能返回每个障碍物的距离。
为了返回每个障碍物的距离,工程师们将摄像头与激光雷达(LiDAR)传感器融合,激光雷达可以返回深度信息。利用传感器融合技术将计算机视觉和激光雷达的输出信息进行融合。
这种方法的问题是激光雷达很贵。工程师们使用的一个有用的技巧是对齐两个摄像头,并使用几何学来确定每个障碍物的距离: 我们称之为伪激光雷达(Pseudo-LiDAR)。

单目视觉 vs 立体视觉

伪激光雷达利用几何构建了一个深度图,并将其与目标检测图结合起来得到3D距离。

如何利用立体视觉实现距离估计?

为了得到距离,下面是5步伪代码:

  1. 校准两个摄像头(内部和外部校准)
  2. 创建极线模式(epipolar scheme)
  3. 建立一个视差图(disparity map),然后一个深度图

然后将深度图与障碍物检测算法相结合,我们将估计边界框像素的深度。关于这一点的更多信息,请见文章末尾。

我们开始吧!


1. 内部和外部校准

每个摄像头都需要校准。校准意味着将一个具有[X,Y,Z] 坐标的(现实世界)3D点转换为具有[ X, Y]坐标的2D像素。

摄像头模型

今天的摄像头使用的是小孔成像模型

这个想法是使用一个针孔,让少量的光线通过摄像头,从而得到一个清晰的图像。

如果图像中间没有这个屏障,每一道光线都会通过,图像就会变得模糊。它还允许我们确定焦距 f 用于缩放和更好的清晰度。

为了校准摄像头,我们需要将世界坐标通过摄像头坐标转换为像素坐标。

摄像头校准过程
  • 从世界坐标到摄像头坐标的转换称为外部校准。外部参数称为 R(旋转矩阵)和 T(平移矩阵)。
  • 从摄像头坐标到像素坐标的转换称为内部校准。它要求摄像头的内部值,如焦距,光学中心,...... 内参数是一个矩阵,我们称为 K。

校准

通过摄像头校准得到矩阵 K。

通常,我们使用跳棋盘和自动算法来执行它。当我们这样做时,我们告诉算法棋盘中的一个点(如: 0,0,0)对应于图像中的一个像素(如: 545,343)。

校准示例

为此,我们必须用摄像头拍摄棋盘的图像,比较一些图像和一些点之后,校准算法将通过最小化最小平方损失来确定摄像头的校准矩阵。
一般来说,校准是必要的,以消除畸变。针孔摄像头模型包括一个失真:“ GoPro 效应”。为了得到一个矫正图像,校准是必要的。畸变可以是径向的,也可以是切向的。校准有助于消除图像失真。

图像校准

下面是摄像头校准返回的矩阵:

  • f 是焦距ー(u0,v0)是光学中心: 这些是内参数。

每个计算机视觉工程师必须了解和掌握摄像头的校准。这是最基本、最重要的要求。我们已经习惯了在线处理图像,从来不碰硬件,这是一个错误。

——尝试使用 OpenCV 进行摄影头校正。

齐次坐标(Homogeneous Coordinates)

在摄像头校准过程中,我们有两个公式来得到从世界到像素空间的一个点 O:

  • 世界到摄像头的转换
外部校准公式
  • 摄像头到图像的转换
内部校准公式

通过计算,你得到了这个等式:

  • 从世界到图像的转换
完整的方程式

如果你看一下矩阵的大小,它们并不匹配。

因此,我们需要将 O_world 从[X Y Z]修改为[X Y Z 1] 。这个“1”叫做齐次坐标。


2. 对极几何学(Epipolar Geometry)——立体视觉

立体视觉是基于两幅图像寻找深度。

我们的眼睛类似于两个摄像头。由于他们从不同的角度看一幅图像,他们可以计算出两个视点之间的差异,并建立一个距离估计。这里有一个双目立体摄像头设置的例子。你可以在大多数无人驾驶汽车中找到类似的东西。

立体相机如何估计深度?

假设你有两个摄像头,一个左,一个右。这两台摄像头在同一个 Y 轴和 Z 轴上对齐。基本上,唯一的区别就是它们的 X 值。现在,看看下面的计划。

双目立体设置

我们的目标是估计 O 点(表示图像中的任意像素)的 Z 值,即距离。

  • X 是对齐轴
  • Y 是高度
  • Z 代表深度
  • 两个蓝色的平面对应着每个相机拍摄的图像

现在从鸟瞰的角度来考虑这个问题。

立体设置的鸟瞰图
  • xL 对应左摄像头图像中的点,类似的xR 对应右摄像头。
  • b 是基线,是两个摄像头之间的距离。

如果你运用泰勒斯定理,你会发现我们可以得到两个等式:

  • 对于左边的摄像头:
左摄像头等式

我们得到 Z = X*f / xL

  • 对于右边的摄像头:
右摄像头等式

我们得到 Z = (X - b)*f/xR.
综合起来,我们可以找到正确的视差 d = xL - xR 和一个物体的正确 XYZ 位置。


3. 视差和深度图

什么是视差?

视差是同一个三维点从两个不同的摄像头角度拍摄的图像位置的差异。

立体视觉方程式

由于立体视觉,我们可以估计任何物体的深度(假设我们已经做了正确的矩阵校准)。

它甚至可以计算一个深度图或视差图

为什么是“对极几何” ?

为了计算视差,我们必须找到左侧图像中的每个像素,并将其与右侧图像中的每个像素匹配。这就是所谓的立体对应问题(Stereo Correspondance Problem)。
为了解决这个问题——

  • 取左图中的一个像素
  • 现在,要在右边的图像中找到这个像素,只需在极线上搜索它。没有必要进行二维搜索,点应该位于这条线上,搜索范围缩小到一维
极线

这是因为摄像头是沿着同一轴线排列的。
以下是极线搜索的工作原理:

极线搜索

应用: 构建伪激光雷达(Pseudo-LiDAR)

现在,是时候把这些应用到现实世界的场景中,看看我们如何使用立体视觉来估计物体的深度。如下两张图片——

立体视觉

这些图像中的每一个都有外部参数 R 和 t,事先由校准确定(步骤1)。

视差

对于每个图像,我们可以计算出相对于其他图像的视差图。我们将:

  1. 确定两幅图像之间的视差
  2. 将投影矩阵分解为相机内部矩阵 K,外部参数 R,t
  3. 使用我们在前两个步骤中收集到的信息来估计深度

我们将得到左侧和右侧图像的视差图。
为了帮助你更好地理解视差的含义,我找到了这个 Stack Overflow 解释:

视差图是指一对立体图像之间的视像素差或运动。要体验这种感觉,试着闭上一只眼睛。迅速闭上一个眼睛同时睁开另一只。距离你很近的物体会跳得很远,而距离更远的物体几乎不会移动。这个动作就是视差。在一对由立体摄像头拍摄的图像中,你可以测量每一个点的视运动,并根据测量结果生成亮度图像。

从视差到深度图

我们有两个视差图,它告诉我们两张图像之间像素的位移。
对于每个摄像头,我们有一个投影矩阵—— P_left 和 P_right。
为了估计深度,我们需要估计 K,R 和 t。

  • 每个摄像头用OpenCV 函数 cv2.decomposeProjectionMatrix () 可以从 P 中得到 K、 R 和 t

深度图

现在是生成深度图的时候了。
利用另一张图像和视差图,深度图可以告诉我们图像中每个像素的距离。整个过程如下:

  • 从 K 矩阵得到焦距 f
  • 使用平移向量 t 中的对应值计算基线 b
  • 使用之前的公式和计算出的视差图 d 计算图像的深度图:
立体视觉公式

我们对每个像素进行计算。

估计障碍物的深度

每个摄像头我们都有了一个深度图!现在,假设我们把这个和一个障碍物检测算法结合起来,比如 YOLO。对于每个障碍物,这样的算法将返回一个包含4个数字的边界框: [x1; y1; x2; y2]。这些数字表示框的左上角和右下角的坐标。
例如,我们可以在左边的图像上运行这个算法,然后使用左边的深度图。
现在,在那个边界框里,我们可以得到最近的点。我们知道它,因为我们知道图像中每一个点的距离,这要归功于深度图。边界框的第一点将是我们到障碍的距离。

Wow! 我们刚刚建立了一个伪激光雷达!
由于立体视觉,我们不仅知道图像中的障碍物,还知道它们与我们的距离!这个障碍物离我们有28.927米远!
立体视觉是使用简单的几何学和一个额外的摄像头将二维障碍物检测转化为三维障碍物检测的方法。今天,大多数新兴的“边缘”平台支持立体视觉,如新的OpenCV AI Kit或树莓派和英伟达Jetson。
在成本方面,与使用激光雷达相比,它相对便宜,并且仍然提供了很好的性能。我们称之为“伪激光雷达” ,因为它可以取代激光雷达的功能: 检测障碍物,对障碍物进行分类,并对障碍物进行三维定位。


References:

  • Course Visual Perception for Self-Driving Cars by University of Toronto

残缺棋盘的伪代码_伪激光雷达:无人驾驶的立体视觉相关推荐

  1. 伪激光雷达:无人驾驶的立体视觉

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 激光雷达成本高,用廉价的立体视觉替代它可行吗? 作者:Jeremy Cohen 编译:McGL 转载自 ...

  2. C++(数据结构与算法):60---分而治之、分而治之应用(残缺棋盘、归并排序、快速排序、选择问题、相距最近的点对)、分而治之解递归方程、复杂度的下限

    一.分而治之的思想 分而治之方法与软件设计的模块化方法非常相似 分而治之通常不用于解决问题的小实例,而要解决一个问题的大实例.一般步骤为: ①把一个大实例分为两个或多个更小的实例 ②分别解决每个小实例 ...

  3. 【论文速读】基于图像的伪激光雷达三维目标检测

    点云PCL免费知识星球,点云论文速读. 标题:End-to-End Pseudo-LiDAR for Image-Based 3D Object Detection 作者:Rui Qian, Divy ...

  4. ICCV2021|单目3D目标检测真的需要伪激光雷达吗?

    作者丨agent@知乎 来源丨https://zhuanlan.zhihu.com/p/406918022 编辑丨3D视觉工坊 Paper: arxiv.org/pdf/2108.0641 Code: ...

  5. 端到端基于图像的伪激光雷达3D目标检测

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 标题:End-to-End Pseudo-LiDAR for Image-Based 3D Objec ...

  6. 残缺棋盘问题 C语言 算法

    问题描述: Incomplete Chessboard Description TheBeet有一个块大小为(2^{N}2N * 2^{N}2N)的棋盘.这个棋盘是由一个个格子组成的.很不幸的,在一个 ...

  7. Hadoop安装教程_伪分布式配置-Ubuntu-CentOS6(究极详细、厦门大学数据库实验室)

    Hadoop安装教程_伪分布式配置_CentOS6.4/Hadoop2.6.0 Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0(2.7.1)/Ubuntu14.04(16.04) 林 ...

  8. 激光雷达—无人驾驶汽车的眼睛

    致谢小虾! 链接:激光雷达-无人驾驶汽车的眼睛 原创 2017-08-14 小虾  头图借用了特斯拉(故意的),我们都知道,特斯拉的无人驾驶技术并未使用激光雷达,而且出过几次事故,当然不全是因为没有使 ...

  9. 棋盘法应用_计算_微信小游戏一笔画完超萌喵星人

    棋盘法应用_计算微信小游戏一笔画完超萌喵星人 例如第41关 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ...

最新文章

  1. 【转】C语言的memset函数
  2. 阿里、华为、美团,大厂面试算法题,这些你会吗?
  3. springboot实现快速整合mybatis+mysql
  4. .html文件可以删掉吗,packages文件夹可以删除吗?
  5. ShadowGun Billboard Blinking God Rays
  6. 史上最实用网站集锦----不容错过
  7. Spring 整合Hibernate 开发实例
  8. 计算机count是什么函数,计算机里COUNT是什么函数?怎么用的?好评!!
  9. 今天给大家推荐一个深挖国内外前端新领域的前端社区
  10. 源发行版 8 需要目标发行版 1.8
  11. 独孤思维:互联网赚钱的底层逻辑
  12. (1)一次意外的屠魔之旅
  13. Zotero——一款文献管理工具
  14. PAT甲级 1027 Colors in Mars (20分)
  15. @EnableConfigurationProperties 进行注册
  16. 向微信公众号文章中添加mp4、rar、zip等文件给用户下载
  17. 【问题记录】ImportError: DLL load failed while importing _imaging: 找不到指定的模块
  18. 【MATLAB图像融合】[14]PCNN脉冲耦合神经网络代码分享
  19. google vr 入门之制作简易的VR播放器(三),真牛皮
  20. 极简个性时尚IOS风PPT-朴尔PPT

热门文章

  1. Linux中常用到的命令
  2. squid配合nginx的gzip压缩的完美解决方案
  3. linux下 open() write() read() close函数
  4. 从Go、Swift出发:语言的选择需谨慎
  5. VS2010解决方案位置不对和改变程序字体的方案
  6. 【机器学习入门笔记7:TensorFlow常量变量的定义】20190210
  7. 定位插件_微创新 | 开发PL/SQL插件,快速定位所需字段
  8. ifstream note
  9. javascript之模拟call以及apply实现
  10. Python-Django-Ajax进阶