memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

The Eye Tribeが提供するC++サンプルを使ってopenframeworksで動かしてみた

作業を終えた後でofxEyetribeという素敵なアドオンがあることを知ったわけですが。。。

openframeworksでThe Eye Tribeを利用したい人は以下の手順ではなくofxEyetribeをそのまま使えばいいと思います。

とはいえ。もしかすると何か役に立つかもしれないので、The Eye TribeのHPに掲載されているC++のサンプルを利用してopenframeworksで動作するまでの手順を書きます。

ステップ0)openframeworksのprojectGenerator.appを使って新規プロジェクトを作成します。ここではとりあえずプロジェクト名をeyerbieとしました。なんでもいいですが。

ステップ1)次にC++ SDK for The Eye Tribe Trackerをtet-cpp-client-masterをダウンロード&展開して、eyerbieプロジェクトツリーのaddonsにAdd Files to "..."でtet-cpp-client-masterを追加します(Create groupを選択すること)

ステップ2)C++ SDK for The Eye Tribe Trackerではboostを利用しているのでboostライブラリをインストールします。Macの場合はHomebrewでインストールするのが普通と思いますが、これは64ビットバイナリ。一方、openframeworksはは32ビットバイナリ。openframeworksを64ビットで再コンパイルするのは大変らしいので、32ビットのboostを公開してくれているのでそれをダウンロードします。で、その中のboost_libstdc++.dmgを開いて適当なフォルダにincludeとlibをいれます。そして、include、libを読み込むように設定します。具体的には以下。

  • Build Settings -> Search Paths -> User Header Search Pathsに上記のincludeのパスを追加
  • Build Settings -> Search Paths -> Library Search Pathsに上記のlibのパスを追加
  • Build Phases -> Link Binary With Librariesにlibboost_system.aとlibboost_thread.aを追加

ステップ3)eyetribeプロジェクトのsrcにMyGaze.h, MyGaze.cppを新規追加します。それぞれのファイルの中にThe Eye TribeのHPに掲載されているサンプルをコピペします。具体的には各ソースは以下のようにしました。

  • MyGaze.h
#ifndef __eyetribe__MyGaze__
#define __eyetribe__MyGaze__

#include <stdio.h>
#include "gazeapi.h"
#include "gazeapi_types.h"

// --- MyGaze definition
class MyGaze : public gtl::IGazeListener
{
public:
    MyGaze();
    ~MyGaze();
    float x, y; //added
private:
    // IGazeListener
    void on_gaze_data( gtl::GazeData const & gaze_data );
private:
    gtl::GazeApi m_api;
};


#endif /* defined(__eyetribe__MyGaze__) */
  • MyGaze.cpp
#ifndef __eyetribe__MyGaze__
#define __eyetribe__MyGaze__

#include <stdio.h>
#include "gazeapi.h"
#include "gazeapi_types.h"

// --- MyGaze definition
class MyGaze : public gtl::IGazeListener
{
public:
    MyGaze();
    ~MyGaze();
    float x, y; //added
private:
    // IGazeListener
    void on_gaze_data( gtl::GazeData const & gaze_data );
private:
    gtl::GazeApi m_api;
};


#endif /* defined(__eyetribe__MyGaze__) */

続いて、ofApp.hに#include "MyGaze.h"と以下を追加します。

    private:
        MyGaze *gaze;

そして、ofApp.cppに以下のように修正します。あくまで例ですが。

void ofApp::setup(){
    gaze = new MyGaze();
}

(略)

void ofApp::draw(){
    string info = ofToString(ofGetFrameRate(), 2);
    ofDrawBitmapStringHighlight(info, 0, 15);
    
    ofCircle(gaze->x, gaze->y, 20);
}

あと、視線座標の原点が左上なのでフルスクリーンで表示する必要がありますので、main.cppのOF_WINDOWをOF_FULLSCREENに書き換えておしまいです。

手順に書き漏れがあるかもしれませんが。。。一応、以下のように動きます。


The Eye Tribe on openframeworks - YouTube

こんな面倒なことをしなくてもofxEyetribeを使えばいいのですが、ちょっと気になるのが、ofxEyetribeのサンプルを動かすとなぜかFPSが30くらいしかでません。上記のコードでは60近辺までいけます。ofxEyetribeも上記もdrawメソッド内でofGetFrameRate()を呼んでいるので測定方法は同じはずですが。。。不思議。ofxEyetribeのサンプルは手が込んでいるのでその分、FPSが落ちるのか?でもそこまで落ちる理由がよくわかりません。もともと、The Eye Tribe自体のサンプリングレートは60Hz(のよう)なので、できればfixationなど様々なデータを処理するためにも、drawというかupdateで生の値を利用したいところです。ofxEyetribeも上記と同様に内部ではSDKを使っているようなのでそんなに違いはないはずなのですが。。。とりあえず私の用途には上記の方が適しているのでこれを使おうとは思います。