26-[译]用 ARKit 2 创建一个博物馆 App

说明

ARKit系列文章目录

资料下载

你是否曾经站在博物馆展台前面,不满足于艺术品或手工艺品前面的小卡片所展示的内容,想要知道更多?要是有一个这样的 app 该有多好。现在,你可以用 ARKit 2 来自己制作一个带有图片/物体检测与追踪的 app。

为了让体验更加有趣,ARKit 允许 app 添加动态的虚拟内容到真实世界物体上。它允许我们为真实世界的地方和物品创建一个交互式的引导 app。是博物馆,画廊,游乐场和学校等地的完美配套 app。它可以让任何地方“活起来”,提供一个动态的或定制的体验。

在本教程中,你将构建一个TriassicLoupe(三叠纪放大镜),一个用在自然历史博物馆里恐龙展览的配套 app。这个概念来自珠宝商的放大镜;这个 app 会在用户指向展品的时候显示出隐藏的细节。如果你周围没有任何恐龙,请不要担心 - 你可以使用普通的家用物品作为占位。

最终应用程序在信息图像上显示一段简短的动画。它还会在复制品旁边显示有关恐龙的信息。该 app 还将为该物体添加一些可怕的声音效果。

该应用程序将 ARKit 与 SceneKit(iOS的3D图形框架)结合使用。你会看到 ARKit 使用 SceneKit 完成所有繁重的工作。对于图片追踪和物体追踪,您将只使用非常基本的 SceneKit 功能,本教程中您从中学到的所有内容都是通用的。了解有关 SceneKit 的更多信息将使您能够构建更丰富的应用程序,但这超出了本教程的范围。

开始

ARKit 依赖于A9或更高版本处理器的内置功能。它使用了机器学习,后置摄像头,以及视频和图像处理。这意味着 ARKit 应用程序需要在iPhone 6s或更新版本上运行,并且它们无法在模拟器中运行。

使用超长的Lightning线缆或者设置设备以通过 Wi-Fi 连接到Xcode方便调试。 ARKit 需要移动一点才能获得一张好的世界地图。世界地图是 ARKit 对物理空间的意识。它是一系列特征点,尺寸,方向和锚点。

稍后你会需要扫描一些图像。显示器上显示的图像应该也适用,但如果您在扫描图像时遇到问题,则可能需要打印图像以获得更好的效果。

要开始使用,请使用本教程顶部或底部的“下载材料”按钮下载入门项目。 .zip文件包含一个帮助项目,包含将在教程中使用的素材,以及初始项目和最终项目。

打开入门项目。应用程序本身非常简单,只需一个ViewController即可添加所有逻辑。有一个辅助结构体,DinosaurFacts,其中包含一些关于一些恐龙的基本信息。

如果你构建并运行,你会看到一个黑屏,因为你尚未连接ARKit会话。

创建图片检测

首先要做的是创建图片检测。图片检测可能是ARKit最简单的功能。要创建图片检测器,您所要做的就是提供带有图像副本的图像跟踪会话。这些提供的图像称为参考图片

添加参考图片

TriassicLoupe 使用含有信息标志的艺术作品作为参考图像。当用户将应用程序指向其中一个标志时,该应用程序将添加恐龙图像叠加层。

与其他应用程序图像一样,增强现实(AR)参考图像存在于素材目录asset catalog中。参考图像有点特殊,因为它们需要专门为ARKit分组。

打开Assets.xcassets 点击下面的 + 按钮。

从弹出菜单中,选择New AR Resource Group以创建新组。将其重命名为AR Images,因为该组将保留参考图像。

在Finder中,从下载的材料中打开Dinosaur Images文件夹。将每个图像文件逐个拖动到Xcode中的AR Images中。完成后,您应该有三个带黄色警告三角形的图像。

如果参考图像作为参考质量不好,Xcode会发出警告。这可能是因为它们太小或者没有足够的特征或对比度。具有大量空白空间,颜色太少或缺乏独特形状的图像是难以检测的。

在这种情况下,警告是“不支持的配置”警告。这是因为参考图像必须具有非零的正宽度。 AR参考图像需要您指定其实际尺寸!

在资产库中选择stegosaurus(剑龙)图像。然后选择Attributes inspector

