• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

ARKit增强现实:特征点和水平面检测

到目前为止,您可能已经在您的iphone上使用了增强现实应用程序,其中的虚拟对象看起来栩栩如生并与环境特征很好地融合在一起。在本系列中,您将学习如何在您自己的 ios 应用程序中使用环境光检测和水平面检测来实现这一点,以改进您的增强现实应用程序。本教程将重点介绍在 ARKit 中显示水平面和特征点。

通常,在使用增强现实时,您希望将虚拟对象放置在平坦的表面上,例如桌子、桌子甚至地面。为了准确地做到这一点,重要的是您能够在开始之前检测到这些对象。检测到您的飞机后,该对象将使用一系列点将您的虚拟对象锚定在其上,并且即使您四处移动设备,该对象也会保留在那里。

入门

Xcode 版本

在开始之前,请确保您的mac上安装了最新版本的 Xcode 。这一点非常重要,因为 ARKit 仅适用于 Xcode 9 或更高版本。您可以通过打开 Xcode 并转到  上方工具栏中的 Xcode  >  About Xcode来检查您的版本。

如果您的 Xcode 版本早于 Xcode 9,您可以前往Mac App Store 并免费更新它。如果您还没有 Xcode,您也可以免费下载并安装它。

示例项目

新项目

在确定您拥有正确版本的 Xcode 之后,您需要创建一个新的 Xcode 项目。 

继续打开 Xcode,然后单击 Create a new Xcode project。

ARKit增强现实:特征点和水平面检测  第1张

您可能习惯于制作单视图应用程序, 但对于本教程,您将需要选择 增强现实应用程序。 然后单击 下一步。

ARKit增强现实:特征点和水平面检测  第2张

游戏框架_

您可以为您的项目命名任何您喜欢的名称,但我将命名我的 平面检测。 您还会注意到底部有一个选项,您可以在其中选择 SceneKit、SpriteKit 和meta l。 

这些都是 Apple 的游戏框架,出于本教程的目的,我们将使用 SceneKit ,因为我们将使用 3D 对象。 

如果尚未选择 SceneKit  ,请继续选择它。您的屏幕应如下所示:

ARKit增强现实:特征点和水平面检测  第3张

准备测试

连接 iPhone

由于 Xcode Simulator 没有摄像头,因此您需要插入 iPhone。不幸的是,如果您没有 iPhone,则需要借一部才能学习本教程(以及任何其他与相机相关的应用程序)。如果您已经将 iPhone 连接到 Xcode,则可以跳到下一步。

Xcode 9 中一个非常棒的新功能是您可以在设备上无线调试您的应用程序,所以让我们现在花点时间进行设置:

在顶部菜单栏中,选择“ 窗口 ” > “ 设备和模拟器”。 在出现的窗口中,确保 在顶部选择了设备 。

现在,使用避雷线插入您的设备。这应该使您的设备出现在“ 设备和模拟器 ”窗口的左窗格中。只需单击您的设备,然后选中 通过网络连接 框。

ARKit增强现实:特征点和水平面检测  第4张

您现在可以在这款 iPhone 上为所有未来的应用程序进行无线调试。

完成设置

现在您的设置已完成。你应该有一个工作的 ARKit 应用程序,你可以在你刚刚连接的 iPhone 上测试它。在 Xcode 左上角的 Run 和 Stop 按钮旁边,选择您的 模拟器下拉菜单中的设备。我选择了 Vardhan 的 iPhone, 但您需要选择您的特定设备。

现在您已经完成了初始项目的创建,单击 “运行”后,您应该会看到一个虚拟宇宙飞船出现在您的世界中。 它应该是这样的:

ARKit增强现实:特征点和水平面检测  第5张

理论上

在我们真正开始编写这个应用程序之前,了解 ARKit 如何实际检测这些平面非常重要。在本教程中,我们将探讨两个主要概念:特征点和水平面。简而言之,iPhone 上的增强现实与称为 Visual Inertial O dom etry  (VIO)的过程一起工作,该过程从您的相机和内部传感器获取数据以获得对场景的 3D 理解。

特征点

