HoloLens 2 × MRTK v2.3 で アイトラッキング機能を追加する方法


Overview : 概要

HoloLens 2 から Eye Tracking のデータを取得できるようになりました !ユーザーから取得した視線データの活用方法 ( 操作のトリガーやデータの可視化・分析など ) は数多く考えられ、今後 HoloLens 2 アプリケーション開発で重要なポイントとなると思われるため、基礎情報を整理しておきたいと思います。まず今回は Unity プロジェクトに対して Eye Tracking 機能を追加する方法を公式ドキュメント Getting started with eye tracking in MRTK に従って、解説 & 紹介します。

TOC ( Table of Contents ) : 目次

  • Expected : 本記事を読んで実現できること
  • Development Environment : 開発環境
  • Detail of HoloLens 2's Hardware ( Sensor ) : ハードウェアについて
  • Required : 必要事項
  • Procedure : 導入手順
  • Appendix : 追加情報

Expected : 本記事を読んで実現できること

  • MRTK v2.3 を活用してアイトラッキングの挙動を検証すること

Development Environment : 開発環境

  • Windows PC ( Windows 10 / SDK 10.0.18362 )

    • Unity ( 2018.4.3f1 )
    • Visual Studio ( Community 2017 )
    • Mixed Reality Toolkit ( MRTK v2.3 )
  • HoloLens 2 ( OSビルド番号 : 10.0.18362.1053 )

Detail of HoloLens 2's Hardware ( Sensor ) : ハードウェアについて

実装を行う前に Microsoft HoloLens 2 に搭載されているセンサー系を簡単にご紹介したいと思います。
Microsoft HoloLens 2 には、以下のセンサー類 ( 下表 ) が搭載されています。

HoloLens 2 Sensor 概要
Head Tracking 4台の可視光カメラ
Eye Tracking 2台の赤外線カメラ
Depth 1-MP ToF 深度センサー ( ※ Time of Flight )
IMU ( Inertial Measurement Unit ) 加速度計、ジャイロスコープ、磁力計
Camera 静止画 8MP/ 動画 1080p30

Eye Tracking には、HoloLens 2 ディスプレイ部分に搭載されている 2つの赤外線センサー ( 参考 : 下図 ) が使用されます。

Required : 必要事項

Eye Tracking 機能を正しく動作させるためには、以下の要件に対応する必要があります。

  • ✅ 入力システムに 「 Eye Gaze Data Provider 」 を追加する必要があります。
      ( これによりプラットフォーム側からアイトラッキングデータを取得することができるようになります。 )
  • ✅ MixedRealityPlaySpace > Main Camera にアタッチされた  「 Gaze Provider ( Component ) 」 の [ Use Eye Tracking ] 項目にチェックを入れる必要がります。
  • ✅ Visual Stuido ビルドでビルドする際に Package.appxmanifest の 「 Capability : GazeInput 」 を有効にする必要があります。
  • ✅ HoloLens を装着しているユーザーにて Eye Tracking をキャリブレーションする必要があります。

【 重要 】 これらの要件が満たされていない場合は、「 Eye Tracking 」 ではなく、 「 Head Gaze Tracking 」 に自動的に切り替わります。

Procedure : 導入手順

それでは実際にアイトラッキングを動作させるサンプルアプリを作成してみたいと思います。

【 前提条件 】 以下、MRTK パッケージをインポート済みであること。

  • Microsoft.MixedReality.Toolkit.Unity.Foundation.2.3.0.unitypackage

01. Unity プロジェクト 「New Scene」 を開きます。

02. グローバルメニュー [ Mixed Reality Toolkit ] > 「 Add to Scene and Configure ... ( 赤枠部分 ) 」 を実行します。

上記ボタンを押下すると、以下ゲームオブジェクトがヒエラルキーに追加されます。

  • MixedRealityToolkit
  • MixedRealityPlayspace

03. MRTK : Input System に Eye Gaze data Provider を追加します。

既存の標準プロファイルでは、独自に設定の追加・変更できないので、新規プロファイルを作成します。
Hierarchy より MixedRealityToolkit を選択し、Inspector を確認します。

MixedRealityToolkit ( Componet ) の最上部、プロファイルの Copy & Customize ボタンを押下します。

上記ウィザードが表示されるので、「 Cloning Profile : DefaultHoloLens2ConfigurationProfile 」、「 Profile Name : EyeTrackingSampleMixedRealityToolkitConfigurationProfile (任意) 」 の入力を確認し、Cloneボタンを押下します。
( ※ カスタムプロファイルは、MixedRealityToolkit.Generated > CustomProfiles 配下に格納されます。 )

続いて Input System のプロファイルを Clone します。

さきほどと同様のウィザードが表示されるので、同じように Clone します。

プロファイルの Clone が完了すると、設定の変更が可能になります。
変更が可能になった Input System settings 内に Eye Tracking 用のデータプロバイダーを追加していきます。
まず、+ Add Data Provider ボタンを押下します。

最下部に New Data Provider 10 という名前のデータプロバイダーが追加されます。

