独自のアプリで拡張フェイスを使用する方法を学びます。
前提条件
- 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
オブジェクトに変換するクラスが用意されています。このジオメトリを使用すると、Augmented Face の Center 変換に配置する SceneKit ノードに簡単にアタッチできます。
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
形式に変換します。