【iOS-ARKit】扫描和检测3D对象-Scanning and Detecting 3D Objects

记录真实世界对象的空间特征,然后使用结果在用户环境中查找这些对象并触发AR内容。

Overview

构建令人信服的AR体验的一种方法是识别用户环境的特征并使用它们触发虚拟内容的外观。 例如,当用户将他们的设备指向显示的雕塑或工件时,博物馆应用可以添加交互式3D可视化。

在iOS 12中,您可以通过在ARKit中启用对象检测来创建此类AR体验:您的应用程序提供参考对象,它可以对已知真实世界对象的三维空间要素进行编码,并且在AR session过程中,ARKit会告诉您的应用何时何地检测到相应的真实世界对象。

This sample code project provides multiple ways to make use of object detection:

此示例代码项目提供了多种方式来使用对象检测:

  • 运行应用程序扫描现实世界的对象并导出参考对象文件,您可以在自己的应用程序中使用该文件来检测该对象。
  • 使用此示例应用程序中演示的 ARObjectScanningConfigurationARReferenceObject 类将引用对象记录为您自己的资产生产管道的一部分。
  • 在世界跟踪AR会话中使用 detectionObjects 来识别参考对象并创建AR交互。

使用iOS应用程序扫描真实世界对象

扫描和定义ARKit可用于检测的参考对象的编程步骤非常简单。 (请参阅下面的“在AR会话中创建参考对象”。)但是,创建的参考对象的保真度以及您在自己的应用程序中检测参考对象的成功取决于扫描时与物体的物理交互。 在您的iOS设备上构建并运行此应用程序,以便通过一系列获取高质量扫描数据的步骤,从而生成可用于在自己的应用程序中进行检测的参考对象文件。

【iOS-ARKit】扫描和检测3D对象-Scanning and Detecting 3D Objects_第1张图片

  1. 准备扫描。第一次运行时,应用程序会显示一个框,粗略估计任何真实世界物体在相机视图中居中显示的大小。将要扫描的对象放置在没有其他对象的表面上(如空的桌面)。然后移动设备,使对象显示在框中居中,然后点击下一步按钮。
  2. 定义边界框。在扫描之前,您需要告诉应用程序世界的哪个区域包含您要扫描的对象。拖动以3D方式移动框,或者按住框的一侧,然后拖动以调整其大小。 (或者,如果您不改变框,则可以在对象周围移动,并且应用程序将尝试自动在其周围放置一个框。)确保边界框仅包含要扫描的对象的功能(不是来自环境),然后点击扫描按钮。
  3. 扫描对象。四处移动以从不同角度查看对象。该应用程序会突出显示边界框的各个部分,以指示您何时扫描足以从相应方向识别对象。请务必扫描您希望您的应用的用户能够识别该对象的各个方面。扫描完成后,应用程序自动进入下一步,或者点击“停止”按钮手动继续。
  4. 调整原点。该应用程序显示x,y和z坐标轴线,显示对象的锚点或原点。拖动圆圈以将原点相对于对象移动。在这一步中,您还可以使用添加(+)按钮以USDZ格式加载3D模型。应用程序会在检测到真实世界对象时显示AR中出现的模型,并使用模型的大小来调整参照对象的比例。完成后点击测试按钮。
  5. 测试和导出。该应用程序现在创建了一个 ARReferenceObject 并重新配置了会话以检测它。在不同的环境和光照条件下,从不同角度观察真实世界的物体,以验证ARKit能够可靠地识别其位置和方向。点击导出按钮打开分享表以保存完成的 .arobject 文件。例如,您可以使用AirDrop轻松将其发送到您的开发Mac,或将其发送到“文件”应用程序以将其保存到iCloud Drive。

注意:参考对象仅包含ARKit识别现实世界对象所需的空间特征信息,并不是该对象的可显示3D重建。

检测AR体验中的参考对象

您可以使用Xcode资产目录在应用程序中捆绑引用对象以用于检测:

  1. 打开项目的资产目录,然后使用添加按钮(+)添加新的AR资源组。
  2. 将.arobject文件从Finder拖到新创建的资源组中。
  3. 或者,对于每个参考对象,请使用检查员为自己的使用提供一个描述性名称。

注意:将想要在同一个会话中查找的所有对象放入资源组中,并使用单独的资源组来保存一组对象以在单独的会话中使用。 例如,博物馆应用程序可能会使用单独的会话(并因此分开资源组)来识别博物馆不同侧翼的显示。

