【Swift】【ARKit】ARkitのFaceTrackingで楽○カードマンになる!
2018/09/01
はじめに
前回の記事「【Swift】1週間、iOSアプリを作ってみた」でARKitを触ってみて色々できて楽しいなと感じていた時に、iPhone XがあるのにFace Trackingを触ってみないのもあれだなーと感じてAppleの公式
サンプルを実際に動かしてみた。動かしてみると、三種類のことができて能面のようなマスクをつけれたり目の位置にARと書かれた文字のオブジェクトを置いたりロボットの頭になったりできた。
ARの文字を目元につけられるサンプルを見て、楽○カードマンも簡単にできると感じたのでやって見た(笑)
ソースコード
すべてViewControllerに記述しているので綺麗なコードではありません。
Appleのサンプルを簡単に使いたいところをまとめただけなのでサンプルを参考にしてください。
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSessionDelegate, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
private var faceNode = SCNNode()
private var virtualFaceNode = SCNNode()
private let serialQueue = DispatchQueue(label: "com.example.apple-samplecode.ARKitFaceExample.serialSceneKitQueue")
var session: ARSession {
return sceneView.session
}
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
sceneView.session.delegate = self
sceneView.automaticallyUpdatesLighting = true
let device = sceneView.device!
let glassesGeometry = ARSCNFaceGeometry(device: device)!
glassesGeometry.firstMaterial!.colorBufferWriteMask = []
virtualFaceNode.geometry = glassesGeometry
let url = Bundle.main.url(forResource: "rakutenCard", withExtension: "scn", subdirectory: "Models.scnassets")!
let node = SCNReferenceNode(url:url)!
node.load()
let faceOverlayContent = node
virtualFaceNode.addChildNode(faceOverlayContent)
resetTracking()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIApplication.shared.isIdleTimerDisabled = true
resetTracking()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneView.session.pause()
}
func resetTracking() {
let configuration = ARFaceTrackingConfiguration()
configuration.isLightEstimationEnabled = true
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}
private func setupFaceNodeContent() {
for child in faceNode.childNodes {
child.removeFromParentNode()
}
faceNode.addChildNode(virtualFaceNode)
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
print("トラッキング開始")
faceNode = node
serialQueue.async {
self.setupFaceNodeContent()
}
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let faceAnchor = anchor as? ARFaceAnchor else { return }
let geometry = virtualFaceNode.geometry as! ARSCNFaceGeometry
geometry.update(from: faceAnchor.geometry)
}
func session(_ session: ARSession, didFailWithError error: Error) {
guard error is ARError else { return }
}
func sessionInterruptionEnded(_ session: ARSession) {
DispatchQueue.main.async {
self.resetTracking()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
実機での確認
ARkitのFace Trackingは画像などの人物にも有効です。
下記の画像は、Googleで画像検索した人を楽○カードマンにして見ました。

自分の顔でも実際動作し動きにも対応しているので試して見てはいかがでしょうか
おわりに
今回作った楽○カードマンになれるアプリはとても簡単に実装できました。
今回はXcodeを使って政策しましたが、Unityなどを使うともっと様々なオブジェクトを容易に顔面に貼り付けたり、顔をつかったゲームを作れそうですね。
ARkit 2が発表されており、FaceTrackingでは舌と目線が検知できるようになるらしいです。
これからどんどん活性化していくAR,VR,MRにはまだまだ注目していきたいところですね。
参考
はじめにでも書いたようにApple のサンプルです。
Apple Developer Documentation