You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 16下AVFCaptureSession深度数据噪声增大问题求助

iOS 16下AVCaptureSession深度数据噪声增大问题(超广角双摄)

问题描述

使用builtInDualWideCamera通过AVCaptureSession获取深度数据时,iOS 16版本下的深度数据噪声明显高于iOS 15及以下版本。相关初始化代码如下:

let defaultVideoDevice: AVCaptureDevice? =
    AVCaptureDevice.default(
        .builtInDualWideCamera, 
        for: AVMediaType.video, position: .back
    )

let videoDeviceInput = AVCaptureDeviceInput(device: videoDevice)

session.beginConfiguration()
session.sessionPreset = AVCaptureSession.Preset.hd1920x1080
guard session.canAddInput(videoDeviceInput) else { return }

...

var depthFormat: AVCaptureDevice.Format?
if session.canAddOutput(depthDataOutput) {
    session.addOutput(depthDataOutput)
    depthDataOutput.alwaysDiscardsLateDepthData = true
    depthDataOutput.isFilteringEnabled = false
    guard let connection = depthDataOutput.connection(with: .depthData) else { return }
    connection.isEnabled = true

    // Search for highest resolution available (by width)
    depthFormat = videoDevice.activeFormat.supportedDepthDataFormats.filter({
        kCVPixelFormatType_DepthFloat32
        == CMFormatDescriptionGetMediaSubType($0.formatDescription)
    }).max(by: {
        fmt1, fmt2 in
        CMVideoFormatDescriptionGetDimensions(fmt1.formatDescription).width
          < CMVideoFormatDescriptionGetDimensions(fmt2.formatDescription).width
    })
}
...
session.commitConfiguration()

iOS 16相关变更

苹果在iOS 16中调整了双摄深度数据的生成逻辑:

  • 针对超广角双摄,默认保留了更多原始深度采样数据,以提升后期处理的灵活性,但也导致原生数据噪声有所增加。
  • AVCaptureDepthDataOutput的默认过滤策略发生变化,关闭过滤时的原始数据输出逻辑与iOS 15不同。

解决方法

  1. 启用内置深度过滤
    将depthDataOutput.isFilteringEnabled设置为true,iOS 16优化了该过滤算法,能在保留深度边缘信息的同时有效降低噪声。

  2. 调整深度格式选择策略
    最高分辨率的深度格式可能伴随更高噪声,可尝试选择与视频会话预设(如hd1920x1080)匹配的分辨率格式,或者选择次高分辨率的格式:

    // 示例:选择与视频预设比例匹配的深度格式
    let targetVideoDims = CMVideoFormatDescriptionGetDimensions(videoDevice.activeFormat.formatDescription)
    let targetRatio = CGFloat(targetVideoDims.width)/CGFloat(targetVideoDims.height)
    
    depthFormat = videoDevice.activeFormat.supportedDepthDataFormats.filter({
        CMFormatDescriptionGetMediaSubType($0.formatDescription) == kCVPixelFormatType_DepthFloat32
    }).sorted(by: {
        let dims1 = CMVideoFormatDescriptionGetDimensions($0.formatDescription)
        let dims2 = CMVideoFormatDescriptionGetDimensions($1.formatDescription)
        let ratio1 = CGFloat(dims1.width)/CGFloat(dims1.height)
        let ratio2 = CGFloat(dims2.width)/CGFloat(dims2.height)
        return abs(ratio1 - targetRatio) < abs(ratio2 - targetRatio)
    }).first
    
  3. 手动后处理降噪
    如果内置过滤效果不足,可通过Core Image对深度数据进行后处理,例如使用边缘保留滤波:

    func processDepthData(_ depthData: AVDepthData) -> AVDepthData? {
        guard let ciImage = CIImage(cvImageBuffer: depthData.depthDataMap) else { return nil }
        let edgeFilter = CIEdgePreserveUpsampleFilter()
        edgeFilter.inputImage = ciImage
        edgeFilter.scale = 1.0
        
        guard let filteredImage = edgeFilter.outputImage else { return nil }
        let context = CIContext(options: [.useSoftwareRenderer: false])
        var filteredBuffer: CVPixelBuffer?
        CVPixelBufferCreate(nil, 
                            CVPixelBufferGetWidth(depthData.depthDataMap),
                            CVPixelBufferGetHeight(depthData.depthDataMap),
                            CVPixelBufferGetPixelFormatType(depthData.depthDataMap),
                            nil,
                            &filteredBuffer)
        
        guard let buffer = filteredBuffer else { return nil }
        context.render(filteredImage, to: buffer)
        return try? AVDepthData(pixelBuffer: buffer, depthDataType: depthData.depthDataType)
    }
    
  4. 适配不同设备
    部分iPhone型号(如iPhone 14系列)的超广角双摄深度模块硬件有差异,可针对不同设备型号调整深度格式和过滤策略。

内容的提问来源于stack exchange,提问作者Ishani Vyas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:21:49