競プロとか

Pupil Labsを使用して、Unity上に目元の映像を抽出する方法

やりたいこと

f:id:Radperia:20200725170735p:plain

上記画像のように、HMDを装着した際でも目の位置が正しいかどうかを把握したい。

更に、目の位置が正しくてもconfidenceが良くない時もあるので、confidenceの値を見ながら調整できるようにしたい。

環境

  • Unity 2019.4.2f1
  • Pupil Capture v2.1.0
  • Hmd-Eyes.VR.v1.3

下準備

Edit > Project Settings > Player > Api Compatibility Level > .NET 4.x に変更
Assets > Import Package > Custom Package > Hmd-Eyes.VR をインポート

手順

  1. Assets > Plugins > Pupil > Demos > FramePublisherDemo を呼び出し
  2. Eye Frame Visualizer, Connection を使用したいScene内にコピペ

    f:id:Radperia:20200725170737p:plain f:id:Radperia:20200725170741p:plain

  3. コピペすると大体ここら辺の依存関係が崩れるから、適当に修正

  4. これだけで目周辺の位置を表示することが可能、楽。Demoに感謝。

    以下はconfidence値を取得して下部に出力する方法。

  5. GameObject > UI > Canvas を生成

  6. Canvas下に GameObject > UI > Text を生成
  7. Text に適当なC#ファイルをアタッチ

以下適当なソースコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace PupilLabs.Expansion{
    public class ReceivePupilConfidence : MonoBehaviour{
        
        public SubscriptionController subsCtrl;
        public TimeSync timeSync;
        
        public Text statusText;
        private PupilListener listener;
        
        private Text confidenceText;
        private float timeleft;
        private bool flag;
        
        void Start(){
            this.confidenceText = this.GetComponent<Text>();
        }
        
        void OnEnable(){
            if(listener == null){
                listener = new PupilListener(subsCtrl);
            }
            listener.Enable();
            listener.OnReceivePupilData += ReceivePupilData;
        }
        
        void OnDisable(){
            listener.Disable();
            listener.OnReceivePupilData -= ReceivePupilData;
        }
        
        void Update(){
            flag = false;
            timeleft -= Time.deltaTime;
            if(timeleft <= 0.0f){
                timeleft = 3.0f; // 3s間隔でconfidence表示を更新
                flag = true;
            }
        }
        
        void ReceivePupilData(PupilData pupilData){
            double unityTime = timeSync.ConvertToUnityTime(pupilData.PupilTimestamp);
            Debug.Log($"Receive Pupil Data with method {pupilData.Method} and confidence {pupilData.Confidence} at {unityTime}");
            if(flag) this.confidenceText.text = pupilData.Confidence.ToString();
        }
    }
}

基本的にはPupilDataDemo.csを参考に書き換えていけば良い。

参考文献

pupil-labs Developer Documentation
https://github.com/pupil-labs/hmd-eyes/blob/master/docs/Developer.md

Qiita Unityでだいたい〇秒ごとに処理を行う https://qiita.com/okuhiiro/items/4c76fd8862e2bbb08ac7