Facebook Surround360 学习笔记--(2)算法原理

  • 本篇从宏观上介绍surround360的算法流程和每个步骤的原理,主要参考surround360官方网页(见参考)上的介绍。
  • Surround360开源项目包含了从相机阵列的硬件设计到图像拼接的软件算法,它在一个系统里实现了端到端的3D360°从视频拍摄到视频处理的过程。开源的目的就是为了促进3D360生态系统建设,不管是代码开发者还是内容制造者,所有人都可以自由地在开源系统的基础上进行改进、扩展、分发、合并等。Surround360硬件组装过程见这个视频:https://www.facebook.com/Engineering/videos/10154278617642200/
  • 必须要注意的是,为了保证高质量的输出效果,硬件设计和软件算法都非常重要。前篇介绍里讨论过硬件设计在降低连续视频处理时间的重要性。但是即使我们使用了高质量的光学镜头和精密的机械圆盘结构,没有经过软件校准的相机镜头之间仍然会有很大不同,这样输出的立体结果会出问题(比如重影或者伪3D)。图像拼接算法将17个相机拍摄的图片转换为适合VR设备观看的360°全景图像。该算法不但极大地降低了经典的3D360算法的处理时间,而且能够保持单眼8K的高清输出效果,从而在VR设备上获得极佳的体验。

立体360视频渲染的挑战

立体360视频渲染是一个非常困难的问题,主要存在如下因素:

  1. 涉及的数据量非常巨大。由于Surround360设备有十几个相机之多,而且为了保证最好的图像质量使用的是原始的未压缩的图像。如果帧率是30FPS的话,每分钟输出的视频将有120GB的数据。这绝对是一个巨大的挑战。
  2. 要求非常高的精度,留给出错的空间极小。对于单眼的2D的360视频内容来说,一些小的拼接错误是可以容忍的,但是对于立体3D360视频来说,必须保证极高的精度达到绝对近乎完美的效果,否则会引起观看者产生眩晕等生理方面的不适感。
  3. 要求较高的处理速度。为了VR视频的实用性要求,需要处理速度尽可能地快,但这常常和高质量地输出效果相矛盾。

传统的单目拼接算法没有上述问题,它的应用相对简单,只要把相邻图像边缘拼接好就行了。但是双目立体拼接算法面临着很大的挑战,很容易因为计算的立体视差不准破坏了3D的沉浸感,并且很容易引起用户的不适感。

构建立体全景图方法的探索

Facebook在开发其3D360相机的原型机时尝试了很多不同的相机阵列和算法的组合方式:
其中一个尝试是4对相机分别位于立方体的四个面,每对相机之间距离和人眼间距差不多的距离。然后利用alpha混合(一种基础的平滑的图像混合技术)的方法将左右眼拼接成为一个无缝的全景图。从实验结果来看,每个面的两对相机之间的立体效果很好,但是在立方体的四个拐角处没有立体效果。该方法的另外一个问题就是该设备旋转拍摄时,相机对必须指向不同的方向使得在一个恒定的距离观察物体,这会引起视疲劳。

有很多比alpha混合和拼接算法更加复杂的方法来获得立体全景。其中一种方法是用一个相机绕固定的轴旋转一周拍摄一系列连续的图片,这种方法和基本的拼接方法相比,可以产生合适的朝向以及具有一致深度的全景图。但是无法用于有运动物体的场景。Surround360就是在此基础上更进了一步,它使用光流法通过一个圆盘相机阵列的 “视图插值”,来模拟一个旋转的相机,该方法对于场景中有运动物体的情况也适用。但是光流法在计算机视觉领域是一个非常有挑战性的问题。

用几何方法创造真实的结果

Surround360渲染算法运行速度还是比较快的,事实上视频渲染的效果具备较高的图像质量、精确的深度和尺度计算、舒适的立体视觉,融入顶面和底面相机可以提供360°x 180°范围的全景沉浸感,同时结果中去除了相机支架。

正方形投影是一种在VR领域图像/视频编码中常用的技术。该投影是一种把球面展开到矩形结构图的的方法,就像世界地图一样。正方形图像中的每一列都对应球面的一条经线,每一行都对应球面的一条纬线。
Facebook Surround360 学习笔记--(2)算法原理_第1张图片
所以我们的目标是为左右眼产生正方形全景图,这样每一列像素对应于一个不同的头部朝向。对于给定的头部朝向,有两个相距6.4cm(瞳距)的绕着头部中心旋转的虚拟的眼睛。对于每个虚拟的眼睛,考虑一条射线沿鼻子(双眼中心)方向穿出,我们想要知道的是从真实世界沿着那条射线方向来的光线到底是什么颜色。这个颜色就是正方形图像中对应的像素。

