22-[译]AR面部追踪教程:开始

ARKit文章目录

译者注:本文是Raywenderlich上《AR Face Tracking Tutorial for iOS: Getting Started》一文的翻译.

在本文中,你将学习如何通过TrueDepth相机来使用AR Face Tracking跟踪你的面部,在你的被跟踪面部覆盖上表情符号,并根据你制作的面部表情来操作表情符号。

资料下载
版本:Swift 4.2, iOS 12, Xcode 10

想象一下。 你刚刚吃过最神奇的韩国BBQ,现在是时候采取自拍来纪念这个场合了。 你拿出你的iPhone,做出最好的鬼脸,然后拍这一餐中自认为最棒的自拍照。 这张照片很好用 -- 但它缺少一些东西。 如果你可以在你的眼睛上放一个表情符号,显示你有多喜欢这顿BBQ就好了。 然而现在,没有一个应用程序可以做类似的事情。要是有一个使用AR Face Tracking技术的app就好了。

好消息! 你可以编写一个应用程序来做到这一点!
在本文中,你将学习如何:

  • 通过TrueDepth相机使用AR Face Tracking跟踪你的脸部。
  • 在被追踪到的的脸上放上emoji表情。
  • 根据你的面部表情操纵emoji。

你准备好了吗? 然后闭上嘴,打开Xcode,准备开始吧!

准备开始

在本文中,你需要一台带有前置TrueDepth相机的iPhone。 在写本文时,只有iPhone X满足条件,但谁知道未来会有什么新型号?

你可能已经下载了本教程开始提供的材料,却发现里面没有初始项目文件.这并不是一个失误.

你将从头开始写完这个app--Emoji Bling.

启动Xcode创建一个Single View App新项目,并将其命名为Emoji Bling

你应该做的第一件事是为默认的ViewController起个好名字。 在左侧的项目导航器中选择ViewController.swift

在标准编辑器中显示的代码中,右键单击类的名称ViewController,然后从弹出的上下文菜单中选择Refactor ▸ Rename

将类的名称更改为EmojiBlingViewController并按回车键或单击蓝色Rename按钮。

注意:有时重构进程会忘记重命名ViewController.swift文件。 如果发生这种情况,只需在Finder中手动执行此操作,然后再将该文件添加到项目中。

由于你已经在使用EmojiBlingViewController.swift,请继续将以下导入添加到头部:

import ARKit

毕竟,你是制作增强现实应用程序的,对吧?

接下来,在Main.storyboard中,选中Emoji Bling View Controller中的顶级View,将类更改为ARSCNView

ARSCNView是一个使用SceneKit内容显示增强现实体验的特殊视图。 它可以显示摄像头数据流和显示SCNNode节点。

将顶级视图更改为ARSCNView后,你需要为EmojiBlingViewController类中的视图创建IBOutlet

要执行此操作,请通过单击带有联锁环的按钮调出辅助编辑器。


这应该会自动在辅助编辑器中显示EmojiBlingViewController.swift相关的内容。 如果没有,你可以在项目导航器中按住Option键并单击它来显示。

现在,按住Control键从storyboard中的ARSCNView拖动到EmojiBlingViewController.swift中的EmojiBlingViewController类定义下方,并命名outlet sceneView

在构建和运行之前,需要一些代码来显示摄像头数据流并开始跟踪你的面部。

EmojiBlingViewController.swift中,将以下函数添加到EmojiBlingViewController类:

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(animated)

  // 1
  let configuration = ARFaceTrackingConfiguration()

  // 2
  sceneView.session.run(configuration)
}

override func viewWillDisappear(_ animated: Bool) {
  super.viewWillDisappear(animated)

  // 1
  sceneView.session.pause()
}

在视图出现之前,你:

  1. 创建配置以跟踪面部。
  2. 使用ARSCNView的内置ARSession属性运行面部跟踪配置。

在视图消失之前,你需要确保:

  1. 暂停AR session。

到目前为止,这段代码存在一个很小的问题。 ARFaceTrackingConfiguration仅适用于带有前置TrueDepth摄像头的手机。 在做任何事之前,你需要确保检查这一点。

在同一个文件中,将以下内容添加到viewDidLoad()函数的末尾,该函数应该已经存在:

guard ARFaceTrackingConfiguration.isSupported else {
  fatalError("Face tracking is not supported on this device")
}

有了这个,就检查并确保设备支持面部跟踪(即,有一个正面的TrueDepth摄像头),否则就停止。 这不是一个优雅的方式来处理这个,但由于这个应用程序进行面部跟踪,其他任何东西都是毫无意义的!

在运行应用程序之前,还需要指定在Info.plist中需要使用相机的权限的原因。

在Project导航器中选择Info.plist,然后添加一个带有Privacy - Camera Usage Description键的条目。 它应该默认为String类型。值为,EmojiBling needs access to your camera in order to track your face

终于现在是时候Build和运行。

当你这样做时,你应该看到你美丽,微笑的脸直视着你。

好了,鬼脸做够了.你还有很多工作要做!

注意:此项目的某些构建步骤可能需要很长时间。 虽然Xcode似乎已经去喝咖啡了,但它可能没有,你只需要耐心等待它。

Face Anchors and Geometries - 面部锚点和几何体

你已经看过ARFaceTrackingConfiguration,它用于配置设备以使用TrueDepth摄像头跟踪你的面部。 很酷吧!。

