ARKit-基于Face的AR体验

原文链接: http://fighting300.com...

Apple昨晚发布了强大但是死贵无比的iPhoneX,惊呆了我们。然后只能默默去刷了下API,发现ARKit新添了基于Face的API。
之前的版本中前置摄像头是不支持AKKit模块的,幸而新发布的版本中添加了对Face识别的支持,然而新的API需要原前置深感摄像头(TrueDepth Camera)的支持,所以看来还得入手一台iPhone X呐。

iPhoneX

新增API

首先新增了ARFaceTrackingConfiguration,以用于追踪用户脸部的运动和表情,并在界面中渲染虚拟内容。此外你还可以设置lightEstimationEnabled为true,来启用脸部扫描并提供预估的定向/环境光。

其次还新增了ARFaceAnchor,这两个新API与之前的ARWorldTrackingConfiguration和ARPlaneAnchor类似,只是基于平面的检测改为了基于Face的检测,恶趣味下Apple会不会继续扩展他的检测API。。。当使用ARFaceTrackingConfiguration时,ARSession会检测用户面部并且用ARFaceAnchor保存面部信息,包括位置、方向、拓扑结构以及表情特征点。

ARFaceAnchor的transform属性描述了面部在世界坐标系中的所在位置和方向,该世界坐标系可以在ARSessionConfiguration的wordlAlignment中设置。可以使用该transform在ARScene检测到的面部上添加虚拟物体。坐标系如下图所示:

ARKit Face coordinate

该坐标系为右手坐标系,x轴只想观察者的右边(即face自己的左边),y轴指向上边(与face绑定),z轴指向了观察者。

ARFaceAnchor的blendShapes属性提供了当前面部表情的高级数据,通过一系列表示面部特征的系数来描述面部表情。你可以使用这些系数跟随用户的面部表情来做2D/3D动画,

开始面部跟踪

和ARKit的其他用法一样,面部追踪需要ARSessionConfiguration并运行一个ARSession来渲染相机屏幕,这部分可以参考之前分享的文章,流程一致,只是这部分需要使用到新加的API。
如前面所说,面部检测只支持配置了原前置深感摄像头(TrueDepth Camera)的iPhone,所以首先需要判断当前设备是否支持ARFaceTrackingConfiguration。

    // 如果设备支持的判断通过 然后配置Session Configuration
    guard ARFaceTrackingConfiguration.isSupported else { return }
    let configuration = ARFaceTrackingConfiguration()
    configuration.isLightEstimationEnabled = true
    session.run(configuration, options: [.resetTracking, .removeExistingAnchors])

跟踪脸部位置和方向

当面部跟踪启用后,ARKit会自动的添加ARFaceAnchor到ARSession中,包括其位置和方向。

注意ARKit目前只能追踪单个用户的面部,如果多个用户同时出现在镜头中,则取最大或者最清晰的可识别面部

你可以在代理方法renderer:didAddNode:forAnchor:(ARSCNViewDelegate协议)中给一个face锚点添加相应3D内容。他会跟随用户的面部动作做相应的位置和方向调整。

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    let device = sceneView.device!
    let maskGeometry = ARSCNFaceGeometry(device: device)!
    let content = SCNNode(geometry:maskGeometry)
    node.addChildNode(content)
}
使用Face Geometry来模拟用户面部

ARKit提供了粗粒度的3D网状几何体,来匹配用户的面部大小、形态、拓扑结构以及当前面部表情,当然ARKit还提供了ARSCNFaceGeometry类来快捷的初始化该网格。你可以在用户的皮肤上通过给网状模型添加材质来绘制虚拟的刺青或者面具等。

let device = sceneView.device!
let maskGeometry = ARSCNFaceGeometry(device: device)!

为了让屏幕中面部模型匹配用户的脸部,甚至跟随用户的眨眼、说话或者更多的表情动作,需要在代理方法中更新该面部模型的数据。

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

    let faceGeometry = content.geometry as! ARSCNFaceGeometry
    faceGeometry.update(from: anchor.geometry)
}

在面部呈现3D内容

ARKit提供的面部网格的另一个用途是在场景中创建遮挡几何体。遮挡几何体是不会呈现任何可见内容(允许相机图像显示)的3D模型,但会阻碍相机对场景中其他虚拟内容的视图。这种技术创造出真实面对与虚拟对象交互的错觉,即使脸部是2D摄像机图像,虚拟内容是渲染的3D对象。例如,如果您将遮挡几何图形和虚拟眼镜放置在用户的脸部上,则脸部可能会眼镜框架遮挡。
要创建面部的遮挡几何,首先创建一个ARSCNFaceGeometry对象,如前面的例子所示。但是,不要使用可见的外观来配置该对象的SceneKit材质,而是在渲染期间将材质设置为渲染深度而不是颜色:

    let geometry = SCNGeometry()
    geometry.firstMaterial!.colorBufferWriteMask = []
    occlusionNode = SCNNode(geometry: geometry)
    occlusionNode.renderingOrder = -1
让你的形象动起来

要获取当前用户的面部表情,需要在代理方法renderer:didUpdateNode:forAnchor:中从ARFaceAnchor的blendShapes中读取数据 。

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    blendShapes = faceAnchor.blendShapes
}

然后,查看该字典中的键值对以计算模型的动画参数。该字典中有52个独特的ARBlendShapeLocation系数。你可以使用尽可能少的或很多的必要条件来创建想要的艺术效果。在此示例中,RobotHead类执行此计算,映射ARBlendShapeLocationEyeBlinkLeft和ARBlendShapeLocationEyeBlinkRight参数到机器人眼睛的scale参数,用ARBlendShapeLocationJawOpen参数以计算机器人上颌所在的位置。

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
    }
}

先简单介绍到这儿,真正要看到效果还得公司的土豪们入手iPhone X之后啦,不过基本用法很简单,维持了ARKit易用的特性。

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

推荐阅读更多精彩内容