【iOS ARKit】人形遮挡

人形遮挡简介

在 AR系统中,计算机通过对设备摄像头采集的图像进行视觉处理和组织,建立起实景空间,然后将生成的虚拟对象依据几何一致性原理嵌入到实景空间中,形成虚实融合的增强现实环境,再输出到显示系统中呈现给使用者。

正确实现虚拟物体与真实环境的遮挡关系,需要基于对真实环境3D结构的了解,感知真实世界的3D结构、重建真实世界的数字3D模型,然后基于深度信息实现正确的遮挡。但真实世界是一个非常复杂的3D 环境,精确快速地感知周围环境,建立一个足够好的真实世界3D模型非常困难,特别是在不使用其他传感器的情况下(如结构光、TOF、双目、激光等)。

随着移动设备处理性能的提高、新型传感设备的发明、新型处理方式的出现,虚实遮挡融合的问题也在逐步得到改善。在 ARKit3 中,苹果公司通过神经网络引入了人形遮挡功能,通过对真实场景中人体的精确检测识别,实现虚拟物体与人体的正确遮挡,虚拟物体可以被人体所遮挡,提升了 AR使用体验。

人形遮挡原理

遮挡问题在计算机图形学中其实就是深度排序问题。在AR初始化成功后,场景中所有的虚拟物体都有一个相对于 AR 世界坐标系的坐标,包括虚拟摄像机与虚拟物体,因此,图形渲染管线通过深度缓冲区(Depth Buffer)可以正确地渲染虚拟物体之间的遮挡关系。但是,从摄像机输人的真实世界图像数据并不包含深度信息,无法与虚拟物体进行深度对比。

为解决人形遮挡问题,ARKit 借助于神经网络技术将人体从背景中分离出来,并将分离出来的人体图像保存到新增加的人体分隔缓冲区(Segmentation Buffer)中,人体分隔缓冲区是一个像素级缓冲区,可以精确地将人体与环境区分开来,因此,通过人体分隔缓冲区,可以得到精确的人形图像数据。但仅仅将人体从环境中分离出来还不够,还是没有人体的深度信息,为此,ARKit 又新增一个深度估计缓冲区(EstimatedDepth Data Buffer),这个缓冲区用于存储人体的深度信息,但这些深度信息从何而来呢?借助A12及以上仿生处理器的强大性能及神经网络技术,ARKit 工程师们设计了一个只从输人的 RGB 图像估算人体深度信息的算法,这个深度信息每帧都进行更新。至此,通过 ARKit 既可以从人体分隔缓冲区得到人体区域信息,也可以通过深度估计缓冲区得到人体深度信息,图形渲染管线就可以正确地实现虚拟物体与人体的遮挡。

人形遮挡实现

人形遮挡的实现技术非常复杂,对计算资源要求也非常高,但在 ARKit 中使用该技术实现人形遮挡却非常简单。在 AR 应用中使用人形遮挡需要使用 ARWorld TrackingConfiguration 配置类,并设置其 frameSemantics值为 personSegmentation 或者 personSegmentation WithDepth 之---。当使用 personSegmentation 时,ARKit 不会估算检测到人形的深度信息,人形会无条件遮挡虚拟元素而不管虚拟元素远近。当使用 personSegmentation WithDepth 时,ARKit 在检测到人体时,不仅会分离出人形,还会计算人体到摄像机的距离,从而实现正确的人形遮挡。需要注意的是,只有A13及以上处理器才支持人形遮挡功能,因此在使用前需要先检查设备是否支持。人形遮挡的基本使用方法代码如下所示。

Swift 复制代码
//
//  HumanOcclusion.swift
//  ARKitDeamo
//
//  Created by zhaoquan du on 2024/2/4.
//

import SwiftUI
import ARKit
import RealityKit
import Combine

//HumanExtraction
struct HumanOcclusionView: View {
    
    var body: some View {
        HumanOcclusionContainer().edgesIgnoringSafeArea(.all).navigationTitle("人形遮挡")
    }
}

struct HumanOcclusionContainer: UIViewRepresentable {
    
    
    
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        guard ARWorldTrackingConfiguration.supportsFrameSemantics(.personSegmentationWithDepth) else {
            print("不支持人形遮挡")
            return arView
        }
        
        let config = ARWorldTrackingConfiguration()
        config.frameSemantics = .personSegmentationWithDepth
        config.planeDetection = .horizontal
        loadModel(arView: arView)
        arView.session.run(config)
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
        
       
        
    }
    
    
    func loadModel(arView: ARView){
        var cancelable : AnyCancellable?
        cancelable = Entity.loadAsync(named: "fender_stratocaster.usdz").sink(
            receiveCompletion: { completion in
                if case let .failure(error) = completion {
                    print("无法加载模型,错误:\(error.localizedDescription)")
                }
                cancelable?.cancel()
            }, receiveValue: { entity in
                let planAnchor = AnchorEntity(plane: .horizontal)
                planAnchor.addChild(entity)
                arView.scene.addAnchor(planAnchor)
                
                cancelable?.cancel()
                
            })
    }
    
    
}

编译运行,在检测到的平面上放置虚拟物体,当人从虚拟物体前面或后面经过时会出现正确的虚实遮挡,AR虚拟物体不会再漂浮于环境之上,可信度大幅提升。

ARKit 对完整人形检测遮挡效果表现很好,除此之外,对人体局部肢体,如手、脚也有比较好的检测识别和遮挡效果,如图所示。从图中可以看到,ARKit 对人形的区分还是比较精确的,当然,由于深度信息是由神经网络估计得出,而非真实的深度值,所以也会出现深度信息不准确、边缘区分不清晰的问题。

具体代码地址:GitHub - duzhaoquan/ARkitDemo

相关推荐
咕噜签名分发冰淇淋5 小时前
免下载苹果 IPA 文件重签名工具:快速更换应用名称和 BID的教程
ios
二流小码农13 小时前
鸿蒙开发:DevEcoStudio中的代码提取
android·ios·harmonyos
Digitally19 小时前
如何用4 种可靠的方法更换 iPhone(2025 年指南)
ios·iphone
9765033351 天前
iOS 审核 cocos 4.3a【苹果机审的“分层阈值”设计】
flutter·游戏·unity·ios
I烟雨云渊T1 天前
iOS Alamofire库的使用
ios
程序员老刘·1 天前
iOS 26 beta1 真机无法执行hot reload
flutter·ios·跨平台开发·客户端开发
EndingCoder1 天前
React Native 构建与打包发布(iOS + Android)
android·react native·ios
程序员小刘1 天前
HarmonyOS 5鸿蒙多端编译实战:从Android/iOS到HarmonyOS 5 的跨端迁移指南详
android·ios·华为·harmonyos
I烟雨云渊T1 天前
iOS swiftUI的实用举例
ios·swiftui·swift
getapi1 天前
将 App 安装到 iPhone 真机上测试
ios·iphone