开启深度的旅程

如果你的iPhone拥有后置双摄像头或者支持FaceID的前置TrueDepth摄像头,相信你一定有使用过系统相机app里面的景深拍照模式。每一张景深模式下的照片都包含了拍摄内容的深度信息(disparity data视差数据或者depth data深度数据)。颜色的数据的每一个值代表着每个像素点的颜色值。与之类似,视差或深度数据的每一个值代表着每个像素点所在的被拍摄的物体与相机之间的距离。根据不同的距离,可以用不同的图片处理算法分别处理。

后置双摄像头类似于人的两只眼睛,通过视差的原理得到距离数据。前置TrueDepth摄像头,就像它的名字一样,通过红外测量深度,信息更加精确。对于我们开发者来说,原理的不同并不是那么重要。两种摄像头默认都是存储视差数据。Apple提供API可以将视差数据和深度数据相互转化。

视差数据和深度数据都是存储深度的信息,那么两者究竟有什么区别呢?

作为一个开发者,让我们通过代码和demo来学习一下两者的区别。

深度信息存储在AVDepthData这个类的实例里。这个类iOS 11版本开始可用。

这个类里面最重要的方法莫过于下面这个函数:

var depthDataMap: CVPixelBuffer { get }

通过这个方法可以获得深度信息。CVPixelBuffer类型可以方便的和Core Image或者Metal的APIs联动。

深度信息的存储类型则可以通过下面的函数获取:

var depthDataType: OSType { get }

目前类型有四种,包括两个视差数据类型:

kCVPixelFormatType_DisparityFloat16
kCVPixelFormatType_DisparityFloat32

以及两个深度数据类型:

kCVPixelFormatType_DepthFloat16
kCVPixelFormatType_DepthFloat32

各个类型之间可以相互转化:

func converting(toDepthDataType depthDataType: OSType) -> Self

实际应用中我们可以实现以下辅助的方法,方便我们在视差和深度两种数据类型中相互转化:

```swift
extension AVDepthData {
func convertingToDepth() -> AVDepthData {
let targetType: OSType
switch depthDataType {
case kCVPixelFormatType_DisparityFloat16:
targetType = kCVPixelFormatType_DepthFloat16
case kCVPixelFormatType_DisparityFloat32:
targetType = kCVPixelFormatType_DepthFloat32
default:
return self
}
return converting(toDepthDataType: targetType)
}

func convertingToDisparity() -> AVDepthData {
    let targetType: OSType
    switch depthDataType {
    case kCVPixelFormatType_DepthFloat16:
top Created with Sketch.