この授業では、スマートフォンの顔認証機能を使った、簡単な自撮りアプリを作成してみます。
1. 使用するアプリケーション
アプリケーションやスマホゲームの開発によく使われる、Unity、Visual Studio、Xcodeを使用します。3Dモデルの作成にはUnity、プログラミング(コーディング)にはVisual Studioを使います。Xcodeは、iOSアプリのデータを書き出すために利用します。
Unity(ユニティ)は、ユニティ・テクノロジーズ社によるゲーム開発環境です。主にスマートフォンの3Dゲーム開発に使われていますが、2Dのアプリケーション開発にも利用でき、Windows、Macの両方に対応しているため、利便性が非常に高いプラットフォームです。
Visual Studio(ヴィジュアルスタジオ)はMicrosoftが提供するアプリケーション開発環境です。Windows、Android、iOS、Webアプリケーションなど、Windows環境での開発には必須です。Unityと連携しているので、コードを書く作業はVisual Studioで行います。
Xcode(エックスコード)は、Apple社が提供する無料のアプリケーション開発ツールです。Swift、Objective-C、Javaなど、様々な言語に対応しています。
2. Unityの操作画面
まずは、Unityを使ってみましょう。
・シーン(Scene)ビュー
シーンビューには3Dモデルが置かれたゲームのステージが表示されます。
・ゲーム(Game)ビュー
ゲームビューは作成したゲームを確認するための画面です。 また、ボタン入力などのインタフェースの操作はこちらで行います。
・ヒエラルキー(Hierarchy)ウィンドウ
ヒエラルキー(階層)ウィンドウは、シーン内のオブジェクトの一覧が表示される画面です。
・プロジェクト(Project)ウィンドウ
プロジェクトに含まれるシーン、スクリプト、イメージ、マテリアルなど、全ての部品のデータが表示される画面です。
・インスペクタ(Inspector)
選択したオブジェクト、マテリアル、画像などの部品の属性を表示/編集できる画面です。
3. まずは顔のマスクを表示させてみる
まずは、顔を覆うマスク(フェイスメッシュ)を表示してみます。下図のようにFaceGestures > ExpressionManager > Mesh Rendererのチェックを入れてください。表示したくない場合はチェックを外します。
次に、File Menu > Build Settings…を選びます。
Build and Runボタンを押してアプリを作成します。
分かりやすいファイル名をつけて保存してください。
同じファイル名で保存する場合には、以下の画面が出てくるので、Append(上書き保存)を選んでください。
Unityがファイルの書き出しを行った後にXcodeが起動します(結構時間かかります)が、このままだとXcodeでエラーが出るので、左のメニューの「Unity-iPhone」を選んで「Automatically manage signing」にチェックを入れます。
「Enable Automatic」を選択し、「signing」の「Team」を「Tokyo Polytechnic University」にする。
XcodeのRunボタンを押して、アプリのデータをiPhone/iPadに転送するとアプリが起動します。
この作業を一度行うと、それ以降エラーは出なくなります。UnityのFile Menu > Build Settings…を開いて、Build and Runを押したのち、もし以下の画面が出てきたら、Append(追加)ボタンを押してください。
4. 目の位置に画像を表示してみる
ProjectブラウザのAssets > Images > eyeImg1〜7のうち、表示させたい目の画像を選択します。ダブルクリックで実際の画像が表示されます。
ProjectブラウザのAssets > Materials > LeftEyeMaterialを選択し、InspectorのAlbedoの横の丸印をクリックして画像を表示/選択します。新しい目の画像に入れ替わります。
Scripts > ExpressionManagerをダブルクリックすると、コードの編集画面(Visual Studio)になります。UpdatePositionAndRotationメソッドの中に、以下のコードを追加します。データをiPadに書き込んでください。アプリに自分の顔が映ると、左目に設定した画像が表示されます。
1 2 3 4 5 6 7 8 9 10 11 | private void UpdatePositionAndRotation(ARFaceAnchor anchorData) { if (anchorData.isTracked) { //左目の位置、回転、大きさ/////////////////////////////////////////////// //anchorDataは頭の位置と回転方向のデータが保存されている変数 LeftEye.transform.position = anchorData.leftEyePose.position; //位置 LeftEye.transform.rotation = anchorData.leftEyePose.rotation; //回転 } } |
先ほどのマスクの表示と同じようにUnityのFile Menu > Build Settings… > Build and runで、再生してみましょう。あなたの目の位置に画像が現れます。
次は、目の大きさと位置を変えてみます。下図のようにHierarchyのEyeを選んでください。Inspectorビューで、位置と大きさを変えることができます。
InspectorのTransform画面は以下です。
Positionでは、X、Y、Zの座標は以下になります。
数値を変えると、Scene上でオブジェクトが移動し、拡大縮小も反映されます。
5. 目を瞬きさせる
次には自分の目の瞬きに画像が反応するようにしてみましょう。先ほどの編集画面を表示し、以下のコードを追加します。eyeBlink_Lは目が閉じているときは0.0、開いているときは1.0の値になります。
File Menu > Build Settings… > Build and runで、再生してみましょう。
1 | LeftEye.transform.localScale = new Vector3(1.0f, 1.0f - eyeBlink_L, 1.0f); |
6. 目の位置が移動するアニメーションを作成する
次に、目の位置が移動するアニメーションを作成してみましょう。
1 2 3 4 5 6 | //そのオブジェクトから見て前方向に0.001fだけ移動 //Vector3.forward(前)/ Vector3.back(後ろ)/Vector3.left(左)( //Vector3.right(右)/Vector3.up(上)/Vector3.down(下) eyeDist += 0.001f; if (eyeDist > 0.1f) eyeDist = 0.0f; LeftEye.transform.Translate(Vector3.back * eyeDist); |
7. 右目と口も動かしてみる。
左目と同じ要領で、右目と口も動かしてみましょう。口の開閉の検出はjawOpenというパラメータを使います。以下のコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //右目の位置、回転、大きさ////////////////////////////////////////////////////////// RightEye.transform.position = anchorData.rightEyePose.position; //位置 RightEye.transform.rotation = anchorData.rightEyePose.rotation; //回転 RightEye.transform.localScale = new Vector3(1.0f, 1.0f - eyeBlink_R, 1.0f); //大きさ //口の位置(絶対座標)、回転、大きさ////////////////////////////////////////////////// //faceMesh上の点(faceMesh.vertices[]の244番と824番が口の両端になる。 Matrix4x4 localToWorld = transform.localToWorldMatrix; mouthPos_L = localToWorld.MultiplyPoint3x4(faceMesh.vertices[824]); mouthPos_R = localToWorld.MultiplyPoint3x4(faceMesh.vertices[244]); //左と右の口の端の点を求め、その中央の点を求める Vector3 a = new Vector3(mouthPos_L.x, mouthPos_L.y, mouthPos_L.z); Vector3 b = new Vector3(mouthPos_R.x, mouthPos_R.y, mouthPos_R.z); Vector3 center = new Vector3((a.x + b.x) / 2, (a.y + b.y) / 2, (a.z + b.z) / 2); Mouth.transform.position = new Vector3(center.x, center.y, center.z); Mouth.transform.rotation = anchorData.leftEyePose.rotation; Mouth.transform.localScale = new Vector3(1.0f, (jawOpen * 1.5f + 0.5f), 1.0f); |
楽しんでもらえたでしょうか。この技術はARKitといって、Appleが開発したものですが、奥行きを認識できるカメラ(True Depthカメラ)の性能の高さによって、非常に精度の高い表情認識ができます。カメラアプリはみなさんがよく使うアプリの一つだと思いますが、実際にどのような仕組み(プログラム)で動いているのかイメージしていただければ嬉しいです。
7. 参考サイト
Unityを勉強してみたい方は、以下のサイトが参考になります。Unityは無料で始めることができるので、この授業で興味を持ったら、ぜひ自身でも勉強してみてください。
はじめてのUnity(初心者向け)
ドットインストールのUnity入門(初心者から中級者向け)
8. この授業で使用したデータ
この授業で使用したUnityのデータがダウンロードできます。
注)深度カメラ(True Depthカメラ)がついている、iPhone X、iPad Pro(2018年発売)が必要になります。