119.AVDepthData、LiDAR 深度数据与人像模式全解析:iOS 真实景深图采集与处理实战
AVDepthData、LiDAR 深度数据与人像模式全解析:iOS 真实景深图采集与处理实战
关键词
AVDepthData、LiDAR 深度采集、iOS 人像模式、深度图、景深模糊、AVCaptureDepthDataOutput、深度融合、真实人像虚化、TOF、TrueDepth、ARKit
摘要
在 iOS 高端影像系统中,真实景深信息的采集与利用已成为区分旗舰设备与基础设备的重要能力。Apple 自 iPhone 7 Plus 引入双摄虚化以来,逐步发展出基于 AVDepthData、TrueDepth 与 LiDAR 的多维深度感知技术,并开放接口供开发者获取高精度深度图,构建背景虚化、人像分割、3D 重建等多种功能。本文将深入解析 AVDepthData 的结构与使用方式,系统讲解 LiDAR 采集架构、人像模式的景深融合逻辑,以及如何在实际项目中采集、预览并处理深度图数据,实现具备工程可用性的景深应用。
目录
-
iOS 影像系统中的深度数据架构概览
- 从双摄到 LiDAR:硬件能力演进
- 深度图在 Apple 影像链路中的角色定位
-
AVDepthData 基础结构解析与核心属性说明
- 深度图类型(Disparity vs Depth)与像素格式
- 深度图尺寸、方向、精度控制与对齐关系
-
LiDAR 与 TrueDepth 传感器的差异与使用场景
- TOF(Time of Flight)测距原理
- 前置与后置深度传感器的物理能力对比
- 实际应用:人像、AR、三维重建
-
AVCaptureDepthDataOutput 的采集配置与回调处理
- 如何在 AVCaptureSession 中添加深度输出通道
- 回调中的数据同步与帧对齐
- 深度与 RGB 图像配准策略
-
AVDepthData 与图像融合:构建真实景深模糊效果
- 深度图与 RGB 图合成原理
- iOS 中人像模式虚化的实现逻辑(Portrait Matte)
- 自定义景深算法与高斯模糊优化路径
-
人像分割与前背景提取实战
- 利用 Depth + SegmentationMatte 进行精细化人像提取
- 多层通道融合实现高质量背景替换
- ARKit 中人物遮挡(People Occlusion)机制解构
-
深度图预处理与精度提升策略
- 深度值归一化与边界保留滤波算法
- 孔洞填补、平滑处理与去噪优化
- 利用 Metal 加速深度图后处理流程
-
性能优化与工程落地建议
- LiDAR 采集对系统资源的影响分析
- 数据同步瓶颈与帧率调控技巧
- 真实场景下的人像模式稳定性评估与容错策略
1. iOS 影像系统中的深度数据架构概览
Apple 在 iOS 影像系统中对于深度信息的采集与表达提供了完整的软硬件协同机制。从最初的双摄景深估计(iPhone 7 Plus),到前置 TrueDepth 摄像头(iPhone X),再到后置 LiDAR 传感器(iPhone 12 Pro 及以上),Apple 的深度感知能力在精度、稳定性和计算效率方面持续进化。AVFoundation 框架对这些能力进行了标准化封装,开发者可通过 AVCaptureSession 配合 AVCaptureDepthDataOutput 获取结构化深度图数据,并结合 RGB 图像进行人像虚化、3D 重建等操作。
从双摄到 LiDAR:硬件演进
-
双摄方案(Dual Camera Disparity)
利用主摄与副摄的视差计算深度,仅适用于固定双摄组合。受限于基线长度、对齐精度与遮挡区域,输出质量有限,存在较多噪点与错误估计。 -
TrueDepth 摄像头(结构光)
主要用于面部识别(Face ID),通过红外点阵投射 + IR 摄像头捕获回波图像,构建高精度 3D 面部模型。前置摄像头仅支持人脸区域采集,适用于 ARKit、人物遮挡等前景处理场景。 -
LiDAR 扫描仪(后置 TOF)
基于时间飞行原理(Time-of-Flight),通过激光测距构建环境深度图,支持大范围、高速、精度一致的深度采集,是目前最强的移动端深度感知方案。支持实时输出、与 RGB 图同步、景深效果应用。
深度图在 Apple 影像链路中的角色定位
在 AVFoundation 中,深度图被封装为 AVDepthData 对象,其数据流与图像帧并行传输。其应用范围包括:
- 人像模式模糊处理(Portrait Mode)
- 背景替换与人像抠图
- 3D 扫描与物体建模
- AR 场景中人物遮挡、地形理解
Apple 在深度处理上采用了分层设计:底层通过 AVCapture 输出采集原始深度数据,中间层提供 AVDepthData 结构进行标准化封装,上层如 Photos Framework、ARKit 再结合这些数据进行语义理解或效果生成。
2. AVDepthData 基础结构解析与核心属性说明
AVDepthData 是 AVFoundation 用于描述相机深度信息的核心数据结构,它将底层采集到的点云或视差图封装为可解析的、与图像对齐的图像帧。理解 AVDepthData 的数据格式、精度、方向关系,是使用深度图进行图像处理的基础。
深度图类型:Disparity vs Depth
AVDepthData 支持两种深度图类型:
- Disparity(视差图):数值越大表示对象越近,通常来源于双摄像头计算;
- Depth(真实距离图):数值为以米为单位的绝对距离,通常来源于 LiDAR 或 TrueDepth。
开发者可使用 depthDataType 属性判断其类型,并通过 converting(toDepthDataType:) 方法在两者之间转换:
if depthData.depthDataType == kCVPixelFormatType_DisparityFloat32 {
let depth = depthData.converting(toDepthDataType: kCVPixelFormatType_DepthFloat32)
}
不同类型决定了后续图像融合与景深计算的算法差异,Depth 类型更适合距离感知与绝对定位。
深度图像素格式与数据结构
AVDepthData 内部存储实际深度信息的格式为 CVPixelBuffer,支持以下几种常见格式:
kCVPixelFormatType_DisparityFloat32kCVPixelFormatType_DepthFloat32kCVPixelFormatType_DisparityFloat16kCVPixelFormatType_DepthFloat16
其中 Float32 提供更高精度,适合科研级或三维建模应用;Float16 性能更优,适合实时处理与移动端优化。
开发者可通过以下方式提取原始深度帧:
let depthBuffer = depthData.depthDataMap
CVPixelBufferLockBaseAddress(depthBuffer, .readOnly)
// 读取像素指针并处理数据
CVPixelBufferUnlockBaseAddress(depthBuffer, .readOnly)
注意深度图并不总是与 RGB 图像具有相同分辨率,需通过 depthData.isDepthDataFiltered 判断其是否经过系统内插滤波对齐到主摄像头图像尺寸。若未对齐,可使用 depthData.applyingExifOrientation(...) 或 depthDataByApplyingExifOrientation(...) 实现对齐变换。
图像方向与对齐关系
由于深度图与 RGB 图像可能来源于不同硬件模块,方向与镜像状态可能存在差异,尤其在使用前置摄像头时更为常见。AVDepthData 提供 depthDataMap 对应的 ExifOrientation 接口用于同步变换:
let alignedDepth = depthData.applyingExifOrientation(.rightMirrored)
为保证图像合成时的像素级准确性,必须在处理流程中维持 RGB 与 Depth 图的方向一致、坐标系一致、缩放比例一致。
3. LiDAR 与 TrueDepth 传感器的差异与使用场景
Apple 在 iOS 影像系统中集成了两类硬件级深度传感器:前置的 TrueDepth 相机和后置的 LiDAR 扫描仪,它们在原理、采集范围、输出精度和适用场景上存在本质差异。理解这些差异,有助于开发者根据实际业务需求选择合适的深度采集方案,并充分挖掘硬件能力。
TOF(Time-of-Flight)测距原理
LiDAR 属于 TOF(Time-of-Flight)传感器,其工作方式为:
- 设备发射短脉冲激光(不可见光),照射场景;
- 反射信号被光电传感器接收;
- 根据发射与接收时间差计算出每个像素点的距离值。
LiDAR 的典型优势包括:
- 支持大范围扫描(最高达 5 米),适用于空间建模与环境感知;
- 实时性高,采集速率可达每秒 60 次;
- 抗光干扰能力强,即便在弱光、暗光环境下依然能获得稳定的深度数据。
相比之下,TrueDepth 属于结构光方案,其核心逻辑是投射数千个红外点阵,捕捉面部反射结构图像,并与已知模式进行比对来计算三维结构,因此在远距离(超过 1 米)或非人脸场景下,效果显著衰减。
前置与后置深度传感器能力对比
| 属性维度 | TrueDepth(结构光) | LiDAR(TOF) |
|---|---|---|
| 安装位置 | 前置(Face ID) | 后置(iPhone 12 Pro 及以上) |
| 测距范围 | 20 cm – 1.5 m(面部最佳) | 最远可达 5 米(无遮挡) |
| 采集精度 | 高精度但仅限于人脸区域 | 中等精度,适用于空间结构 |
| 硬件依赖 | 点阵投射器 + 红外镜头 | 激光发射器 + 飞行时间传感器 |
| 光照适应能力 | 强,弱光下表现良好 | 非常强,几乎不受可见光影响 |
| 适用场景 | 面部识别、人脸建模、AR面具 | 人像模式、背景虚化、AR遮挡、3D建模 |
在实际开发中,常见的选择建议:
- 需要采集人脸结构、AR 表情识别的应用:使用 TrueDepth;
- 需要真实背景深度、AR 空间定位、人像模糊等应用:使用 LiDAR;
- 低端或无深度传感器设备:回退为双摄差值估计或 ML 模型预测。
实际应用:人像模式、AR 与三维重建
- 人像模式(Portrait Mode):使用 LiDAR 精确区分前景人物与背景,输出高质量
AVDepthData+PortraitEffectsMatte实现景深模糊; - ARKit 空间感知:LiDAR 构建 3D 空间网格与障碍识别,提升 AR 内容与真实环境的融合度;
- 3D 建模 / 扫描:采集深度数据并重建网格,用于室内空间还原、物体扫描、尺寸测量等工业或消费类应用;
- 遮挡判断:结合 RGB + Depth,实现虚拟对象与人物之间正确的遮挡关系(如人物在前,虚拟物体自动被遮住)。
随着 Apple 芯片性能提升(如 A17 Pro),LiDAR 数据处理也获得更强的实时性和图像融合能力,为移动端景深算法的工程化提供了良好支撑。
4. AVCaptureDepthDataOutput 的采集配置与回调处理
Apple 在 AVFoundation 中通过 AVCaptureDepthDataOutput 提供了统一的深度数据采集能力,开发者可将其作为 AVCaptureSession 的输出组件,实时获取与 RGB 图像配对的深度图帧数据。其回调机制与视频帧类似,但具有更强的帧同步要求与图像配准控制。
在 AVCaptureSession 中添加深度输出
深度采集的完整配置流程如下:
let depthOutput = AVCaptureDepthDataOutput()
depthOutput.isFilteringEnabled = true // 启用系统深度图插值对齐
if session.canAddOutput(depthOutput) {
session.addOutput(depthOutput)
}
depthOutput.setDelegate(self, callbackQueue: DispatchQueue(label: "depth.queue"))
关键配置说明:
- isFilteringEnabled:若设置为 true,系统将自动对低分辨率深度图进行插值并与 RGB 图像对齐;
- callbackQueue:深度数据回调的线程,应使用低延迟串行队列处理,避免阻塞系统采集。
深度数据仅在支持的设备(如配备 LiDAR 或 TrueDepth 的机型)上可用,需在配置前判断当前 AVCaptureDevice.activeFormat.supportedDepthDataFormats 是否为空。
回调中的数据同步与帧对齐
深度数据与 RGB 帧之间必须保持时间戳一致,确保合成或处理时的像素级匹配。回调函数中可获取每一帧深度图对应的 AVDepthData:
func depthDataOutput(_ output: AVCaptureDepthDataOutput,
didOutput depthData: AVDepthData,
timestamp: CMTime,
connection: AVCaptureConnection) {
let pixelBuffer = depthData.depthDataMap
// 后续图像处理逻辑
}
同步性保障建议:
- 使用同一个 AVCaptureSession 同时绑定 Video 与 Depth 输出;
- 避免在回调中长时间阻塞,防止同步失配;
- 若需复合处理,可在接收帧后使用环形缓存结构合并 RGB + Depth 数据对。
深度与 RGB 图像配准策略
深度图通常为低分辨率图像,分辨率可能为 256x192 或 640x480,与 4K 主摄图像差异较大。Apple 提供了两种对齐策略:
- 启用 isFilteringEnabled:系统自动进行图像尺寸、方向插值处理,适合大部分常规应用;
- 使用 AVDepthData 的对齐 API:如
applyingExifOrientation(_:)、converting(toDepthDataType:)等手动对齐;
若需将深度图与图像预览层实时合成,需提前将深度图处理为可视化图像(如归一化至 0–255 灰度图),再使用 Metal 或 CoreImage 渲染输出。
5. AVDepthData 与图像融合:构建真实景深模糊效果
实现背景虚化的人像模式,是深度图数据在 iOS 系统中最直观的实际应用之一。通过将 AVDepthData 与图像帧结合,可以基于目标距离判断是否执行模糊处理,从而在保持前景人物清晰的同时模糊背景,模拟专业相机中的浅景深效果。
深度图与 RGB 图合成原理
核心流程如下:
- 从
AVCaptureVideoDataOutput获取当前图像帧; - 从
AVCaptureDepthDataOutput获取当前帧的深度图; - 将深度图归一化为灰度通道(Depth Mask),用于表示每个像素点与摄像头的距离;
- 根据阈值或模糊曲线,对背景区域图像进行模糊处理;
- 使用原始图像的前景区域与模糊后的背景图融合,输出最终图像。
实际工程中,可通过 CoreImage 或 Metal 实现该过程,以下是基于 CoreImage 的一个简化示意:
let ciImage = CIImage(cvPixelBuffer: rgbPixelBuffer)
let depthCI = CIImage(cvPixelBuffer: depthPixelBuffer)
// 创建景深遮罩
let mask = CIFilter(name: "CIDepthToDisparity")?.outputImage
// 使用掩码执行高斯模糊处理
let blurred = ciImage
.applyingFilter("CIGaussianBlur", parameters: ["inputRadius": 8.0])
.applyingFilter("CIBlendWithMask", parameters: [
"inputMaskImage": mask!,
"inputBackgroundImage": ciImage
])
这个流程模拟了 Apple 系统层 Portrait Mode 中对深度图的处理机制,当然系统内部实现采用了更精细的模糊衰减曲线(非线性函数)与边缘保持机制(edge-aware blur),避免人物边缘被误判进入背景。
iOS 中人像模式虚化的实现逻辑(Portrait Matte)
iOS 相册中的人像照片不仅仅包含一张图像,它还包括额外的图层信息,通常以 HEIC 文件封装的形式保存,包含:
- 原始图像(Base RGB)
- PortraitEffectsMatte(人物前景掩码)
- AVDepthData(原始深度图)
- SemanticSegmentationMatte(如头发、皮肤分割图)
在 AVFoundation 中,开发者可以通过 AVCapturePhoto 对象获取这些附加信息:
if let depthData = photo.depthData {
// 使用 AVDepthData 创建背景模糊
}
if let matteData = photo.portraitEffectsMatte {
// 使用人像前景掩码实现更精准的前背景分离
}
PortraitEffectsMatte 是一张单通道灰度图,值域在 0.0–1.0 之间,表示每个像素是否属于人像主体。这张图比深度图更适合前背景合成,尤其在人脸边缘、头发区域具备更高精度,适合用于边缘保持处理。
Apple 在系统层使用了基于 CNN 的分割网络结合 AVDepthData 进行融合判断,这一融合也构成了 iOS 相册中“调整背景模糊”功能的基础。
自定义景深算法与高斯模糊优化路径
虽然 Apple 提供了系统级背景模糊能力,但在很多场景中,开发者仍需定制化实现虚化强度、衰减曲线、视觉风格等逻辑。例如:
- 多区域模糊强度控制:根据深度值线性/非线性函数映射模糊半径;
- 景深过渡区域平滑优化:处理前背景交界处虚化“硬边”问题;
- 暗部/高光虚化增强:模拟光圈效果中的焦外高光(Bokeh)形态。
针对性能敏感场景(如实时预览),建议采用 Metal Shader 编写高斯模糊核函数并在 GPU 上加速执行,同时对 Depth Mask 做 downscale 降采样处理,以减少运算量。
此外,还可基于 Apple 的 CoreML 模型训练分割网络,在缺少深度图或不支持 LiDAR 的设备上提供兼容背景模糊能力,实现全设备覆盖。
6. 人像分割与前背景提取实战
深度图与人物前景掩码的联合使用,不仅限于背景模糊,还可用于背景替换、人像剪影、AR 场景遮挡等更加广泛的视觉功能。iOS 提供了 SemanticSegmentationMatte 接口,进一步提升分割精度与语义控制力。
利用 Depth + SegmentationMatte 进行精细化人像提取
对于支持人像模式的拍照结果,开发者可以提取 SemanticSegmentationMatteType.hair, .skin, .teeth 等多种语义掩码,用于构建多层前景模型。例如:
if let hairMatte = photo.semanticSegmentationMatte(for: .hair) {
let pixelBuffer = hairMatte.mattingImage
let hairMask = CIImage(cvPixelBuffer: pixelBuffer)
// 与原图合成,进行染发、边缘过渡等处理
}
通过对不同部位应用不同后处理方式,可以实现更加真实的人像渲染效果,例如:
- 头发使用渐变融合避免锯齿边;
- 皮肤区域做美白磨皮;
- 背景区域实现风格迁移或实时替换。
多层通道融合实现高质量背景替换
完整的人像替换流程包括以下几个步骤:
- 获取 RGB 图像、AVDepthData、PortraitMatte、SegmentationMatte;
- 构建 Composite Mask:将多个掩码按权重或优先级叠加;
- 使用 CIImage 或 Metal 将 Composite Mask 应用于原图,裁剪出前景;
- 后台填充背景图、视频流或 AR 虚拟空间;
- 使用图像混合滤镜(如
CIBlendWithMask,CIMaskToAlpha)完成前景融合。
此类方法已广泛应用于虚拟背景、虚拟主播、在线会议 App 等场景中,并成为消费级相机产品中的标准功能。
ARKit 中人物遮挡(People Occlusion)机制解构
在 ARKit 中,Apple 利用设备的深度感知能力与前景分割数据,实现了虚拟物体在人物背后的“遮挡”效果。该机制依赖以下要素:
- 实时人像分割:基于 TrueDepth 或摄像头 + CNN 模型生成;
- 实时深度图:基于 LiDAR 实时采集场景三维信息;
- 渲染管线集成:通过 SceneKit 或 Metal,将前景渲染层插入虚拟对象之前,构成遮挡层。
在 AVFoundation 中,开发者可模拟该机制,构建属于自己的 AR 人像渲染引擎,尤其适用于低成本 AR 内容创作场景。
7. 深度图预处理与精度提升策略
直接从设备采集到的 AVDepthData 数据往往存在一定程度的噪点、孔洞与不连续边缘,特别是在非纹理区域、光照不足或物体边缘处表现更为明显。因此,在使用前,必须对深度图进行一系列预处理操作,以提升其在后续应用中的可用性与稳定性。
深度值归一化与图像化处理
AVDepthData 的深度值单位通常是米(Depth)或视差单位(Disparity),其原始值为浮点型,无法直接用于图像显示或简单阈值判断。开发者通常需将其归一化为 0–1 范围后进行后续操作:
let depthBuffer = depthData.depthDataMap
CVPixelBufferLockBaseAddress(depthBuffer, .readOnly)
let width = CVPixelBufferGetWidth(depthBuffer)
let height = CVPixelBufferGetHeight(depthBuffer)
let baseAddress = CVPixelBufferGetBaseAddress(depthBuffer)!.assumingMemoryBound(to: Float32.self)
var minDepth: Float32 = Float.greatestFiniteMagnitude
var maxDepth: Float32 = 0.0
for y in 0..<height {
for x in 0..<width {
let value = baseAddress[y * width + x]
if value > 0 {
minDepth = min(minDepth, value)
maxDepth = max(maxDepth, value)
}
}
}
let depthRange = maxDepth - minDepth
归一化后的深度图不仅可以直接可视化(作为灰度图),也更适合在 OpenGL/Metal 中作为纹理处理输入,或者在 ML 网络中作为输入通道。
边缘保留滤波与去噪策略
常见的深度图噪点处理方法包括:
- 双边滤波(Bilateral Filter):保留边缘特征的同时平滑深度图,是深度图预处理中的经典算法。适合对低分辨率深度图进行处理后再上采样;
- 高斯模糊(Gaussian Blur):简化背景景深或做景深衰减处理,适合人像背景处理;
- 中值滤波(Median Filter):适合消除局部突变的噪点,适合边缘空洞填补。
如果结合 RGB 图像进行处理,还可以使用 引导滤波(Guided Filter),以 RGB 图像边缘为参考,提升深度边缘的一致性,尤其适合在人脸与背景交界处提升虚化准确性。
空洞区域修复
受光照遮挡、物体材质反射率等影响,深度图中常存在缺失区域(如玻璃、镜面或过曝区域),这些空洞区域会导致背景虚化或前景提取错误。常见修复策略包括:
- 双线性插值填补:对局部空洞使用邻近像素值进行平均;
- 边界外推(inpainting):结合边界值进行区域推测;
- 使用语义掩码引导修复:如果能识别出空洞区域位于背景,可安全地使用均值填补;若位于人物轮廓内部,则需精细处理。
实际工程中通常将孔洞判断与修复集成至预处理模块,确保后续合成逻辑的鲁棒性与稳定性。
8. 利用 Metal 加速深度图后处理流程
深度图后处理属于典型的“像素级密集计算”任务,尤其在需要高分辨率(如 1920×1440)深度图实时处理时,CPU 实现效率难以满足 30fps 的要求。因此,Apple 推荐使用 Metal 实现 GPU 加速处理,兼顾性能与电源效率。
Metal 处理深度图的常见操作场景
- 深度图归一化 → 转为 8bit 灰度图 → 显示在预览层上;
- 根据深度阈值裁剪图像前背景区域;
- 构建基于深度的模糊强度图并应用动态高斯模糊;
- 深度图双边滤波、空洞修复。
以灰度图构建为例,典型 Metal Shader 可将 32F 浮点深度值按 min-max 映射为 0–255 并输出至纹理:
kernel void depthToGrayscale(texture2d<float, access::read> inTexture [[texture(0)]],
texture2d<uchar, access::write> outTexture [[texture(1)]],
constant float &minDepth [[buffer(0)]],
constant float &depthRange [[buffer(1)]],
uint2 gid [[thread_position_in_grid]]) {
float depth = inTexture.read(gid).r;
float normalized = clamp((depth - minDepth) / depthRange, 0.0, 1.0);
outTexture.write(uchar4(normalized * 255.0), gid);
}
此类处理可直接集成至 AVCaptureVideoPreviewLayer 上的图像通路,实现边采集边预览边处理的完整图像链路。
性能调优建议
- 减少像素带宽,使用 RG8 或 Gray8 替代 RGBA;
- 调整线程组大小配合缓存布局,提升 GPU 吞吐效率;
- 避免在主线程执行 Metal 渲染调用,使用异步队列;
- 对于需处理前后两帧差值的算法,使用 RingBuffer 存储历史帧,避免多次 CPU-GPU 传输。
通过 Metal 构建完整深度图处理 pipeline,不仅可显著降低处理延迟、提升帧率,还能实现复杂特效算法(如景深模拟、虚拟绿幕)在移动端流畅运行,是深度处理工程化的关键路径之一。
本文转自 https://zhxin.blog.csdn.net/article/details/148675516,如有侵权,请联系删除。
119.AVDepthData、LiDAR 深度数据与人像模式全解析:iOS 真实景深图采集与处理实战
http://114.132.213.38:6250/archives/1751024430399
评论