前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iPhone 摄影中的深度捕捉 ( WWDC2017-Session 507 ) 上篇

iPhone 摄影中的深度捕捉 ( WWDC2017-Session 507 ) 上篇

原创
作者头像
张耀琦
修改2017-09-20 09:30:48
3.5K0
修改2017-09-20 09:30:48
举报
文章被收录于专栏:张耀琦的专栏张耀琦的专栏

导语

iPhone 7 Plus上的人像模式展现了摄影深度的强大功能。 在iOS 11中,驱动此功能的深度数据现在开放使用。 了解如何利用深度信息为创意成像开辟新的可能性。 获得对高层次深度概念的更广泛的了解,并学习如何从相机中捕获流式传输和静态图像深度数据。

视频地址,只能用safari观看

前言

507是深度媒体相关的概念层面的内容。主要为下面4个部分:

  • Depth and disparity on iPhone 7 Plus
  • Streaming depth data from the camera
  • Capturing photos with depth data
  • Dual photo capture

Depth and disparity on iPhone 7 Plus

7 Plus 有两个摄像头,28毫米的广角摄像头,56毫米的长焦镜头。它们都是1200万像素,分享同样的配置项、格式。可以单独使用它们,也可以用一个虚拟的第三方摄像头来共同使用它们,使它们配合。它以同步的方式运行,相同的帧速率,并且一起运行它们可以实现两个选框功能。

Dual Camera Zoom 双摄变焦

  • Switches between wide and tele automatically
  • Matches exposure, focus, and frame rate
  • Compensates for parallax shift to smooth the transition
  • 在缩放时,会自动切换广角与长焦;
  • 适配曝光、对焦和帧速率;
  • 对视差偏移进行补偿,使其在广角和长焦之间来回切换时平滑过渡。

Portrait Mode

人像模式锁定在长焦摄像头,但是会同时使用广角和长焦来生成一副浅景深效果的图像。聚焦的前景清晰,背景则会逐渐模糊。

iOS11 上改进了对焦区域的渲染。更准确的展现了一个自由度高的快速镜头,例如上图中清晰明亮的花束圈。还改进了前景和背景边缘的渲染。

为了生成这样效果的图片,就要有能力区分前景和背景,也就是需要depth。在iOS10,depth信息还只是包含在苹果自己相机的人像模式中。iOS11,苹果正在向第三方应用开放depth map。

上面这幅图中内嵌了下面这样一个灰度可视化的深度图:

深度信息有了对图像编辑更多的可能性,例如上图对前景和背景应用不同的滤光器;将黑白滤光器应用到背景,Fade Filter应用到前景。

也可以像上图,将前景的范围缩小到手和花。

还可以对前景和背景应用不同的曝光

Deep Learning

Depth Map

首先定义depth map。真实世界中depth 意思是你和观察物体之间的距离。深度图是将三维场景转化为二维表示,并将深度设置为恒定距离。

下面对针孔相机做一点研究:

针孔相机是一个没有镜头的简单的防光盒,观察物体通过一个孔映射到传感器上。

光线通过的孔被称为焦点,聚焦到成像平面的距离就是焦距,物体在成像平面上的缩放程度就取决于焦距。较短的焦距意味着更宽的视野;而更长的焦距,较长的盒子意味着较窄的视野。

简单来说,深度图是将3D深度转换为2D,单通道图像,其中每个像素值是不同的深度,如五米,四米,三米。

为了真正测量深度,需要一个专用的摄像头,比如飞行时间相机。例如,一个系统,它从物体反射光信号,然后测量返回到传感器所需的时间。

iPhone 7双摄像头不是飞行时间相机。相反,它是一个基于Disparity的系统。

Disparity

Disparity 是从两个不同的摄像机(如眼球)观测到的物体的偏移量的量度。Disparity 是视差的另一个名称。

你可以通过稳定头部并将目光固定在靠近的位置上观察此效果,然后不移动您的头部,闭上一只眼睛,然后闭上另一只眼睛。而且你可以看到彩色的铅笔看起来比后面的标记更多,因为它们更接近。这就是 Disparity效果,或者说视差效果。

