Unity AssetのKinect v2 Examples with MS-SDKを使用してHD Faceの各ポイントを取得する手順を説明します。
1. HD Faceを使えるように設定する
適当なGameObject(仮にFaceObjという名前にしておきます)にKinectManagerとFacetrackingManagerをAdd Componentして
Get Face Model Data にチェックを入れます。
2. 各Faceポイントを取得する
Asset内にある GetFacePointsDemo.cs を参考に各ポイントが取得できるスクリプト GetFacePoints.cs を作りFaceObjにAdd Componentする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
using UnityEngine; using System.Collections; using System.Collections.Generic; using Microsoft.Kinect.Face; public class GetFacePoints : MonoBehaviour { [Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")] public int playerIndex = 0; private KinectManager manager = null; private FacetrackingManager faceManager = null; private Vector3[] faceVertices; private Dictionary<HighDetailFacePoints, Vector3> dictFacePoints = new Dictionary<HighDetailFacePoints, Vector3>(); // returns the face point coordinates or Vector3.zero if not found public Vector3 GetPoint(HighDetailFacePoints pointType) { if (dictFacePoints != null && dictFacePoints.ContainsKey(pointType)) { return dictFacePoints[pointType]; } return Vector3.zero; } void Update() { if (!manager) { manager = KinectManager.Instance; } if (!faceManager) { faceManager = FacetrackingManager.Instance; } // get the face points if (manager != null && manager.IsInitialized() && faceManager && faceManager.IsFaceTrackingInitialized()) { long userId = manager.GetUserIdByIndex(playerIndex); if (faceVertices == null) { int iVertCount = faceManager.GetUserFaceVertexCount(userId); if (iVertCount > 0) { faceVertices = new Vector3[iVertCount]; } } if (faceVertices != null) { if (faceManager.GetUserFaceVertices(userId, ref faceVertices)) { Matrix4x4 kinectToWorld = manager.GetKinectToWorldMatrix(); HighDetailFacePoints[] facePoints = (HighDetailFacePoints[])System.Enum.GetValues(typeof(HighDetailFacePoints)); for (int i = 0; i < facePoints.Length; i++) { HighDetailFacePoints point = facePoints[i]; dictFacePoints[point] = kinectToWorld.MultiplyPoint3x4(faceVertices[(int)point]); } } } } } } |
3. 各FaceポイントをPixel値で取得する
GetFacePointsTest.cs を作成してFaceObjにAdd Componentします。これで実行するとNoseTopの位置がpixel値で表示されるはずです。
※ここでpublic宣言しているKinectManagerとGetFacePointsはEditorで指定しておいてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
using UnityEngine; using Windows.Kinect; public class GetFacePointsTest : MonoBehaviour { public KinectManager kinectManager; public GetFacePoints getFacePoints; private KinectSensor sensor; // Use this for initialization void Start () { sensor = KinectSensor.GetDefault(); } void Update () { Vector2 pos = GetFacePos(Microsoft.Kinect.Face.HighDetailFacePoints.NoseTop); print(pos); } public Vector2 GetFacePos(Microsoft.Kinect.Face.HighDetailFacePoints point) { // 指定のポイントを取得します。 Vector3 facePos = getFacePoints.GetPoint(point); // Colorのpixelに位置を合わせます。 CameraSpacePoint faceCameraSpace = new CameraSpacePoint(); faceCameraSpace.X = facePos.x; faceCameraSpace.Y = facePos.y - kinectManager.sensorHeight; faceCameraSpace.Z = facePos.z; ColorSpacePoint faceColorPoint = sensor.CoordinateMapper.MapCameraPointToColorSpace(faceCameraSpace); if (float.IsInfinity(faceColorPoint.X)) return Vector2.zero; Vector2 faceVec2 = new Vector2(faceColorPoint.X, faceColorPoint.Y); return faceVec2; } } |
コード解説
(1) y軸方向の座標をassetの位置からkinectの位置に変更しています。
28 |
faceCameraSpace.Y = facePos.y - kinectManager.sensorHeight; |
(2) kinectManagerに CoordinateMapper がなかったため下記の部分では Windows.Kinect の CoordinateMapper を使用しています。
30 |
ColorSpacePoint faceColorPoint = sensor.CoordinateMapper.MapCameraPointToColorSpace(faceCameraSpace); |
コメントを残す