ARKit 人物遮挡样本是如何完成的?

Zba*_*itZ 3 augmented-reality scenekit swift arkit realitykit

这可能是一个晦涩的问题,但我在网上看到很多非常酷的示例,展示人们如何使用 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...

    }
}
Run Code Online (Sandbox Code Playgroud)

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

ARG*_*Geo 5

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

// 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)
}
Run Code Online (Sandbox Code Playgroud)

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

let image = frame.estimatedDepthData
Run Code Online (Sandbox Code Playgroud)

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

let image = session.currentFrame?.capturedDepthData?.depthDataMap
Run Code Online (Sandbox Code Playgroud)

另外,ARKit 3.0 中有一个generateDilatedDepth实例方法:

func generateDilatedDepth(from frame: ARFrame, 
                       commandBuffer: MTLCommandBuffer) -> MTLTexture
Run Code Online (Sandbox Code Playgroud)

在你的情况下,你必须使用,estimatedDepthData因为苹果文档说:

它是一个缓冲区,表示用于遮挡虚拟内容的相机输入的估计深度值。

var estimatedDepthData: CVPixelBuffer? { get }
Run Code Online (Sandbox Code Playgroud)

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

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

在此输入图像描述