在Xcode中我们可以通过创建ARResourceGroup, 添加.arobject的文件到ReferenceObject, 以及相关模型来到达3D物体检测识别的效果。同样的效果我们在Swift Playgrounds中亦可以实现, 但到目前为止(2022-03-15)Swift Playgrounds还没有可以创建ARResourceGroup的功能菜单,所以我们需要手动去创建。
1. 空间特征信息提取
我们使用iPad为例,首先需要对所要检测识别的实物进行空间特征信息提取,并且储存为.arobject格式的文件,然后导入到工程文件。截至目前(2022-03-15)我们有两种办法获取物体的空间特征信息,这两种方法都适用于iOS端或iPadOS端设备,这里我们使用iPad。
方法一:通过Apple官方提供的ARKit Scanner应用程序。
下载地址:Apple Developer Documentation
扫描特征信息与提取,请看下载链接中的教程。获取的特征信息为.arobject的文件,我们需要将这个文件保存并上传到Swift Playgrounds的工程文件中。
方法二:通过Reality Composer获取
我们需要在ios端或者ipados端App Store下载Reality Composer,按照视频演示步骤,也可以获得物体特征信息文件,并保存上传到Swift Playgrounds的工程文件里。
2. 创建参考物体库
当我们将物体的空间特征信息文件.arobject以及模型文件上传到swift playgrounds工程文件后,就可以开始创建参考物体库,具体代码如下:
var trackedObjectLibs = Set()
创建物体特征信息的url :
let arObjectUrl = Bundle.main.url(forResource: "MXMaster3", withExtension: "arobject")
通过特征信息url创建参考物体:
let referenceObject = try? ARReferenceObject(archiveURL: arObjectUrl!)
给参考物体一个与模型一样的名字,并且添加参考物体到参考物体库中:
referenceObject?.name = "MXMaster3"
trackedObjectLibs.insert(referenceObject!)
3. 配置与加载模型
ARKit并没给3D物体识别提供独一的Configuration,而是使用ARWorldTrackingConfiguration.
将手动创建的参考物体库分配给配置下的detectionObjects检测物体库,ARKit只会用这个检测物体库里的特征信息文件与用户环境中的物体特征信息作匹配。
let config = ARWorldTrackingConfiguration()
config.detectionObjects = trackedObjectLibs
最后我么可以通过 session(_ session: ARSession, didAdd anchors: [ARAnchors])方法来加载模型。
总结:
关于物体特征信息获取的两种办法,我个人的体验是第一种方法获取的无论是特征信息数量还是准确度都能满足较好的用户体验。
以下为完整代码:
import SwiftUI
import ARKit
import RealityKit
import Combine
struct ContentView: View {
var body: some View {
ZStack {
ARViewContainer()
.edgesIgnoringSafeArea(.all)
}
}
}
struct ARViewContainer: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
var trackedObjectLibs = Set()
let arObjectUrl = Bundle.main.url(forResource: "MXMaster3", withExtension: "arobject")
let referenceObject = try? ARReferenceObject(archiveURL: arObjectUrl!)
referenceObject?.name = "MXMaster3"
trackedObjectLibs.insert(referenceObject!)
let config = ARWorldTrackingConfiguration()
let peopleOcclusion: ARConfiguration.FrameSemantics = [.personSegmentationWithDepth]
if type(of: config).supportsFrameSemantics(peopleOcclusion){
config.frameSemantics = peopleOcclusion
}
config.detectionObjects = trackedObjectLibs
arView.session.delegate = arView
arView.session.run(config, options: [])
return arView
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
extension ARView: ARSessionDelegate {
public func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
guard let objectAnchor = anchors[0] as? ARObjectAnchor else {return}
let objectAnchorEntity = AnchorEntity(anchor: objectAnchor)
let referenceModelName = objectAnchor.referenceObject.name
var cancellable: AnyCancellable? = nil
cancellable = ModelEntity.loadModelAsync(named: referenceModelName!, in: .main).sink(receiveCompletion: { status in
print("Completion: \(status)")
cancellable?.cancel()
}, receiveValue: { entity in
entity.setOrientation(simd_quatf.init(angle: -(.pi/2.2), axis: simd_float3(x: 0, y: 1, z: 0)), relativeTo: nil)
entity.setPosition(simd_float3(x: 0, y: 0.1, z: 0), relativeTo: nil)
objectAnchorEntity.addChild(entity)
})
self.scene.addAnchor(objectAnchorEntity)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)