但是你还需要了解面部追踪的其他信息吗?

你很快就会使用的三个非常重要的类是ARFaceAnchorARFaceGeometryARSCNFaceGeometry

ARFaceAnchor继承自ARAnchor。 如果你之前已经使用ARKit做过任何事情,那么你就会知道ARAnchors是如此强大和简单的原因。 它们是ARKit在现实世界中追踪到的位置,当你移动手机时它们不会移动。ARFaceAnchors还包括有关面部的信息,例如拓扑关系和表情。

ARFaceGeometry正如听起来一样。 它是包含verticestextureCoordinates的面部的3D描述。

ARSCNFaceGeometry使用来自ARFaceGeometry的数据来创建SCNGeometry,它可用于创建SceneKit节点 - 基本上就是你在屏幕上看到的内容。

好吧,够了。 是时候使用其中一些类了。 回到编码!

Adding a Mesh Mask - 添加网格蒙版

从表面上看,你似乎只打开了前置摄像头。 但是,你没看到的是你的iPhone已经在追踪你的脸了。

看到iPhone正在追踪的内容不是很好吗? 多么巧合,因为这正是你接下来要做的事情!

EmojiBlingViewController类定义的右大括号后面添加以下代码:

// 1
extension EmojiBlingViewController: ARSCNViewDelegate {
  // 2
  func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {

    // 3
    guard let device = sceneView.device else {
      return nil
    }

    // 4
    let faceGeometry = ARSCNFaceGeometry(device: device)

    // 5
    let node = SCNNode(geometry: faceGeometry)

    // 6
    node.geometry?.firstMaterial?.fillMode = .lines

    // 7
    return node
  }
}

在这段代码中你:

  1. 声明EmojiBlingViewController实现了ARSCNViewDelegate协议。
  2. 从协议中定义renderer(_:nodeFor:)方法。
  3. 确保用于渲染的Metal设备不是nil。
  4. 创建要由Metal设备渲染的面部几何体。
  5. 基于面部几何体创建SceneKit节点。
  6. 将节点材质的填充模式设置为线条。
  7. 返回节点。

注意:ARSCNFaceGeometry仅在使用Metal渲染的SceneKit视图中可用,这就是你需要在初始化期间传入Metal设备的原因。 此外,此代码仅在你选择真实硬件时才会编译;如果你选中模拟器,它将无法编译。

在运行之前,你需要将此类设置为ARSCNView的代理。

viewDidLoad()函数的末尾,添加:

sceneView.delegate = self

好的,到了每个人最喜欢的一步了。 Build并运行该应用程序!

Updating the Mesh Mask - 更新网格蒙版

你是否注意到网格蒙版有点......静态? 当然,当你移动头部时,它会跟踪你的面部位置并随之移动,但是当你眨眼或张开嘴时会发生什么? 没有。

多么令人失望。

幸运的是,这很容易解决。 你只需要添加另一个ARSCNViewDelegate方法!

ARSCNViewDelegate类扩展的末尾,添加以下方法:

// 1
func renderer(
  _ renderer: SCNSceneRenderer, 
  didUpdate node: SCNNode, 
  for anchor: ARAnchor) {

  // 2
  guard let faceAnchor = anchor as? ARFaceAnchor,
    let faceGeometry = node.geometry as? ARSCNFaceGeometry else {
      return
  }

  // 3
  faceGeometry.update(from: faceAnchor.geometry)
}

在这里,你:

  1. 定义renderer(_:didUpdate:for:)协议方法的didUpdate版本。
    2)确保正在更新的锚点是ARFaceAnchor,并且节点的几何体是ARSCNFaceGeometry
    3)使用ARFaceAnchorARFaceGeometry更新ARSCNFaceGeometry

现在,当你Build并运行时,你应该看到网格蒙版表单并更改以匹配你的面部表情。

Emoji Bling

如果你还没做完,直接去本文开头或末尾下载本教程的资料代码.

在里面,你会找到一个名为SuperUsefulCode的文件夹,里面有一些Swift文件。 将它们拖到EmojiBlingViewController.swift下面的项目中。 如果需要,请选择Copy items if needed, Create groups,并确保选中Emoji Bling为目标

StringExtension.swift包含String的扩展,可以将String转换为UIImage

EmojiNode.swift包含一个名为EmojiNodeSCNNode子类,它可以呈现一个String。 它需要一个字符串数组,并可以根据需要循环它们。

你可以随意浏览这两个文件,但深入了解此代码的工作方式超出了本文章的范围。

是时候来增强一下你的鼻子了。没有任何错误.你立即成为了好看的人.:]

在你的EmojiBlingViewController类的顶部,定义下面的常数:

let noseOptions = ["👃", "🐽", "💧", " "]

数组末尾的空白区域使你可以选择清除鼻子。 如果你愿意,可以随意选择其他鼻子选项。

接下来,将以下辅助函数添加到你的EmojiBlingViewController类:

func updateFeatures(for node: SCNNode, using anchor: ARFaceAnchor) {
  // 1
  let child = node.childNode(withName: "nose", recursively: false) as? EmojiNode

  // 2
  let vertices = [anchor.geometry.vertices[9]]

  // 3
  child?.updatePosition(for: vertices)
}

在这里,你:

top Created with Sketch.