swift - 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 无法手动更新。
解决方案
在下面的代码片段中,我们看到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
此外,generateDilatedDepth
ARKit 3.0 中有一个实例方法:
func generateDilatedDepth(from frame: ARFrame,
commandBuffer: MTLCommandBuffer) -> MTLTexture
在您的情况下,您必须使用estimatedDepthData
,因为 Apple 文档说:
它是一个缓冲区,表示您用于遮挡虚拟内容的摄像机源的估计深度值。
var estimatedDepthData: CVPixelBuffer? { get }
如果您通过或使用合成技术DEPTH
将此缓冲区中的数据相乘(首先您必须将深度通道转换为 RGB),您将获得很棒的效果。RGB
ALPHA
看看这 6 幅图像:下排代表用深度通道校正的三幅 RGB 图像:深度分级、深度模糊、深度点位置传递。
推荐阅读
- java - Android BuildConfig 类值为空
- angular - 如何在 Angular 9 项目中使用 amplify-authenticator 修复生产构建?
- java - 建议如何编写在 SFTP 位置可用的文本文件
- javascript - 什么是支持不同变体的 javascript 库的好策略
- javascript - 节点 JS 异步执行
- c - C语言内联函数的语法错误
- python-3.x - python3 EOFError:读取一行时出现EOF
- asp.net - 为什么控制器在使用HttpPost请求时收不到参数?
- c - 如何始终分配大小为 32 倍数的静态数组
- json - .NET NewtonSoft JSON 使用不同的属性名称反序列化