将单位更改为英寸。接下来,输入宽度4.15。当你这样做时,根据纵横比,高度将自动变为2.5711!这些数字就是您桥接虚拟世界和真实世界的地方。

这两张图片,配置值如下:

  • trex:Inches, width: 6.3333, height: 4.75
  • triceratops: Inches, width: 5, height: 2.8125

当你输入尺寸后,警告就消失了。

这些图像对应于所包含的Dinosaurs.key Keynote文件的幻灯片。每张幻灯片代表一个信息标语牌,旁边是博物馆展示。在美国信纸大小的纸张上打印时,这个尺寸就是物理图像尺寸。

注意:某些图像实际上是在Keynote幻灯片中裁剪出来的。只要保持大小和宽高比相同,ARKit 完全能够识别并匹配。

这些图像都是不同的风格,以展示ARKit系列的一小部分。这里有两件事情:1。图像中有足够的形状和对比度。 2.真实世界中的图片平坦,光线充足,不反光。

书页上,壁纸上或在镜相打印出的图片是难以识别的。照片,绘画或插图可以很好地识别出来。如果参考图片不够友好,Xcode会发出警告。这样就无需在运行时猜测!

现在,是时候继续编写代码来寻找这些图像了。

添加图片追踪

ViewController.swift中,在注释下添加一个新变量:// Add configuration variables here:

private var imageConfiguration: ARImageTrackingConfiguration?

这将设置一个变量,以便在创建后保留图像跟踪配置。
现在,查找setupImageDetection()并添加以下代码:

imageConfiguration = ARImageTrackingConfiguration()

这会将该实例变量设置为新的ARImageTrackingConfiguration。顾名思义,此类是一个ARKit配置,用于检测和跟踪图像。
在该行下面,添加以下内容:

guard let referenceImages = ARReferenceImage.referenceImages(
  inGroupNamed: "AR Images", bundle: nil) else {
      fatalError("Missing expected asset catalog resources.")
  }
imageConfiguration?.trackingImages = referenceImages

这将使用您刚刚在素材目录中创建的AR Images组中的图像,创建一个ARReferenceImage集。然后,将它们作为要跟踪的图像列表添加到配置中。

注意:图像检测最适用于资源组中不超过25个图片。如果您的博物馆有超过25个展品,您可以创建多个资源组,并在用户在建筑物周围移动时切换它们。

要使用配置,请将以下内容添加到viewWillAppear(_ :)

if let configuration = imageConfiguration {
  sceneView.session.run(configuration)
}

这将使用imageConfiguration启动ARKit会话。一旦运行,ARKit将处理相机数据以检测参考图片。

要确保全部启动,请将以下内容添加到viewDidLoad()的底部:

setupImageDetection()

最后,为了平衡会话运行,在viewWillDisappear(_ :)添加:

sceneView.session.pause()

当视图消失时,这会暂停会话。ARKit会话会因为相机调用,视频处理和渲染,而把电池耗尽。在我们的单视图应用程序中,这不是什么大问题,但是尊重用户的设备并在没有显示时暂停会话总是一个好主意。

处理检测到的图片

一旦检测到图像,AR会话就会将ARImageAnchor添加到其世界地图中。当发生这种情况时,您将在渲染器处获得回调renderer(_:didAdd:for:)

ViewController.swift的底部找到此函数并添加以下代码:

DispatchQueue.main.async { self.instructionLabel.isHidden = true }
if let imageAnchor = anchor as? ARImageAnchor {
  handleFoundImage(imageAnchor, node)
}

此代码检查是否为图像锚点添加了新添加的节点。这意味着在现实世界中检测到图像。
handleFoundImage(_:_:)函数替换为:

let name = imageAnchor.referenceImage.name!
print("you found a \(name) image")

let size = imageAnchor.referenceImage.physicalSize
if let videoNode = makeDinosaurVideo(size: size) {
  node.addChildNode(videoNode)
  node.opacity = 1
}

这将从锚点的参考图片中获取图像的名称和大小。您在素材目录中指定了这些值。使用该尺寸,调用辅助函数以在检测到的图像之上创建视频播放器。

要创建视频节点,请将makeDinosaurVideo(size :)的内容替换为:

// 1
guard let videoURL = Bundle.main.url(forResource: "dinosaur",
                                     withExtension: "mp4") else {
  return nil
}