现在我已经拍摄了两台被认为是立体纠正相机的鸟瞰图。意思是说,它们彼此平行,它们指向同一个方向,而且焦距是相同的,这个很重要。

每个相机将具有测量的光学中心或主要点,并且如果从针孔到图像平面绘制垂直线,则光学中心是其与图像平面相交的点。

baseline基线

基线是指立体纠正系统中透镜的两个光学中心之间的距离。 下面是它的工作原理:

来自被观察物体的光穿过光学中心,或者说穿过两个照相机的图像平面上的不同点的孔径和平台。

Z

Z是深度或者真实世界深度的规范术语

现在看看当观察点越远,图像平面上的点更加接近,同理观察点越近,图像平面上的点间隔越远。

所以当相机是立体纠正时,这些偏移只能在一个方向上移动。他们要么靠近要么远离彼此,要么在同一条线上,要么是对极线。

有了基线,可以沿着它们的光学中心排列相机,并减去图像平面上的观察点之间的距离来获得视差。一般用像素单位来表示。

但是现在对于编辑并不是很方便,如果将图像缩小,实际是改变了像素大小,然后必须在深度图中缩放每个值。

Removing Despair from Disparity

苹果选择使用对缩放操作有弹性的归一化值来表示Disparity。

这里有两个相似三角形,高亮:

现实世界的三角形边是Z,单位是米,而基线是两个光学中心之间的距离。在防光盒内,同一个三角形表示为像素中的焦距和以像素为单位的Disparity。

数学表示,并化简得到1 / z。当物体移动得更远时,视差会缩小。基线现在绑定在Disparity中了,当处理深度图时,不需要单独携带该信息。

Disparity单位1/米,它可以承受缩放操作,并且从深度到Disparity的转换很简单,只需要 1除以 这样一个操作。

Disparity vs. Depth

  • iPhone 7 Plus双摄像头系统是基于Disparity的
  • Disparity是深度的代理
  • 归一化Disparity是深度的倒数

New Term: Depth Data

Depth Data是通用术语,对于任何depthy,都可以叫depth data。可以指深度图或者视差图,因为都是深度相关的。

Introducing AVDepthData

  • 苹果的平台( iOS, macOS, and tvOS)对于深度的规范表示叫做AVDepthData。
  • 它是AVFoundation框架中的一个类。
  • 它代表深度或差异图。
  • 它还提供了一些方法,可以在深度和差异之间进行转换。
代码语言:javascript
复制
public var kCVPixelFormatType_DisparityFloat16: OSType { get } /* 'hdis' */
public var kCVPixelFormatType_DisparityFloat32: OSType { get } /* 'hdis' */
public var kCVPixelFormatType_DepthFloat16: OSType { get } /* 'hdep' */
public var kCVPixelFormatType_DepthFloat32: OSType { get } /* 'fdep' */

像RGB图像一样,除了是单通道,但它们仍然可以表示为CV像素缓冲区,现在 CoreVideo 定义了在上一张幻灯片中看到类型的四个新像素格式。因为如果是在GPU上,会要求16位的值,而在CPU上,就都是32位的值。

AVDepthData的核心属性:

代码语言:javascript
复制
@available(iOS 11.0, *)
open class AVDepthData: NSObject {
    open var depthDataType: OSType { get }
    open var depthDataMap: CVPixelBuffer { get }
    open var isDepthDataFiltered: Bool { get }
    open var depthDataAccuracy: AVDepthDataAccuracy { get }
}

Holes

由于光线,或者边缘难以分清等因素,可能会出现无法得到Disparity的点,这种点叫做holes。深度图也可能被处理来填补这些点。 可以通过基于周围深度数据进行内插,或者通过使用RGB图像中存在的元数据来实现。 AVDepthData 的 isDepthDataFiltered 属性告诉是否以这种方式处理了map。

Calibration Errors 校准错误

比如基线计算错误。

iPhone相机不是针孔,iPhone有透镜,并且它的透镜都不是固定的。

  • Optical Image Stabilization
  • Gravity
  • Focus Coil

