iOS深度相机开发:CVPixelBufferRef视频缓冲区与深度缓冲区方向不一致问题咨询
解决iOS深度相机视频与深度缓冲区方向/尺寸不匹配问题
这确实是iOS深度相机开发里的常见坑——AVCaptureSession输出的深度数据默认会保留设备传感器的原生方向(通常是横屏,对应640x480的尺寸),而你的视频数据已经根据应用的竖屏方向完成了适配旋转,导致两者的尺寸和方向无法直接对应。下面是具体的解决方法:
核心思路
利用AVDepthData提供的原生转换API,将深度数据的方向和尺寸对齐到视频帧的方向,确保两者的像素坐标可以一一对应。
具体实现步骤
在你获取到depthData之后,添加以下代码完成深度数据的对齐:
- (void)dataOutputSynchronizer:(AVCaptureDataOutputSynchronizer *)synchronizer didOutputSynchronizedDataCollection:(AVCaptureSynchronizedDataCollection *)synchronizedDataCollection { AVCaptureSynchronizedDepthData *syncedDepthData = (AVCaptureSynchronizedDepthData *)[synchronizedDataCollection synchronizedDataForCaptureOutput:depthDataOutput]; AVCaptureSynchronizedSampleBufferData *syncedVideoData = (AVCaptureSynchronizedSampleBufferData *)[synchronizedDataCollection synchronizedDataForCaptureOutput:dataOutput]; if (syncedDepthData.depthDataWasDropped || syncedVideoData.sampleBufferWasDropped) { return; } AVDepthData *depthData = syncedDepthData.depthData; CMSampleBufferRef sampleBuffer = syncedVideoData.sampleBuffer; if (!CMSampleBufferDataIsReady(sampleBuffer)) { return; } // 关键步骤:获取视频帧的方向并转换深度数据 AVCaptureConnection *videoConnection = [dataOutput connectionWithMediaType:AVMediaTypeVideo]; AVCaptureVideoOrientation targetOrientation = videoConnection.videoOrientation; // 将深度数据转换为视频的方向,自动适配尺寸 AVDepthData *convertedDepthData = [depthData convertingToDepthDataFormat:depthData.depthDataFormat videoOrientation:targetOrientation]; CVPixelBufferRef alignedDepthPixelBuffer = convertedDepthData.depthDataMap; // 现在alignedDepthPixelBuffer的尺寸应该和视频帧(480x640)完全匹配 // 后续可以用这个对齐后的深度缓冲区来做像素-深度值的对应 // ... 你的后续业务代码 }
补充说明
为什么会出现这个差异?
深度传感器的输出方向与主摄像头的原生硬件方向一致(横屏),当你将AVCaptureSession的方向设置为竖屏时,视频数据会被自动旋转适配,但深度数据不会触发自动转换,因此需要手动处理方向对齐。镜像场景的额外处理
如果你的应用支持前置摄像头镜像拍摄,还需要判断镜像状态并添加对应转换:BOOL isMirrored = NO; CMItemCount attachmentCount = CMSampleBufferGetNumSampleAttachments(sampleBuffer); if (attachmentCount > 0) { CFDictionaryRef attachments = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, YES)[0]; isMirrored = CFDictionaryGetValue(attachments, kCMSampleBufferAttachmentKey_MirroringApplied) ? YES : NO; } // 带镜像的深度数据转换 AVDepthData *convertedDepthData = [depthData convertingToDepthDataFormat:depthData.depthDataFormat videoOrientation:targetOrientation mirroring:isMirrored];关于转换的可靠性
这个API是Apple官方提供的,转换后的深度数据会保留原有的精度和格式,不会丢失深度信息,可以放心用于后续的距离计算逻辑。
内容的提问来源于stack exchange,提问作者Eugene Alexeev
相关产品推荐
相关产品推荐