现在想象上述发生在2D俯视图下的相机内,头部的中心就是相机中心。通过每个像素构建的射线从一个虚拟眼出发最后从相机圆盘出去。如果该射线正好穿过一个真实的相机,那么从相机图像中的像素我们就能知道它的颜色。但是通常射线穿出相机圆盘时没有对应一个真实的相机。这种情况下,我们在两个真实的相机之间利用视角插值出一个虚拟的相机,然后从插值的视角的像素中得到射线的颜色。
Facebook Surround360 学习笔记--(2)算法原理_第2张图片
上面的模型讲的是:如何将渲染出的立体正方形图像对应到真实世界中沿射线方向的光的颜色,这解释了为什么渲染的结果会让人感觉很真实(虽然是近似)。

渲染流程

实现上述模型实际上需要一系列的图像处理流程,有很多步骤,不过几乎都是自动化的,所以和人工拼接相比上述模型的渲染耗时很少。

首先,相机输出RAW Bayer格式的图像,surround360渲染算法中的图像信号处理部分利用gamma校正和颜色调整将RAW数据转换为标准的RGB图像。然后,读取图像数据并对每张图做正方形投影。这些正方形投影的矩形结构可以覆盖整个球体。每张图只占整个球体中的一小部分(如下图)。
Facebook Surround360 学习笔记--(2)算法原理_第3张图片
把原始输入图片投影为正方形时,需要对镜头引起的图像畸变做校正。Surround360使用张正友标定法(如下图),对标定板拍摄多张图片来做标定,可以求得内参和畸变系数用于做畸变校正。
Facebook Surround360 学习笔记--(2)算法原理_第4张图片
另外,surround360也对相机、镜头、支架系统的旋转、平移错位进行了校正。这些错位会引起垂直方向的视差(会引起重影,破坏3D效果)。为解决该问题,Surround360首先对相邻相机拍摄的图片之间特征点匹配,然后联合最小化所有侧面相机的垂直视差(同一个物体在左右眼图像中垂直方向的距离差),对每个相机计算出一个透视变换矩阵。
Facebook Surround360 学习笔记--(2)算法原理_第5张图片
首先介绍一下视差的概念:距离两个相机无穷远处的同一个物体视差为零,而在有限距离内,两个相机的投影图中同一个物体所处位置的差异就产生了视差。这有益于光流的计算,因为光流的初始假设就是0,正好对应于无穷远处的物体。

如下图左就是相邻相机之间的重叠区域,surround360通过计算它们之间的光流来计算视差。
Facebook Surround360 学习笔记--(2)算法原理_第6张图片
光流用于视角插值,因此可以从虚拟相机中得到我们所需要的光线。

至此,我们已经描述了如何渲染侧面的立体全景图。融入顶部和底部相机的图片可以得到更具有沉浸感的360°x 180°的全景。侧面相机的水平和垂直视场角约为90°(经过桶型畸变校正后视场角降低为77°)。所以侧面相机在垂直方向总共180°的范围内在靠近地平线方向占据77°左右的垂直区域,剩下的空缺可以由顶上和底下的180°单目鱼眼相机来填补。实际上,在正对的顶部和底部只能采用单目相机,因为无法对所有头部朝向进行立体校正使之成为一个左/右正方形图像对,所以surround360的立体效果从水平线到两极是逐渐变小的。使用不同的镜头,可以增加水平方向的立体范围,但是这是和图像分辨率/像素密度之间的折中。

为了无缝拼接顶部的相机拍摄的图片和侧面相机拍摄的图片,并且产生舒适的立体效果,surround360用光流来匹配顶部图片和侧面生成的全景图,通过alpha混合(具有去重影效果)合成最终的图像。

底部有两个相机,所以可以用算法自动从图像中去掉支架。底部的主相机位于圆盘正中心,和顶部的相机完全对称。底部另外一个辅助相机在支架的另一面,所以主相机中被支架遮挡的部分的图像通过辅相机可以看到,反过来也是。Surround360在两张图里指定支架的模板,然后用光流把第2张图变形为第一张图,然后融合两张图。
Facebook Surround360 学习笔记--(2)算法原理_第7张图片
如下图,两张底部相机的图融合成为一张图,去掉了支架。然后像顶部相机那样,把底部融合出来的一张图拼接到侧面相机生成的全景图里。
Facebook Surround360 学习笔记--(2)算法原理_第8张图片
为了充分利用多核CPU,以上过程在多线程里进行。例如,所有相机对之间的光流可以同时计算,此外,每个步骤的处理流程都根据它和其他步骤之间的相互依赖关系进行规划,使得可以充分利用所有的GPU资源。

总结

以上流程中的每一步骤都尽可能地保持较高的图像质量,并且进行了速度优化,目的就是为了在现有的硬件设备上产生和现实世界最精确的逼近。

参考:
https://code.facebook.com/posts/265413023819735/surround-360-is-now-open-source/

你可能感兴趣的:(计算机视觉)