EyeTrackerでgaze dataを取得する

gaze dataの取得もProライセンスがないとできない?

サンプルプログラム

def myGetGazeData(eyetracker):
    global global_gaze_data
    
    print("Subscribing to gaze data for eye tracker with serial number {0}.".format(eyetracker.serial_number))
    eyetracker.subscribe_to(tr.EYETRACKER_GAZE_DATA, gaze_data_callback, as_dictionary=True)

    # Wait while some gaze data is collected.
    time.sleep(2)

    eyetracker.unsubscribe_from(tr.EYETRACKER_GAZE_DATA, gaze_data_callback)
    print("Unsubscribed from gaze data.")
    
    print("Last received gaze package:")
    print(global_gaze_data)
        
        
def gaze_data_callback(gaze_data):
    global global_gaze_data
    global_gaze_data = gaze_data

メモ

global_gaze_dataには以下のようなデータが格納される(ただしas_dictionary=Trueの場合)

{'right_pupil_validity': 1, 'right_gaze_point_on_display_area': (-0.03804759308695793, -0.001516682212240994), 'left_gaze_origin_validity': 1, 'system_time_stamp': 83366461989L, 'right_gaze_origin_in_user_coordinate_system': (10.435709953308105, -17.863492965698242, 490.8170471191406), 'left_gaze_point_in_user_coordinate_system': (-225.17933654785156, 239.3080596923828, 79.05516815185547), 'left_gaze_origin_in_user_coordinate_system': (-53.26900863647461, -21.059024810791016, 488.1297912597656), 'left_pupil_validity': 1, 'right_pupil_diameter': 2.851318359375, 'left_gaze_origin_in_trackbox_coordinate_system': (0.6585485339164734, 0.5946857929229736, 0.18295831978321075), 'right_gaze_point_in_user_coordinate_system': (-253.1724395751953, 272.1340637207031, 91.00283813476562), 'left_pupil_diameter': 2.85693359375, 'right_gaze_origin_validity': 1, 'left_gaze_point_validity': 1, 'right_gaze_point_validity': 1, 'left_gaze_point_on_display_area': (0.020004242658615112, 0.12727093696594238), 'right_gaze_origin_in_trackbox_coordinate_system': (0.47324785590171814, 0.5821692943572998, 0.1825057417154312), 'device_time_stamp': 5289917103L}

個々の値をとるには、

globl_gaze_data['right_gaze_point_on_display_area'] #右目のディスプレイ上の注視点

のように指定すればよい。

as_dictionary=Falseの場合は、GazeDataクラスのインスタンスが格納されるので、以下のように指定する。

global_gaze_data.right_eye.gaze_point.position_on_display_area
# GazeData, EyeData, GazePointクラスのリファレンスを参照のこと。

EyeTrackerのProSDKライセンスを適用する

前提

  • ライセンスファイル名をXXXXとする
  • ライセンスファイルをスクリプトを実行するフォルダに配置しておく

実行

以下を実行する

    license_file_path = './' + 'XXXX'
    print "Applying license from {0}.".format(license_file_path)
    with open(license_file_path, "rb") as f:
        license_key = f.read()

    #failed_licenses_applied_as_list_of_keys = eyetracker.apply_licenses([tr.LicenseKey(license_key)])
    #failed_licenses_applied_as_list_of_bytes = eyetracker.apply_licenses([license_key])
    #failed_licenses_applied_as_key = eyetracker.apply_licenses(tr.LicenseKey(license_key))
    failed_licenses_applied_as_bytes = eyetracker.apply_licenses(license_key)
    
    if len(failed_licenses_applied_as_bytes) == 0:
        print "Successfully applied license from single key."
    else:
        print "Failed to apply license from single key. Validation result: {0}.".\
            format(failed_licenses_applied_as_bytes[0].validation_result)
