独自のアプリで拡張フェイスを使用する方法を学びます。
前提条件
- Xcode バージョン 13.0 以降
- Cocoapods を使用している場合: Cocoapods 1.4.0 以降
- iOS 12.0 以降を搭載した ARKit 対応の Apple デバイス(デプロイ ターゲットが iOS 12.0 以降である必要があります)
サンプルアプリをビルドして実行する
詳しい手順については、クイックスタートをご覧ください。
- GitHub から ARCore SDK for iOS のクローンを作成するか、この SDK をダウンロードして、サンプルアプリのコードを取得します。
- ターミナル ウィンドウを開き、Xcode プロジェクトが存在するフォルダから
pod install
を実行します。 - Xcode バージョン 10.3 以降でサンプルアプリを開き、USB 経由でデバイスを開発マシンに接続します。ビルドエラーを回避するには、
.xcodeproj
ファイルではなく.xcworkspace
ファイルからビルドしていることを確認してください。 - Cmd+R キーを押すか、Run をクリックします。拡張フェイスを使用する場合は、シミュレータではなく物理デバイスを使用します。
- [OK] をタップして、カメラがサンプルアプリにアクセスできるようにします。アプリが前面カメラを開き、カメラフィードですぐに顔をトラッキングします。額の両側にキツネの耳の画像が配置され、自分の鼻の上にキツネの鼻が配置されます。
アプリに拡張フェイスを実装する方法の概要
*.scn
ファイルを Xcode にインポートする
アプリで検出された顔にテクスチャや 3D モデルなどの独自のアセットを追加するには、*.scn
アセットを Xcode にドラッグします。
拡張フェイス セッションを初期化する
アプリで Augmented Faces API を使用するには、Augmented Faces セッションを初期化します。このセッションは、60 fps でカメラ画像を取得し、顔の更新を非同期でデリゲート メソッドに返します。初期化するときに、キャプチャ デバイスの画角を渡し、デリゲートを設定します。
// Session takes a float for field of view
let faceSession = try? GARAugmentedFaceSession(fieldOfView: cameraFieldOfView)
faceSession?.delegate = self
カメラ画像をセッションに渡す
セッションが適切に初期化され、構成されたので、アプリはカメラ画像をセッションに送信できるようになりました。このサンプルアプリでは、前面カメラの動画フレームを使用して AVCaptureSession
を作成し、カメラ画像を取得します。
次のコードサンプルは、AVFoundation
のキャプチャ出力デリゲート メソッドの実装を示しています。このメソッドは、画像、タイムスタンプ、認識回転をフェイス セッションに渡します。
func captureOutput(_ output: AVCaptureOutput,
didOutput sampleBuffer: CMSampleBuffer,
from connection: AVCaptureConnection) {
faceSession.update(with: imageBuffer,
timestamp: frameTime,
recognitionRotation: rotationDegrees)
}
画像が処理されると、Augmented Faces API は GARAugmentedFaceFrame
を返すデリゲート コールバックを送信します。これには、顔にエフェクトを適用できる拡張顔オブジェクトが含まれています。また、更新メソッドに渡した画像バッファとタイムスタンプも含まれます。これは、顔のエフェクトを画像と同期する場合に便利です。このオブジェクトには、検出された顔に付加される顔エフェクトを簡単にレンダリングできるように、3D ワールドと 2D ビューを設定するためのディスプレイ変換と投影行列も用意されています。
var face: GARAugmentedFace? { get }
var capturedImage: CVPixelBuffer { get }
var timestamp: TimeInterval { get }
顔メッシュの向き
iOS のフェイスメッシュの向きをメモします。
顔に 2D テクスチャを適用する
サンプルアプリには、拡張された顔を SCNGeometry
オブジェクトに変換するクラスが用意されています。このジオメトリを使用すると、SceneKit ノードに簡単にアタッチできます。このノードは、拡張フェイスの Center 変換に配置します。
let faceNode = SCNNode()
// Gets the most recent frame's face
let face = faceSession.currentFrame?.face
// This is instantiated once, not with every frame
let faceGeometryConverter = FaceMeshGeometryConverter()
// Converts Augmented Face to SCNGeometry object
let faceMesh = faceGeometryConverter.geometryFromFace(face)
// Assigns geometry to node and sets the pose
faceNode.geometry = faceMesh
faceNode.simdTransform = face.centerTransform
2D 顔テクスチャは UIImage
として読み込まれ、顔メッシュのジオメトリに適用されるマテリアルに設定されます。
faceTextureMaterial = SCNMaterial()
faceTextureMaterial.diffuse.contents = UIImage(named:@"face.png")
faceMesh?.firstMaterial = faceTextureMaterial
3D オブジェクトを顔に装着する
デリゲート コールバックから受け取った GARAugmentedFace
には、顔にコンテンツを適用するために使用できる 3 つの異なる領域(変換)が用意されています。これらの変換により、世界空間で鼻、額の左側、額の右側を取得できます。ここでは、鼻の変換を使用して球体を鼻に接続しています。
// Create node and add to scene
let node = SCNNode(geometry: SCNSphere(radius: .02))
sceneView.rootNode.addChild(node)
// Every frame updates the node's position
node.simdWorldTransform = session.currentFrame.face.transform(for: .nose)
独自のアセットを Xcode にインポートする
アプリで検出された顔にテクスチャや 3D モデルなどのアセットを追加するには、まずアセットを Xcode にインポートします。
*.dae
(3D モデル)ファイルをエクスポートします。*.dae
ファイルを Xcode プロジェクトにドラッグします。- Xcode で Editor > Convert to SceneKit scene file format (.scn) に移動して、ファイルを
.scn
形式に変換します。