那么,究竟什么是特征点?每个图像自然都会有其独特的特征。例如,在一朵花中,会有独特的形状,或者在地毯上,可能有独特的纹理。

这些点代表在相机图像中检测到的显着特征。它们在 3D 世界坐标空间中的位置被推断为 ARKit 执行的图像分析的一部分,以便准确跟踪设备的位置、方向和运动。总而言之,这些点与相机视野中的现实世界对象的轮廓松散相关。— 苹果

正如 Apple 的文档所解释的,特征点可帮助您的设备(和 ARKit)了解您的世界的深度和“真实感”,从而使增强现实更加准确。这些还用于帮助为您的虚拟对象提供一个锚定的位置,帮助他们了解在您移动设备时该留在哪里。

水平面

与特征点类似,水平面可帮助您的应用了解其周围环境。毫不奇怪,特征点和水平平面非常紧密地耦合,因为没有特征点就无法检测到这些平面。 

使用 iPhone 的内置传感器,包括相机(当然)和这些特征点的组合,ARKit 可以检测场景中的各种平面。这些计算和估计在每一帧都进行,并且可以一次检测到多个平面。

当您运行启用了 planeDetection 选项的世界跟踪 AR 会话时,该会话会自动为 ARKit 使用后置摄像头检测到的每个平面添加一个 ARPlaneAnchor 对象到其锚点列表中。每个平面锚提供有关估计的表面位置和形状的信息。— 苹果

在代码中

伟大的!您现在已经拥有了一个可以工作的 ARKit 应用程序。这个应用程序的目标是能够检测水平平面并使用特征点(放置在 ARKit 场景中的虚拟点)将其可视化。

入门代码

您现在对什么是特征点和水平面有了深入的了解,并且您现在可以开始将它们编程到应用程序中。如果您想了解更多有关特征点和水平面的背景知识,我建议您阅读Apple 的文档。

Vardhan Agrawal 2017 年 10 月 24 日 增强现实

由于很多代码是样板代码,我们将保留它,但至于宇宙飞船,让我们通过删除处理其放置的代码来摆脱它。在您的ViewController.swift 文件中,在您的 viewDidLoad()方法中, 删除以下代码行:

let scene = SCNScene(named: "art.scnassets/ship.scn")!
sceneView.scene = scene

特征点

启用调试选项

您的 Xcode 项目现在可以开始工作了。我们的第一步是添加可见的特征点。您可能不会让它们对生产应用程序可见,但它是调试增强现实应用程序的绝佳功能。

这一步非常简单,可以一行完成。在您的 viewDidLoad()方法中,添加以下代码行:

sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]

此代码使用一组选项配置调试选项。您可以通过将其他功能添加到此数组来启用它们,但现在,我们只需要显示我们的特征点。这是您运行应用程序时的样子:

ARKit增强现实:特征点和水平面检测  第6张

如您所见,所有检测到的特征点都是可见的。如果您没有看到它们,请尝试移动您的 iPhone,您应该会看到黄点出现。它们没有立即出现的部分原因是 ARKit 仍在检测场景。

配置

现在,我们准备好进行平面检测了。如果您看一下您的 viewWillAppear()方法,您将看到以下两行代码。让我们花点时间了解它们的含义,因为它们与平面检测相关:

let configuration = ARWorldTrackingConfiguration()
sceneView.session.run(configuration)

在这里,创建了一个类的实例 ARWorldTrackingConfiguration。该类负责设备定位。之后,我们在当前 sceneView会话上运行配置。如果您有兴趣了解有关此内容的更多信息,可以访问Apple 的文档 。不过,就目前而言,您已准备好继续下一步。

现在,让我们在ARWorldTrackingConfiguration. 在创建配置的行下方,您需要插入以下行:

configuration.planeDetection = .horizontal

出色的!现在,启用了水平平面检测,但我们看不到它,因为它发生在引擎盖下,这意味着 iPhone 知道平面在哪里,但我们看不到它的想法。

平面检测

检查锚点

在开始可视化检测到的平面之前,我们需要找出检测到平面的时间和地点。这可以通过 Apple 提供给我们的委托方法轻松完成。