如果使用OIS,则透镜可以横向移动来抵消手抖动。重力可以发挥作用,因为它会导致镜头下垂。聚焦致动器实际上是施加电流的弹簧。所以这些原因可能会导致它横向移动一点,而光学中心位置的这些非常小的误差可能导致Disparity的巨大误差。当发生这种情况时,结果是map中每个像素的误差是一个恒定的。 Disparity 值相对于彼此仍然可用,但它们不再反映真实世界的距离。

Depth Data Accuracy

代码语言:javascript
复制
extension AVDepthData {
    public enum Accuracy: Int {
        case relative
        case absolute 
    }
}

因此 AVDepthData 有一个精度的概念。绝对值的精度值意味着单位确实反映了现实世界的距离,没有校准问题。相对精度意味着Z排序仍然保留,但是现实世界的尺度已经丢失。从第三方摄像机获取的深度数据可以报告为绝对或相对,但由于刚刚提到的校准错误,iPhone 7 Plus总是报告相对精度。

相对精度并不是坏的精度。双摄像头的depth完全可以使用。

Streaming Depth Data

AVCamPhotoFilter

Introducing AVCaptureDepthDataOutput

AVFoundation 框架相机捕获类分为三大部分。第一个是 AVCaptureSession,仅仅是个控制对象。你可以告诉它开始或者停止运行,它不做任何事情,除非给它一个输入,比如 AVCaptureDeviceInput ,这里与双摄像头的设备关联,并且给session提供输入。然后需要一个输出,这里是一个新的输出类型 AVCaptureDepthDataOutput,它的功能类似于 VideoDataOutput,除了提供 CoreMedia 示例缓冲区之外,它提供了 AVDepthData 对象。

  • 只有双摄像头才能支持 AVCaptureDepthDataOutput。
  • 将 DepthDataOutput 附加到会话中时,双摄像机自动缩放到2倍,即长焦的全部视野,这是因为为了计算视差,焦距必须相同,而在2倍变焦下,广角摄像机的焦距与长焦相匹配。在计算深度时缩放是被禁用的。
  • 苹果已经向 AVCaptureDevice 添加了一些新的访问器。在双摄像头上,您可以通过查询 supportedDepthDataFormats 属性来发现哪些视频格式支持深度。
  • 还有一个新的 activeDepthDataFormat 属性,可以让您看到 activeDepthDataFormat 是什么或选择一个新的 DepthDataFormat。

Supported Depth Resolutions for Streaming

第一个是受欢迎的照片预设。 在照片预设中,可以从 VideoDataOutput 中获得屏幕尺寸的预览,还可以从photoOutput中获得1200万像素的完整图像。所以在这里 VideoDataOutput提供了1440x1080,这是屏幕尺寸。如果使用DepthDataOutput,可以获得24 fps,最大320x240的depthData。这么小的原因是每秒处理24次视差图已经消耗很多性能了。也可以以较低的分辨率得到它,160x120。

第二个是16x9的格式,这是今年的新格式。去年有一个720p 16x9的格式,帧率高达60 fps。今年这个新格式只有30 fps,但是支持depth。同样支持两种分辨率。

最后,有一个非常小的VGA大小的预设或活动格式,如果只是想要非常小非常快,可以使用它。

Depth Frame Rate Examples

AVCaptureDevice允许设置最小和最大视频帧速率,但不允许独立于视频帧速率设置深度帧速率。因为深度需要和视频帧率一致,或者小于视频帧率。例如,如果选择最大视频帧率为24,深度可以跟上这一点,所以得到24 fps的深度。但是,如果选择30 fps视频,则深度跟不上,不过不会选择24,而是15,倍数是比较好的选择。

DepthDataOutput支持过滤深度数据。这样就可以填满空洞,并且随着你的移动也可以比较平滑,这样就不会看到从帧到帧的时间跳跃。

代码语言:javascript
复制
open var isFilteringEnabled: Bool

非同步数据输出

现在有四种数据输出:

第一个是 VideoDataOutput ,从iOS 4开始,它是以30 fps或60 fps的流媒体方式一次给出视频帧。 还有一个 AudioDataOutput,通常会以44.1的速度一次推送1024个PCM帧。 还有一个 MetadataOutput 可以提供面部,检测到的面孔或条形码,并且这些都偶尔出现。 他们可能会有一些延迟,寻找面孔多达四帧延迟。

