調べもの帳

「役に立ちそうだなー」「これお金になりそうだなー」って思うことを書く

UnlimitedHandを使って血流のヘモグロビン濃度値を計測したりlibsvmで分類器を作った話

先日UnlimitedHandというデバイスを会社の上司から貸してもらいまして、

そのデバイスを用いて検証することにしました。

測定自体は比較的に楽にできるのですがいくつか問題点はありました。

  • 取り付けるのが難しい

  誰かサポートが必要かもしれないです。

  • 腕とデバイスの接合部のゲルパッドがかなり剥がれやすい

  ゲルパッドが丸まってしまうと再度使用するのが結構厳しい

  amazonでゲルパッド2セット1680円で販売しています

 

気軽に装着できるデバイスとしてUnlimitedHandを使用するのは

少し厳しい感じがします。

 

今回Unityプロジェクトからヘモグロビン濃度の測定を行うための手順を説明します。

1. Arduino IDEをインストールしてシリアル通信を行う

 以下の公式ドキュメントを見てIDEのインストールをして

 シリアル通信を行ってください。

 通信しなければUnityプロジェクトで測定値の受信ができません。

 http://dev.unlimitedhand.com/ja/introduction/index_intro.html#3 

2. UnityプロジェクトにUnity用プラグインを導入する

 以下のURLのPlugin for Unityをダウンロードし、Unityプロジェクトに組み込みます。

 http://dev.unlimitedhand.com/download.html

 このプラグインスクリプトをゲームオブジェクトに追加することで

 測定できるようになります。

 f:id:arystmk1104:20161226042718p:plain

 あとは適当にファイル出力用のスクリプトを作成して計測値を測定します。

 ヘモグロビン濃度だけでなくデバイスのジャイロセンサーや温度センサーの値も

 測定することが可能です。

 

測定用のスクリプト自体は比較的に楽に作成できますが、

実際その値を用いた手の動作キャプチャは精度が微妙だというのを聞いていました。

そこで、このヘモグロビン濃度の時系列データを周波数解析し、

スペクトルを特徴量とした分類器の作成をしました。

何を分類するかというと

  • 力をいれずに手の指を適当に動かしている状態1パターン
  • 握りこぶしを作っている状態1パターン
  • 皮膚の一部をスイッチのように押す状態2パターン

この4パターンで分類を行いました。

目的としてはUnlimitedHandを装着している状態で、

手の一部を押下することで、スイッチの役割として利用できないかを検証するために

行いました。

 

分類器作成用のスクリプトPythonlibsvmを用いた

SVMの分類器を作成しました。

特徴量は高速フーリエ変換によるパワースペクトルを用いました。

開発環境のIDEはPycharmを使用したのですが、libsvmを使用するために

プロジェクトの構造をlibsvm用に設定しなければいけません。

libsvmのso.2ファイルをmakeした後、以下のサイトを見て

Pycharmに合わせたプロジェクトの構成に変更してください。

http://digitallibraryworld.com/?p=520

 

で、結果なのですが上記の4パターンのクラスに分類した結果、

クロスバリデーションで評価したところ分類精度は61%くらいしかなかったです。

分類精度としてはかなり低めだと感じました。

 

そこで「皮膚の一部をスイッチのように押す状態2パターン」のデータで

分類器を作成し分類精度を出したところ55%でした。

この2パターンのデータが分類精度を下げる要因であることがわかりました。

 

そこでこの2パターンのデータのうち片方のパターンを除外し、

3パターンの学習データで分類器を作成しました。

その結果、分類精度83%となり、3クラスの分類器としては

かなり高めの精度となりました。

 

一応、手の状態における分類をUnlimitedHandで可能だと思いますが、

手への刺激を検知するのはあまり特徴として出ないと考えられます。

腕に力をいれることで魔法のように電子機器を操作することならできるように思えます。

Tobii EyeX SDK for Unityを触ってみた

