首页 > 解决方案 > ARKit People Occlusion 样本是如何完成的?

问题描述

这可能是一个晦涩难懂的问题,但我在网上看到很多非常酷的示例,说明人们如何使用 ARKit 3 中的新 ARKit 人物遮挡技术来有效地将人物与背景“分离”,并对“人”(见这里)。

在查看 Apple 提供的源代码和文档时,我发现我可以segmentationBuffer从 ARFrame 中检索,就像这样;

func session(_ session: ARSession, didUpdate frame: ARFrame) {
    let image = frame.capturedImage
    if let segementationBuffer = frame.segmentationBuffer {

        // Get the segmentation's width
        let segmentedWidth = CVPixelBufferGetWidth(segementationBuffer)

        // Create the mask from that pixel buffer.
        let sementationMaskImage = CIImage(cvPixelBuffer: segementationBuffer, options: [:])

        // Smooth edges to create an alpha matte, then upscale it to the RGB resolution.
        let alphaUpscaleFactor = Float(CVPixelBufferGetWidth(image)) / Float(segmentedWidth)
        let alphaMatte = sementationMaskImage.clampedToExtent()
            .applyingFilter("CIGaussianBlur", parameters: ["inputRadius": 2.0)
            .cropped(to: sementationMaskImage.extent)
            .applyingFilter("CIBicubicScaleTransform", parameters: ["inputScale": alphaUpscaleFactor])

        // Unknown...

    }
}

在“未知”部分,我试图确定如何在原始相机源之上渲染我的新“模糊”人物。似乎没有任何方法可以在原始相机源的“顶部”绘制新的 CIImage,因为 ARView 无法手动更新。

标签: swiftscenekitaugmented-realityarkitrealitykit

解决方案


在下面的代码片段中,我们看到personSegmentationWithDepth了深度合成的类型属性(有 RGB、Alpha 和深度通道):

// Automatically segmenting and then compositing foreground (people), 
// middle-ground (3D model) and background.

let session = ARSession()

if let configuration = session.configuration as? ARWorldTrackingConfiguration {
    configuration.frameSemantics.insert(.personSegmentationWithDepth)
    session.run(configuration)
}

您可以手动访问 CVPixelBuffer 中的世界跟踪深度数据(执行分割的深度值):

let image = frame.estimatedDepthData

您可以手动访问 CVPixelBuffer 中的人脸跟踪深度数据(来自 TrueDepth 相机):

let image = session.currentFrame?.capturedDepthData?.depthDataMap

此外,generateDilatedDepthARKit 3.0 中有一个实例方法:

func generateDilatedDepth(from frame: ARFrame, 
                       commandBuffer: MTLCommandBuffer) -> MTLTexture

在您的情况下,您必须使用estimatedDepthData,因为 Apple 文档说:

它是一个缓冲区,表示您用于遮挡虚拟内容的摄像机源的估计深度值。

var estimatedDepthData: CVPixelBuffer? { get }

如果您通过或使用合成技术DEPTH将此缓冲区中的数据相乘(首先您必须将深度通道转换为 RGB),您将获得很棒的效果。RGBALPHA

看看这 6 幅图像:下排代表用深度通道校正的三幅 RGB 图像:深度分级、深度模糊、深度点位置传递。

在此处输入图像描述


推荐阅读