補足
  • ライセンスファイルの形式によって、適切なfailed_....をコメントアウトして使うとよいらしい
    • その場合は、if len(failed_....の部分も修正しておくこと

EyeTrackerでキャリブレーションしてみる

画面に注視点を表示する必要あり。
もしくは注視点を書いた紙などをセットしておこなう必要あり。
それも無理なら、とりあえずEye Tracker Managerを使ってキャリブレーションする。
(というようなことがドキュメントに書いてあった)

サンプルプログラム

# calibrationする
def myCalibratingEyeTracker(eyetracker):
    #calibrationする
    calibration = tr.ScreenBasedCalibration(eyetracker)
    #calibrationモードに入る
    calibration.enter_calibration_mode()
    print("Entered calibration mode for eye tracker with serial number {0}.".format(eyetracker.serial_number))
    #calibration用のポイントを設定する
    points_to_calibrate = [(0.5, 0.5), (0.1, 0.1), (0.1, 0.9), (0.9, 0.1), (0.9, 0.9)]
    for point in points_to_calibrate:
        print("Show a point on screen at {0}.".format(point))
        # Wait a little for user to focus.
        time.sleep(0.7)
        print("Collecting data at {0}.".format(point))
        #print("  deb: " + calibration.collect_data(point[0], point[1]))
        if calibration.collect_data(point[0], point[1]) != tr.CALIBRATION_STATUS_SUCCESS:
            # Try again if it didn't go well the first time.
            # Not all eye tracker models will fail at this point, but instead fail on ComputeAndApply.
            calibration.collect_data(point[0], point[1])
    
    print("Computing and applying calibration.")
    calibration_result = calibration.compute_and_apply()    
    print("Compute and apply returned {0} and collected at {1} points.".\
        format(calibration_result.status, len(calibration_result.calibration_points)))

    calibration.leave_calibration_mode()
    print("Left calibration mode.\n")

注意点

  • ライセンス登録しないとだめらしいのでライセンス登録しておきましょう。
  • 最後は必ずleave_calibration_mode()しておくこと
  • 注視点(ポイント)をしばらく見つめさせるだけの余裕を持たせること。
    • 短すぎると失敗するらしい(どの程度が良いかは不明。0.7秒が初期値?)

EyeTrackerの取得

  • 自動検出する方法と直接指定する方法がある
  • 直接指定する場合はアドレスで指定
    • アドレスはEye Tracker Managerを使うと確認できる
      • IP addressをマウスオーバーすると表示される
import tobii_research as tr

# 自動検出
print("自動検出: ")
eyetrackers = tr.find_all_eyetrackers()

for eyetracker in eyetrackers:
    print("Address: " + eyetracker.address)
    print("Model: " + eyetracker.model)
    print("Name(It's OK if this is empty)): " + eyetracker.device_name)
    print("Serial number: " + eyetracker.serial_number)
    
# アドレスを使って直接指定
print("直接指定: ")
address = "tobii-ttp://XXXXX-XXXXXXXXXXXX";
the_eyetracker = tr.EyeTracker(address)

print("Address: " + the_eyetracker.address)
print("Model: " + the_eyetracker.model)
print("Name(It's OK if this is empty)): " + the_eyetracker.device_name)
print("Serial number: " + the_eyetracker.serial_number)

Tobii Eye Tracker 4Cを使って開発してみる-事前準備

注意事項

とりあえずソフトウェアをダウンロードしてEye Trackerを使ってみる

Tobii Gaming | Download or Setup Eye Tracking Software and Drivers
からTobii Eye Tracking Core Softwareをダウンロードしてインストール開始するだけ。

Eye Tracker Managerをインストールする

Tobii Pro SDK - Develop eye tracking applications for research
からEye Tracker Managerをダウンロードしてインストールする。

SDKの場所を追加しておく

import sys
sys.path.append('/path/to/dir')

を使うか、PYTHONPATHに追加しておく。

EyeTracker使用の流れ

Python - Getting started - Tobii Pro SDK documentation

  1. eyetrackerオブジェクトを取得する(Browsing and Connecting to an eye tracker)
    • その後の処理はここで取得したオブジェクトを利用する
  2. キャリブレーション
  3. データ取得

ubuntuに Caffeをインストールできなくてはまった話

ちょっくらディープラーニングでもやってみるか、ということでubuntuにCaffeをインストールしようとした。
が、なんどやってもmakeでhdf5.hが見つからないとかいうエラーが出る。

あれを入れてもダメ、これを入れてもダメ、というようにいろいろ悩んだ挙句、以下の方法でうまくいったみたい。

Optimize build process on debian jessie · Issue #2347 · BVLC/caffe · GitHub

あと、anaconda2を入れてないとダメかも知んない。


とおもったら、こんどはlhdf5が見つからないだと…
 /usr/bin/ld: -lhdf5_hl が見つかりません
 /usr/bin/ld: -lhdf5 が見つかりません

なかなか厳しい。

    • 追記-- 2016/7/12

以下のサイトを参考に、LIBRARY_DIRに、/usr/lib/x86_64-linux-gnu/hdf5/serial を追加したらうまくいったみたい。
http://lang.sist.chukyo-u.ac.jp/Classes/Python/CAFFE-server.txt

モジュールのimportができなくてはまった話

Pythonを使っていてとあるモジュールをimportしようとしたら、

Traceback (most recent call last):
  File "XXXXX.py", line 1, in 
    from XXXXX.YYYYY import ZZZZZ
  File "/aaaa/bbbb/cccc/XXXXX.py", line 3, in 
    from XXXXX.YYYYY import ZZZZZ
ImportError: No module named YYYYY

となって進まない。
同じpyファイルを別のディレクトリに設置するとちゃんと動く。

設置場所によって挙動が違うの?なんで?
と悩むこと小一時間。
sys.pathをみて「カレントディレクトリが最初でしょ、次が…」と確認していてふと気がついた。
もしかして、カレントディレクトリに同じ名前のファイルがあるのでは、と。

ちょっと試すようなファイルはまとめて一つのディレクトリに置いていたんだけど、もうちょっと真面目にファイル管理しないとなー。