// 2
let avPlayerItem = AVPlayerItem(url: videoURL)
let avPlayer = AVPlayer(playerItem: avPlayerItem)
avPlayer.play()

// 3
NotificationCenter.default.addObserver(
  forName: .AVPlayerItemDidPlayToEndTime,
  object: nil,
  queue: nil) { notification in
    avPlayer.seek(to: .zero)
    avPlayer.play()
}

// 4
let avMaterial = SCNMaterial()
avMaterial.diffuse.contents = avPlayer

// 5
let videoPlane = SCNPlane(width: size.width, height: size.height)
videoPlane.materials = [avMaterial]

// 6
let videoNode = SCNNode(geometry: videoPlane)
videoNode.eulerAngles.x = -.pi / 2
return videoNode

此功能创建一个视频播放器并将其放入一个大小适合图像的SceneKit节点。它通过以下方式实现:

  1. 从资源包中抓取视频。这有一个适用于所有恐龙的简单动画。但您可以根据图像锚点的名称为每种恐龙类型提供不同的视频。
  2. 为该视频创建和启动AVPlayer
  3. AVPlayer 实例并不会自动循环播放。此通知块通过侦听播放器完成来循环视频。然后, 它会返回开头并重新开始播放。
  4. SceneKit 不使用UIViews, 而是使用节点来渲染场景。不能直接添加AVPlayer。相反, 视频播放器可以用作节点的纹理或 "材质"。这将把视频帧映射到关联的节点。
  5. 检测到的图像是平坦正方形 (即平面), 因此覆盖的节点是与检测到的图像大小相同的SCNPlane。这架飞机被装饰成视频作为其纹理。
  6. 创建出的实际节点将成为场景的一部分。这就需要在 x 轴上进行翻转, 以便它正确显示给用户。

尝试一下

最后的最后, 是时候构建并运行了!但是, 首先, 打印幻灯片Dinosaurs.key中至少一张恐龙。将其放置在光线充足的区域中 (垂直或水平).

构建并运行该应用程序。接受相机权限并显示视频后, 请将其指向打印页面。它可能需要两只稳定的手来检测图像。完成后, 您将在控制台中看到一个注释, 并在屏幕上显示一个动画叠加。

不幸的是, 如果会话启动, 但它没有检测到图像, 那也没有错误消息。大多数情况下, ARKit 不保证能找到该图像, 因此它不被视为错误。只要素材目录中没有关于图像的警告, 就应该最终检测到该图像。

添加物体检测和追踪

现在, 您已经看到了图像检测如何工作。接下来, 您将向应用添加物体检测。从开发人员的角度来看, 物体检测的工作原理几乎相同。主要区别在于它将寻找三维物体而不是平面图像。设置物体检测稍微复杂一些。参考物体的创建也比较复杂。

回顾一下, 以下是使用图像和物体检测的步骤:

  1. 创建参考对象。
  2. 将参考对象放入素材集的AR Resources组中。
  3. 创建一个 ARKit 会话。
  4. 加载参考图片/物体,并设置会话来检测他们。
  5. 启动 session.
  6. 等待锚点被添加时的回调。
  7. 添加交互节点到场景中,或采取其他措施。

物体检测

另一个有用的 ARKit 函数是物体检测和跟踪。TriassicLoupe 检测已知物体并标记它们。在现实中, 这些将是恐龙在一个透视或恐龙骨架。对于本教程, 您将使用手头上的任何东西。

选择参考物体

检测物体所需的第一件事是参考物体。通过图像检测, 您可以创建、扫描或拍摄图像。但是, 对于3D 对象, 参考物体很难构造.

ARKit 提供了自己的 API, 用于使用 iPhone 扫描它们来创建参考物体。TriassicLoupe 不直接使用此项, 因为它只能检测到一组已知的对象。您可以使用 Apple 提供的实用程序提前扫描它们。

如果可以, 您应该下载 Apple 的对象扫描程序项目Object Scanner project。它也包括在项目下载ScanningAndDetecting3DObjects文件夹中, 为您的方便。请注意, 在您阅读此内容时, 包含的项目可能已过期。

此应用程序扫描对象, 并允许您导出. arobject文件。然后, 您可以将此文件作为素材导入到 Xcode 项目中。成功的扫描需要有合适的对象和良好的照明。适当的对象是:

  • 实体不可变形。
top Created with Sketch.