上記で追加したデータプロバイダーに、Eye Tracking 設定を追加します。
Type 項目の下矢印ボタンを押下し、[ Microsoft.MixedReality.Toolkit.WindowsMixedReality.Input ] > [ WindowsMixedRealityEyeGazeDataProvider ] を選択します。

これで Eye Gaze Provider の登録が完了します。

04. Gaze Provider にて Eye Tracking を有効化します。

MixedRealityPlayspace > Main Camera にアタッチされている Gaze Provider[ Use Eye Tracking ] にチェックをいれます。

05. EyeGazeProvider で取得できる主なデータ

EyeGazeProvider メンバ変数 概要 備考
UseEyeTracking bool 使用ハードウェアがアイトラッキング可能かつ、アプリの権限 [視線入力] が有効になっている場合 true 、それ以外の場合は false を返す
IsEyeCalibrationValid bool? ( null許容値 ) 装着者のアイトラッキング機能のキャリブレーション有無 ( true / false ) を示す。アイトラッキングシステムからデータを受け取っていない場合は null を返す。 視線入力のパーミッションが有効ではない場合 null が返ってくる。
IsEyeGazeValid bool 現在のアイトラッキングデータが有効かどうか ( true / false ) を示す。 タイムアウト時間を超えた場合、ハードウェアのトラッキングが欠如している場合、パーミッションの問題などで無効になる可能性があります。 極度にディスプレイの外に視線を向けるとアイトラッキングが失われ、False が返ってくる。
GazeOrigin Vector3 視線の原点。IsEyeGazeValidfalse の場合、Head-Gaze の原点を返すので注意。
GazeDirection Vector3 視線の向き。IsEyeGazeValidfalse の場合、Head-Gaze の向きを返すので注意。
HitInfo, HitPosition, HitNormal 現在見ているターゲット ( GameObject ) の情報を返します。

06. Eye Gaze Provider から値を取得する

Data Provider は Mixed Reality Toolkit Service からデータを取得するコンポーネントです。
今回の場合、Input System ( Service ) から Eye Gaze Provider 経由でトラッキングデータの取得を行います。

アプリケーション内のソースコードから Data Provider へアクセスする場合、IMixedRealityDataProviderAccessインターフェースを経由します。さらに 簡単に Data Provider へアクセスしたい場合は、 CoreService という Helper Class を使用すると良いみたいです。

例えば、Eye Tracking のキャリブレーション有無を確認したい場合はこのような記述で値を取得することができます。

bool? CalibrationStatus = CoreServices.InputSystem?.EyeGazeProvider?.IsEyeCalibrationValid;

07. Package.appxmanifest の 機能 : 視線入力 を有効にします。

Visual Studio でビルドを実行する前に Package.appxmanifest の Capability 設定を下記の通り変更します。

※ この設定をしないと Eye Tracking データが取得できないので、必ずチェックを入れるようにしてください。

以上の手順を行うことで、Eye Tracking を既存プロジェクトに組み込むことができます。

Appendix

Calibration チェック用の Prefab

MRTK Example 内にキャリブレーションのチェックを行う EyeCalibrationChecker という Prefab が公開されています。
( Path : Assets/MixedRealityToolkit.Examples/Demos/EyeTracking/General/Prefabs/EyeCalibrationChecker.prefab )

こちらの Prefab にアタッチされている EyeCalibrationChecker.cs スクリプト内でキャリブレーション有無のチェックを実行しているようです。

EyeCalibrationCheker.cs
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using Microsoft.MixedReality.Toolkit.Input;
using UnityEngine;
using UnityEngine.Events;

namespace Microsoft.MixedReality.Toolkit.Examples.Demos.EyeTracking
{
    /// <summary>
    /// Checks whether the user is calibrated and prompts a notification to encourage the user to calibrate.
    /// </summary>
    [AddComponentMenu("Scripts/MRTK/Examples/EyeCalibrationChecker")]
    public class EyeCalibrationChecker : MonoBehaviour
    {
        [Tooltip("For testing purposes, you can manually assign whether the user is eye calibrated or not.")]
        [SerializeField]
        private bool editorTestUserIsCalibrated = true;

        public UnityEvent OnEyeCalibrationDetected;
        public UnityEvent OnNoEyeCalibrationDetected;

        private bool? prevCalibrationStatus = null;

        private void Update()
        {
            bool? calibrationStatus;

            if (Application.isEditor)
            {
                calibrationStatus = editorTestUserIsCalibrated;
            }
            else
            {
                calibrationStatus = CoreServices.InputSystem?.EyeGazeProvider?.IsEyeCalibrationValid;
            }

            if (calibrationStatus != null)
            {
                if (prevCalibrationStatus != calibrationStatus)
                {
                    if (calibrationStatus == false)
                    {
                        OnNoEyeCalibrationDetected.Invoke();
                    }
                    else
                    {
                        OnEyeCalibrationDetected.Invoke();
                    }
                    prevCalibrationStatus = calibrationStatus;
                }
            }
        }
    }
}

See Also