どうもともきです。順序として先に視線の距離を用いた解析プログラムを作成したかったのですが、先にUnityでゲームを作ることになりました。

そこでTobii EyeX SDK for Unityを使ってまず導入方法の調査やサンプルを用意しようかと思います。

 

手順としてはこのような流れになります。

  1. Unityをインストールする
  2. Tobii EyeX SDK for Unityをダウンロードする
  3. Unityプロジェクトを作成する
  4. Tobii EyeX SDK for Unityのパッケージをインポートする
  5. Unity上で視覚情報を取得するためのスクリプトを用意する

1. Unityをインストールする

Unityをダウンロードしてインストールしてください。ドキュメントを見る感じバージョンは5.3.1以上で動作できます。

Unity - Get Unity

 

2. Tobii EyeX SDK for Unityをダウンロードする

Tobii EyeX SDK for Unityをダウンロードしてください。

Download Tobii SDKs and Developer Tools

 

3. Unityプロジェクトを作成する

プロジェクトを作成してください。特に専用の設定はないです。

 

4. Tobii EyeX SDK for Unityのパッケージをインポートする

Tobii EyeX SDK for Unity内に含まれるEyeXFramework.unityPackageをインポートする。

これでTobii EyeXのコンポーネントを使用することができます。

 

5. Unity上で視覚情報を取得するためのスクリプトを用意する

空のゲームオブジェクトにTobii EyeXのコンポーネントを追加する。

以下の画像で追加されている「Gaze Point Data Component」と「Eye Position Data Component」が追加したコンポーネントである。

f:id:arystmk1104:20160411010308j:plain

これらのコンポーネントを追加したのを踏まえて用意したTobii Eyex Arrange Controllerというスクリプトを用意した。

 

ただ単に視覚情報の座標を出力するだけのコードだが、右目と左目の有無も特定できるので瞬きの検出もできそうです。

次はこのゲームオブジェクトを使ってゲームを作成します。

ffmpegでヒートマップの連番画像から動画を作成する

今回はヒートマップの連番画像を作成し、ヒートマップの動画を作成します。
前回のスクリプトをもとに動画用のスクリプトを作成しました。

今回はffmpegを使用するので、環境に応じてffmpegを導入してください。
私は以下のページを参照しました。

nu-pan.hatenablog.com

環境変数ちゃんと設定して、コマンドラインで動作確認しましょうね。

で、早速ですが作成したコードを貼ります。

動画作成する手順としては以下の通りです。

  1. csvファイルを読み込む
  2. 時系データをもとに指定したfpsで動画が作成できるかvalidateする
  3. imagesディレクトリを作成する
  4. 指定fps通りヒートマップの連番画像を作成し、imagesディレクトリに保存する
  5. imagesディレクトリのヒートマップの連番画像から指定fpsの動画を作成する
  6. imagesディレクトリを削除する

連番画像を保存しているのですが…うーん…長くてfpsが高い動画を作るとなると、毎回大量の連番画像を作る仕組みにしているのでなんとかしたいっすね…

実際こんな感じの動画が作成できます。

youtu.be

10fpsなので結構カクカクな動画になってます。時系列データが100[ms]間隔なのでしゃーないです。
でもこれで短期的な視線の位置や変化を可視化することができました。

次はヒートマップ以外の出力を試してみようかと思います。

tobii eyeXで測定した視覚情報のcsvファイルからヒートマップ画像を作成してみた

前回、Tobii EyeXのSDKで測定用アプリケーションを作成しました。

tomohage-tech.hatenablog.com

実際に測定したデータを人に見せる際、やはり時系列データをポンと見せても「いや…見せられてもよくわからないっす…」という反応だと思われます。
そこで、こういう視覚情報の時系列データを他人に提示するために、ヒートマップやゲイズプロットのようなグラフを作成します。