首先为 声明一个方法 ARSCNViewDelegate,如您所见, ViewController该类已经符合起始代码中的这个委托。将以下委托方法粘贴到您的 ViewController类中:

func渲染器(_渲染器:SCNSceneRenderer,didAdd节点:SCNnode,锚点:ARAnchor){
    // 你的代码在这里}

当新ARAnchors添加一个相应的节点时调用它,在这种情况下,这将是我们的水平面。

告诉代理对应于新 AR 锚点的 SceneKit 节点已添加到场景中。—— Apple

平面几何

但是,对于大多数应用程序,您希望用户能够知道您的应用程序认为它在哪里发现了水平面,因此我们将学习如何使用代理中提供的节点和锚点向用户实际显示这些平面我们之前调用的方法。

我们的第一个问题是:这ARAnchor真的是一架飞机,还是我们不想要的东西?我们可以使用类型转换和可选绑定来检查这一点。将这行代码放入您的委托方法中:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    // Your code goes here
}

您可能已经注意到 anchor参数的类型为 ARAnchor。如果我们想知道这个锚点是否是一个平面,我们可以尝试将它类型转换为一个 ARPlaneAnchor. 如果成功,我们就知道已检测到一架飞机。

在可选的绑定语句中,让我们添加代码以 SCNPlane使用我们从委托方法收到的锚点的尺寸创建一个。写出以下两行代码:

if let anchor = anchor as? ARPlaneAnchor {
    // Your code goes here          
}

这里的第一行创建了一个二维 SCNPlane,它的构造函数中有两个参数:宽度和高度。你会看到我们传入了 anchor.extent.xand  anchor.extent.z,正如它们的名字所暗示的,它代表检测到的平面的宽度和高度。您会注意到我们省略了锚点的 y 值,这是因为我们正在检测的平面是二维的,并且 x 和 z 轴穿过我们正在识别的平面。

下一行代码将半透明的红色色调应用于这些检测到的平面,您可以看穿这些平面,因为 alpha 值设置为 0.5。当然,你可以使用任何你想要的颜色或外观,只要你能看到它们。

创建节点

我们还没有完成;我们仍然需要创建节点以添加到我们的视图中。虽然我们的平面是一个二维对象,但我们仍然需要用 x、y 和 z 坐标在 3D 中表示它。这些坐标将相对于检测到的平面锚的父节点,而不是 sceneView. 输入以下代码行:

let plane = SCNPlane(width: CGFloat(anchor.extent.x), height: CGFloat(anchor.extent.z))
plane.materials.first?.diffuse.contents = UIColor.red.withAlphaComponent(0.5)

我们首先 SCNNode使用我们在上一步中创建的平面几何创建一个。这是通过将几何作为 SCNNode构造函数的参数传入来完成的。

接下来,我们使用 SCNVector3三维平面中的 x、y 和 z 坐标表示将平面节点直接定位在平面锚的中心。 

此外,在下一行中,您会看到 xour 的值 eulerAngles被设置为-π/2。该属性 eulerAngles表示 的俯仰、偏航和滚动 SCNNode。根据 Apple 的文档,x 值代表俯仰(或围绕 x 轴的旋转),我们希望我们的值与平面平齐(而不是直立)。

最后,将新创建的节点添加为检测到的平面节点的子节点,使其在同一位置对用户可见。

结论

很好!当您在 iPhone 上运行应用程序时,您现在应该能够看到水平面(当然还有特征点)。如果不这样做,请确保缓慢移动手机以使其扫描表面,并尝试增加我们之前设置的颜色的 alpha。这是我的样子:

ARKit增强现实:特征点和水平面检测  第7张



文章目录
  • 入门
    • Xcode 版本
    • 示例项目
      • 新项目
      • 游戏框架_
    • 准备测试
      • 连接 iPhone
      • 完成设置
  • 理论上
    • 特征点
    • 水平面
  • 在代码中
    • 入门代码
    • 特征点
      • 启用调试选项
      • 配置
    • 平面检测
      • 检查锚点
      • 平面几何
      • 创建节点
  • 结论