ARKit从入门到精通(5)--AR人脸识别应用

苹果公司近几年推出的最具创新性的发明之一是True Depth camera。作为开发者,深度相机为我们打开了一个充满可能性的世界,特别是在人脸交互领域。

在我们开始这个ARKit教程之前,简单介绍一下相机的不同部分。与大多数iPhone/iPad前置摄像头一样,True Depth camera配有麦克风、700万像素摄像头、环境光传感器、近距离传感器和扬声器。True Depth camera本身是增加了一个点投影仪,泛光照明,和红外相机。

点投射器在你的脸上投射出超过30,000个不可见的点来构建一个本地地图(你将在本教程的后面看到这一点)。红外摄像机读取圆点图案,捕获红外图像,然后将数据发送到A12/A13仿生芯片,以确认匹配。最后,漫射照明装置允许不可见的红外线识别你的脸,即使是在天黑的时候。这些功能可以让我们一起创造了一些神奇的体验,如Animojis和Memojis,当然还有炫酷的AR效果。

以下内容由公众号:AIRX社区(国内领先的AI、AR、VR技术学习与交流平台) 整理

效果预览

 

Step 1:新建项目

打开Xcode,选择AR模版创建,Content Technology选择SceneKit

打开Main.storyboard

在视图中添加一个UIView和一个UILabel。告诉用户他们正在做的面部表情。将一个UIView拖放到ARSCNView中,设置约束条件:宽度为240pt,高度为120pt;将左侧和底部约束设置为20pt。

将视图的alpha值设置为0.8,并将UILabel拖放到刚刚添加的视图中,约束设置为8,如下图所示:

 

将刚刚创建的组件写入代码,命名为faceLabel 和 labelView

 

Step 2:创建Face Mesh

稍微整理一下代码。因为我们选择了AR作为模板,所以有些代码我们不需要。将viewDidLoad函数更改为:


override func viewDidLoad() {
    super.viewDidLoad()

    // 1 
    labelView.layer.cornerRadius = 10

    sceneView.delegate = self
    sceneView.showsStatistics = true

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

本来这个模版代码是加载一个3D场景。然而,我们不需要这个场景,所以我们删除了它。然后删除art.scnassets文件夹。

然后向viewDidLoad方法添加了两段代码,这部分代码主要是检查设备是否支持ARFaceTrackingConfiguration。这是AR跟踪设置,因为我们需要使用它创建一个脸部网格。如果我们不检查设备是否支持这个,我们的应用程序将崩溃。

接下来,更改viewWillAppear函数中的一行。将常量配置更改为ARFaceTrackingConfiguration(),如下图所示:

添加ARSCNViewDelegate方法

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    let faceMesh = ARSCNFaceGeometry(device: sceneView.device!)
    let node = SCNNode(geometry: faceMesh)
    node.geometry?.firstMaterial?.fillMode = .lines
    return node
}

首先,创建了sceneView的face几何体,将其设置为常量faceMesh。然后,我们将这个几何图形分配给SCNNode。接着设置节点的材质。

对于face mesh,你可以使用两种材质——填充材质或线条材质。此次示例使用的是线条材质(fillMode = .lines),现在的代码应该是这样的:

现在运行程序,效果如下图:

 

Step 3:更新Face Mesh

运行后发现当你改变你的面部特征(眨眼、微笑、打哈欠等)时,mesh不会更新。这是因为我们需要在renderer(_nodeFor)方法下添加renderer(_didUpdate:):

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    if let faceAnchor = anchor as? ARFaceAnchor, let faceGeometry = node.geometry as? ARSCNFaceGeometry {
        faceGeometry.update(from: faceAnchor.geometry)
    }
}

将faceAnchor定义为它在sceneView中检测到的面。achor是人脸跟踪AR session中检测到的人脸姿态、拓扑结构和表情信息。我们还定义了常数面几何,这是一个拓扑的脸检测。使用这两个常量,我们每次都会更新faceGeometry。

再次运行代码。你会看到mesh随着你的面部特征改变而更新

 

Step 4:表情特征

在文件的顶部创建一个变量

var analysis = ""

在文件末尾创建以下函数:

func expression(anchor: ARFaceAnchor) {
    // 1
    let smileLeft = anchor.blendShapes[.mouthSmileLeft]
    let smileRight = anchor.blendShapes[.mouthSmileRight]
    let cheekPuff = anchor.blendShapes[.cheekPuff]
    let tongue = anchor.blendShapes[.tongueOut]
    self.analysis = ""
 
    // 2    
    if ((smileLeft?.decimalValue ?? 0.0) + (smileRight?.decimalValue ?? 0.0)) > 0.9 {
        self.analysis += "You are smiling. "
    }
 
    if cheekPuff?.decimalValue ?? 0.0 > 0.1 {
        self.analysis += "Your cheeks are puffed. "
    }
 
    if tongue?.decimalValue ?? 0.0 > 0.1 {
        self.analysis += "Don't stick your tongue out! "
    }
}

上面的函数以ARFaceAnchor作为参数。

blendShapes是一个根据特定面部特征的移动表示检测到的面部表情的字典。Apple提供了50多个系数来检测各种不同的面部特征。上面我们只使用了4种:mouthSmileLeft、mouthSmileRight、cheekPuff和tongueOut。

为了检测一个微笑,我们将嘴的左右两边的概率相加。发现0.9的微笑和0.1的脸颊和舌头效果最好。

将可能获取到的值添加到analysis字符串,然后更新renderer(_didUpdate:)方法:

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    if let faceAnchor = anchor as? ARFaceAnchor, let faceGeometry = node.geometry as? ARSCNFaceGeometry {
        faceGeometry.update(from: faceAnchor.geometry)
        expression(anchor: faceAnchor)
        
        DispatchQueue.main.async {
            self.faceLabel.text = self.analysis
        }
        
    }
}

运行测试

 

完整项目代码:

https://github.com/appcoda/Face-Mesh

参考文章:

https://www.appcoda.com/arkit-face-tracking/

ARKit与iPhone的True Depth camera的结合会有很多酷炫的、创新的、脑洞大开的应用场景,大家有什么好的idea可以在下面留言哦!!!

 

可以关注下公众号(AIRX社区),一个专注AI、AR、VR学习与交流的平台。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章