本題ですが、今回は前回作成した視覚情報の時系列データを用いてヒートマップを作成します。
こういう図を作成する方法として、opencvとかmatlabとか使えば作成できるみたいですが、今回すごく簡単にヒートマップを作成できるPythonライブラリがあったので紹介します。

今回扱うライブラリはjjguy氏が作成したヒートマップライブラリです。

heatmap.py: create heatmaps in python

python2.xでしか使用できないので注意してください。

パラメータを少しいじれば見栄えがとても良いヒートマップ画像を作成することができます。
サンプルコードは以下のように作成してみました。

[2016/11/03追記]
コメント欄でguest様がご指摘している通り、
csvファイルの文字列読み込みの処理に問題があるようです。
サンプルコードの挙動に問題があれば、
コメント欄のguest様の改修案を参考に修正をお願いします。
尚、現状私の開発環境では再現できない状態になっていて、検証ができない状態です。
開発環境を用意し次第、検証・調査を行い、修正をする予定ですので、
準備ができるまで何卒、お待ちいただけるようお願いいたします。

前回作成した測定アプリケーションで生成した視覚情報のcsvファイルをそのまま読み込めば実行できますが、重要な箇所は以下のコードです。

    img = hm.heatmap(
        points=pts,
        size=monitor_size,
        dotsize=30,
        area=((0, 0),(monitor_size[0], monitor_size[1])),
        scheme='classic',
        opacity=150
        )

パラメータをざっくり説明すると以下のようになる。

points: ヒートマップを形成する点のリスト
size: 画像のサイズを指定するリスト
dotsize: ヒートマップで生成される点の大きさ
area: ヒートマップを生成する領域で、最少値と最大値で指定できる
scheme: ヒートマップのグラデーションを変えることができる
opacity: ヒートマップの透明度を指定できる

詳しくは配布先のページに書かれているので、不安でしたら確認してください。
実際コード書いて、パラメータを変更しながらヒートマップを作成するのもいいですね。

で、実際どんな画像が作成できるのかというと、このような画像が作成できます。

f:id:arystmk1104:20160328045029p:plain

この画像、ゲームプレイしている際のヒートマップでして、だいたい20分くらいの時系列データから作成しています。

長時間の時系列データを一気にヒートマップすると、一応特徴は捉えられますがわかりづらい結果になっています…。

どうせ作成するならもうちょっと短期的な時系列データで画像を作成するか、動画にした方が特徴が出るかもしれないですね…。

次回はヒートマップの画像を用いて、ヒートマップの動画を作成する方法を書きます。

Tobii EyeXとWindowsFormアプリケーションで測定アプリを作成してみた

ブログ作成から5時間くらい経って、とりあえず測定用のアプリ用のコードを少し清書してpushしました。

github.com

 

基本的に前回の記事で用意したコントローラを用いて作成すれば楽に作成できるかと思われます。

tomohage-tech.hatenablog.com

 

さて、今回はコードの説明ではなくこのアプリの使い方を書いておきます。

(使い方は見てもらってわかると思いますが…)

 

1. 起動時のフォーム

この状態だとレコードボタンを押せず、まず先に設定ボタンを押して

保存先のファイルパスを設定する必要がある。

f:id:arystmk1104:20160321211402j:plain

 

2. レコード開始

保存先のファイルパスを指定した後、レコードボタンが押せるようになるので、レコードボタンを押す。

f:id:arystmk1104:20160321211702j:plain

 

3. レコード中

レコードが開始されるとタイマーラベルの時刻が進み始める

f:id:arystmk1104:20160321212211j:plain

 

4. トリガーをONにする

切り替えボタンを押すことでトリガーを視覚情報の時系列データに付与することができます。

f:id:arystmk1104:20160321213337j:plain

 

 

f:id:arystmk1104:20160321213454j:plain