要在AR会话中启用对象检测,请将要检测的引用对象加载为 ARReferenceObject 实例,将这些对象提供给ARWorldTrackingConfigurationdetectionObjects 属性,然后使用该配置运行ARSession:

let configuration = ARWorldTrackingConfiguration()
configuration.detectionObjects = ARReferenceObject.referenceObjects(inGroupNamed: "gallery", bundle: nil)
sceneView.session.run(configuration)

当ARKit检测到您的一个参考对象时,会话会自动将相应的 ARObjectAnchor 添加到其锚点列表中。 要响应正在识别的对象,请实施一个适当的 ARSessionDelegateARSCNViewDelegateARSKViewDelegate 方法,以报告添加到会话的新锚点。 例如,在基于SceneKit的应用程序中,您可以实现 renderer:didAddNode:forAnchor: 向场景添加3D资产,自动匹配锚点的位置和方向

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    if let objectAnchor = anchor as? ARObjectAnchor {
        node.addChildNode(self.model)
    }
}

为了获得对象扫描和检测的最佳效果,请遵循以下提示:

  • 扫描和检测物体时,ARKit会寻找清晰,稳定的视觉细节区域。 详细的纹理物体比普通或反射物体更适合检测。
  • 对象扫描和检测针对小到足以放在桌面上的对象进行了优化。
  • 要检测的物体必须与扫描的参考物体具有相同的形状。 刚性物体比软体或弯曲,扭曲,折叠或以其他方式改变形状的物品更适合检测。
  • 当要检测的真实世界物体的照明条件与扫描原始物体的条件类似时,检测效果最佳。 一致的室内照明效果最好。
  • 高质量的对象扫描需要峰值设备性能。 使用最新的高性能iOS设备扫描的参考对象适用于在所有ARKit支持的设备上进行检测。

在AR会话中创建参考对象

此示例应用程序提供了一种创建参考对象的方法。 您还可以在自己的应用中扫描引用对象,例如,构建资产管理工具以定义进入其他应用的AR内容。

参考对象对ARKit用于跟踪设备位置和方向的内部空间映射数据进行编码。 要启用对象扫描所需的高质量数据收集,请使用ARObjectScanningConfiguration 运行会话:

let configuration = ARObjectScanningConfiguration()
configuration.planeDetection = .horizontal
sceneView.session.run(configuration, options: .resetTracking)

在对象扫描AR会话期间,从各个角度扫描对象以确保收集足够的空间数据以识别它。 (如果您正在构建自己的对象扫描工具,请帮助用户完成本示例应用程序提供的相同步骤。)

扫描完成后,调用createReferenceObjectWithTransform:center:extent:completionHandler: 从会话映射的用户环境区域生成一个ARReferenceObject:

// Extract the reference object based on the position & orientation of the bounding box.
sceneView.session.createReferenceObject(
    transform: boundingBox.simdWorldTransform,
    center: float3(), extent: boundingBox.extent,
    completionHandler: { object, error in
        if let referenceObject = object {
            // Adjust the object's origin with the user-provided transform.
            self.scannedReferenceObject =
                referenceObject.applyingTransform(origin.simdTransform)
            self.scannedReferenceObject!.name = self.scannedObject.scanName
            creationFinished(self.scannedReferenceObject)
        } else {
            print("Error: Failed to create reference object. \(error!.localizedDescription)")
            creationFinished(nil)
        }
})

当检测到参考对象时,ARKit根据参考对象定义的原点报告其位置。 如果要放置看起来与真实世界对象位于同一表面上的虚拟内容,请确保将参照对象的原点放置在现实世界对象所在的位置。 要在捕获 ARReferenceObject 之后调整原点,请使用referenceObjectByApplyingTransform: 方法。

获取ARReferenceObject之后,可以立即使用它来检测(请参阅上面的“在AR Experience中检测参考对象”),或将其另存为 .arobject 文件,以便在稍后的会话或其他基于ARKit的应用程序中使用。 要将对象保存到文件,请使用exportObjectToURL:previewImage:error: 方法。 在该方法中,您可以提供Xcode的真实世界对象的图片以用作预览图像。

See Also

物体检测

  • ARReferenceObject
  • ARObjectAnchor
  • ARObjectScanningConfiguration

你可能感兴趣的:(iOS)