ARKit框架详细解析(五)—— 创建基于面部的AR体验

版本记录

版本号 时间
V1.0 2017.09.27

前言

苹果最近新出的一个API就是ARKit,是在2017年6月6日,苹果发布iOS11系统所新增框架,它能够帮助我们以最简单快捷的方式实现AR技术功能。接下来几篇我们就详细的对ARKit框架进行详细的解析。AR相关代码已经上传到Github - 刀客传奇,感兴趣的可以看上面几篇。
1. ARKit框架详细解析(一)—— 基本概览
2. ARKit框架详细解析(二)—— 关于增强现实和ARKit
3. ARKit框架详细解析(三)—— 开启你的第一个AR体验之旅
4. ARKit框架详细解析(四)—— 处理增强现实中的3D交互和UI控件

创建基于面部的AR体验

放置和动画3D用户脸部的内容,并匹配面部表情(在具有兼容的前置摄像头的设备上)。


概要

此示例应用程序提供了一个简单的界面,允许您使用兼容设备上的前置摄像头在四个增强现实(AR)可视化之间进行选择(请iOS Device Compatibility Reference)。

  • 单独的相机视图,没有任何AR内容。
  • ARKit提供的面部网格,可以自动估计真实的定向照明环境。
  • 虚拟3D内容似乎附加到用户的真实面孔(并被部分遮蔽)。
  • 一个简单的机器人角色,其表情符合用户的动画。

使用示例应用程序中的“+”按钮在这些模式之间切换,如下所示。


Start a Face Tracking Session in a SceneKit View - 在SceneKit视图中启动面部跟踪会话

像ARKit的其他用途一样,脸部跟踪需要配置和运行会话(ARSession对象),并将视频图像与虚拟内容一起渲染。 有关会话和视图设置的更详细说明,请参阅About Augmented Reality and ARKitBuilding Your First AR Experience。 此示例使用SceneKit显示AR体验,但也可以使用SpriteKit或使用Metal构建您自己的渲染器(请参阅ARSKViewDisplaying an AR Experience with Metal)。

面部跟踪与用于配置会话的类中的ARKit的其他用途不同。 要启用脸部跟踪,请创建一个实例,配置其属性,并将其传递给与视图关联的AR会话的方法,如下所示。

guard ARFaceTrackingConfiguration.isSupported else { return }
let configuration = ARFaceTrackingConfiguration()
configuration.isLightEstimationEnabled = true
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])

在提供需要面部跟踪AR会话的用户功能之前,请先检查.属性来确定当前设备是否支持ARKit的脸部跟踪。


Track the Position and Orientation of a Face - 跟踪面部的位置和方向

当脸部跟踪处于活动状态时,ARKit会自动将对象添加到正在运行的AR会话中,其中包含有关用户脸部的信息,包括其位置和方向。

注意:ARKit会检测并提供有关用户脸部信息的信息。 如果摄像机图像中存在多个面部,则ARKit会选择最大或最清晰可识别的脸部。

在基于SceneKit的AR体验中,您可以在方法(从协议)中添加与面锚相对应的3D内容。 ARKit为锚点添加了一个SceneKit节点,并更新了每一帧上节点的位置和方向,因此您添加到该节点的任何SceneKit内容都会自动跟随用户脸部的位置和方向。

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    // Hold onto the `faceNode` so that the session does not need to be restarted when switching masks.
    faceNode = node
    serialQueue.async {
        self.setupFaceNodeContent()
    }
}

在此示例中,该方法调用setupFaceNodeContent方法将SceneKit内容添加到faceNode。 例如,如果您更改示例代码中的showsCoordinateOrigin变量,则应用程序将x / y / z轴的可视化添加到该节点,指示面部锚点坐标系的起点。


Use Face Geometry to Model the User’s Face - 使用面几何来建模用户脸部

ARKit提供与用户脸部的大小,形状,拓扑和当前面部表情相匹配的粗略3D网格几何。 ARKit还提供了该类,提供了一种在SceneKit中可视化此网格的简单方法。

您的AR体验可以使用此网格放置或绘制似乎附加到脸部的内容。 例如,通过将半透明纹理应用于此几何体,您可以将虚拟纹身或化妆画到用户的皮肤上。