第四个就是 DepthDataOutput ,是以视频的帧速率或以视频均匀分割的速率传送。

如果关心同时处理所有这些数据,或者处理一定的演示时间。为了处理所有这些数据输出,您必须拥有一个非常复杂的缓冲机制,以便跟踪所有进入的时间,

Synchronized Data Output

在iOS 11中,苹果添加了一个名为 AVCaptureDataOutputSynchronizer 的新同步对象。它可以在单个统一回调中为给定呈现时间,提供所有可用数据,并传递一个称为AVCaptureSynchronizedDataCollection 的集合对象。

所以这样就可以指定一个主输出,一个最重要的输出,一个希望所有其他东西要同步的输出,然后只要它需要,就可以做这个工作, 以确保给定演示时间的所有数据在可用之前提供给单独的统一回调。它将为你提供输出的所有数据,或者如果确保没有特定输出的数据,它将继续提供与它有关的集合。

下面一个代码示例:

代码语言:javascript
复制
func dataOutputSynchronizer(_ synchronizer: AVCaptureDataOutputSynchronizer, didOutput synchronizedDataCollection: AVCaptureSynchronizedDataCollection) {
    // Iterate through an AVCaptureSynchronizedDataCollection using fast enumeration
    for syncedData in synchronizedDataCollection {
        if let syncedDepthData = syncedData as? AVCaptureSynchronizedDepthData {
            // ...
        }
    }
}

可以像数组一样使用它,也可以像字典那样使用它,具体取决于要做什么。

代码语言:javascript
复制
func dataOutputSynchronizer(_ synchronizer: AVCaptureDataOutputSynchronizer, didOutput synchronizedDataCollection: AVCaptureSynchronizedDataCollection) {
    // Use dictionary-esque subscripting to find a particular data
    if let synDepth = synchronizedDataCollection[self.ddo] as? AVCaptureSynchronizedDepthData {
        // ...
    }
}

Streaming Camera Intrinsics

iOS 11中还有一个新的流式传输功能,当使用 VideoDataOutput 时,支持每个视频帧的相机内在功能。

上面讲到针孔相机,为了将3D空间中的点转换为2D空间,需要两个信息,光学中心和焦距。在计算机视觉中,可以使用这些属性通过使用逆变换将2D图像重新投影回3D空间,这在新的AR kit中是重点。

iOS 11中的新功能,可以选择在每个视频帧中收到这样一组内在函数,通过调用 AVCaptureConnection 的 isCameraIntrinsicMatrixDeliveryEnabled 来选择。

相机内在函数是描述相机几何属性的3x3矩阵。fx和fy是像素焦距。它们是分开的x值和y值,因为有时相机具有变形镜头或变形像素。

在iOS设备上,我们的相机总是具有一致的像素,所以fx和fy总是相同的值。

x0和y0是透镜光学中心的像素坐标。

这些都是像素值,它们是以提供它们的视频缓冲区的分辨率给出的。

所以,一旦你选择了,可以期望以流式方式获取样本缓冲区,可以获得这个附件,有效载荷是一个C/F数据,它包装一个矩阵3x3浮点数,这是一个SIMD数据类型。

接《 iPhone 摄影中的深度捕捉 ( WWDC2017-Session 507 ) 下篇

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导语
  • 前言
  • Depth and disparity on iPhone 7 Plus
  • Dual Camera Zoom 双摄变焦
  • Portrait Mode
  • Deep Learning
    • Depth Map
    • Disparity
    • baseline基线
    • Z
    • Removing Despair from Disparity
    • Disparity vs. Depth
    • New Term: Depth Data
    • Introducing AVDepthData
    • Holes
    • Calibration Errors 校准错误
    • Depth Data Accuracy
    • Streaming Depth Data
      • AVCamPhotoFilter
        • Introducing AVCaptureDepthDataOutput
        • Supported Depth Resolutions for Streaming
        • Depth Frame Rate Examples
        • 非同步数据输出
        • Synchronized Data Output
        • Streaming Camera Intrinsics
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档