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不同。
解决方法
启用内置深度过滤
将depthDataOutput.isFilteringEnabled设置为true,iOS 16优化了该过滤算法,能在保留深度边缘信息的同时有效降低噪声。调整深度格式选择策略
最高分辨率的深度格式可能伴随更高噪声,可尝试选择与视频会话预设(如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手动后处理降噪
如果内置过滤效果不足,可通过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) }适配不同设备
部分iPhone型号(如iPhone 14系列)的超广角双摄深度模块硬件有差异,可针对不同设备型号调整深度格式和过滤策略。
内容的提问来源于stack exchange,提问作者Ishani Vyas
相关产品推荐
相关产品推荐