要创建一个SceneKit面几何,使用SceneKit视图用于呈现的Metal设备初始化一个对象:

// This relies on the earlier check of `ARFaceTrackingConfiguration.isSupported`.
let device = sceneView.device!
let maskGeometry = ARSCNFaceGeometry(device: device)!

示例代码的setupFaceNodeContent方法(如上所述)将包含面几何的节点添加到场景中。 通过使该节点成为由脸部锚点提供的节点的子节点,脸部模型自动跟踪用户脸部的位置和方向。

为了使屏幕上的脸部模型符合用户脸部的形状,即使用户眨眼,说话并进行各种面部表情,您需要在委托回调中检索更新的脸部网格。

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    guard let faceAnchor = anchor as? ARFaceAnchor else { return }
    
    virtualFaceNode?.update(withFaceAnchor: faceAnchor)
}

然后,通过将新的面网格传递给其方法来更新场景中的对象进行匹配:

func update(withFaceAnchor anchor: ARFaceAnchor) {
    let faceGeometry = geometry as! ARSCNFaceGeometry
    faceGeometry.update(from: anchor.geometry)
}

Place 3D Content on the User’s Face - 将3D内容放在用户脸上

ARKit提供的面部网格的另一个用途是在场景中创建遮挡几何。 遮挡几何是不会呈现任何可见内容(允许相机图像显示)的3D模型,但会阻碍相机对场景中其他虚拟内容的视图。

这种技术创造出真实面对与虚拟对象交互的错觉,即使脸部是2D摄像机图像,虚拟内容是渲染的3D对象。 例如,如果您将遮挡几何图形和虚拟眼镜放置在用户的脸部上,则脸部可能会遮挡眼镜框架。

要创建面部的遮挡几何,请先创建一个对象,如上例所示。 但是,不要使用可见的外观来配置该对象的SceneKit材质,而是在渲染期间将材质设置为渲染深度而不是颜色:

geometry.firstMaterial!.colorBufferWriteMask = []
occlusionNode = SCNNode(geometry: geometry)
occlusionNode.renderingOrder = -1

因为材料渲染深度,所以SceneKit渲染的其他对象正确地出现在它的前面或后面。 但是由于材质不会呈现颜色,相机图像会出现在其位置。 示例应用程序将此技术与位于用户眼睛前方的SceneKit对象相结合,创建一个效果,其中对象被用户的鼻子实际遮蔽。


Animate a Character with Blend Shapes - 用混合形状动画化一个人物

除了上述示例中所示的面部网格之外,ARKit还提供了一种以词典形式的用户面部表情的更抽象的模型。 您可以使用该字典中的命名系数值来控制自己的2D或3D资产的动画参数,创建遵循用户真实面部动作和表达的角色(如头像或木偶)。

作为混合形状动画的基本演示,此示例包含使用SceneKit原始形状创建的机器人角色头部的简单模型。 (请参阅源代码中的robotHead.scn文件。)

要获取用户当前的面部表情,请从代理回调中的面部锚点中读取字典:

func update(withFaceAnchor faceAnchor: ARFaceAnchor) {
    blendShapes = faceAnchor.blendShapes
}

然后,检查该字典中的键值对以计算模型的动画参数。 有52个独特系数。 您的应用程序可以使用尽可能少的或很多的必要条件来创建您想要的艺术效果。 在该示例中,RobotHead类执行此计算,将参数映射到机器人眼睛因子的一个轴,以及偏移机器人下颚位置的参数。

var blendShapes: [ARFaceAnchor.BlendShapeLocation: Any] = [:] {
    didSet {
        guard let eyeBlinkLeft = blendShapes[.eyeBlinkLeft] as? Float,
            let eyeBlinkRight = blendShapes[.eyeBlinkRight] as? Float,
            let jawOpen = blendShapes[.jawOpen] as? Float
            else { return }
        eyeLeftNode.scale.z = 1 - eyeBlinkLeft
        eyeRightNode.scale.z = 1 - eyeBlinkRight
        jawNode.position.y = originalJawY - jawHeight * jawOpen
    }
}

后记

未完,待续~~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容