どういうときに使用するかは計測者次第だが、私の場合はゲームプレイ中に抽出したいシーンの際、トリガーをONにしていました。格闘ゲームの対戦中だとか、RPGの戦闘画面だとか、ピンポイントにデータを抽出する際、この機能を使用します。

 

とりあえずTobiiのアイトラッカーを用いた視覚情報の測定はできるようになりました。

次回はこのアプリケーションで測定したデータを用いて、Pythonでヒートマップを作成する方法を書きます。

視覚情報の座標を常に受け取り続けるサンプルコード

これさえできればアイトラッカー関係のアプリケーションはいくらでも作成できると思います。 まずここからTobii EyeX SDKをダウンロードしてください。

http://developer.tobii.com/downloads/

今回、開発する環境はWindows/C#/Visual Studio2015で行うため、SDK for .NET系のSDKをダウンロードしてください。 ファイルの中にlibフォルダとsourceフォルダがあります。

sourceフォルダにはTobiiが用意して下ったサンプルコードがあります。 (測定用のプログラムもあるので、まずそのコードを読んだ方がいいかも)

libフォルダにはdllファイルがあり、こちらを作成するプログラムに追加する必要があります。 「参照の追加」からTobii.EyeX.Client.Net20.dllとEyeXFramework.dllを追加し、プロジェクトから「既存の項目」として、Tobii.EyeX.Client.dllを追加します。 (Tobii.EyeX.Client.dllのプロパティで「出力ディレクトリにコピー」という項目があって、ここを「新しい場合はコピーする」と設定しないとビルドできないかも…)

実際どのようなコードを作成する必要があるのかというと、EyeXHostクラスのオブジェクトを管理する コントローラクラスを用意すればいいと思います。 このコントローラクラスに視覚情報のx, y座標をメンバ変数として管理し、 取得するたびに最新の値に更新されるようにすれば、リアルタイムで視覚情報が反映されるアプリケーションを作成することができるはずです。

※ Tobii EyeXのSDKでモニターのサイズとか取得できるかどうかちょっとわからないので暫定対応しています

結局のところ、このクラスで行っている処理は

  1. EyeXHostオブジェクトを作成する

  2. EyeXHostオブジェクトを起動する

  3. EyeXHostオブジェクトからデータストリームを取得する

  4. データストリームのNextイベントリスナーに、新しいイベントが発生したらメンバ変数のx, yを更新するようなイベントハンドラを追加

つまり、視覚情報の座標データをアイトラッカーから受け取ったら、 メンバ変数のx, yを更新するようになります。

とりあえず作成したサンプルはgithubに載せておきます。動かなかったり、変なところがあれば連絡いただけると幸いです。

github.com

TobiiEyeXでユーザの視覚情報を取得する

Tobii EyeXとはTobii社が出しているアイトラッカーで、かなりの高精度で視覚情報を取得することができます。(eyetribeというアイトラッカーを使用しましたが、圧倒的にTobiiの方が精度が高いと感じました)

視覚情報を取得することで何ができるかと言うと以下の2点が挙げられます。

  • 視覚でPCの操作ができる
  • 広告、動画といったメディアを評価することができる

ただ、一つ目の視覚でPCの操作をすることはできるのだが、

手が不自由なユーザを対象となると、ターゲットが狭すぎるように思います。

健常者ユーザがわざわざ手を用いずに目で操作するにしても、かなりのトレーニングをユーザへ強いると考えています。

 

そこで今回、アイトラッカーを用いてお金になりそうなことを考えたのですが、

以下の2点に絞ることにしました。

 

  • 広告、動画といったメディアだけでなく、ゲームのインタフェースを改善するための評価指標を用意する
  • 視覚情報を用いてユーザを監視する

 

前者はまぁわかるとして後者はかなり物騒に聞こえるかもしれないですwww

ただ、ユーザへ貴重な体験を提供するためには必要な要素だと私は思っています。

次の記事からTobii EyeXのサンプルコード、作成方法について説明します。