演算処理詳細

サービスのデータの流れ

schematics

JINS MEMEによるセンシング・20Hzデータの演算

センサーによるデータの取得から20Hzデータに変換するまでを解説します。

JINS MEME ではまばたき・視線移動を検出する眼電位センサー、動きを検出する加速度・角速度センサーを搭載しています。各センサーは100hzでデータを取得しており、以下の1次検出を実施します。

※なお、100Hzのデータを取得できる実験用機体も受注生産しております。

まばたき・視線移動の検出

まばたきをした場合、眼電位シグナルに以下のようなピークが鋭くオーバーシュートがあるシグナルが発生します(眼電位シグナルにはアナログ回路にてband pass filterがかかっているため、視線移動は段差ではなくなだらかに収束する波形を示します)。 この基線からのピーク高さをまばたき強度、しきい値線を超えたところから下回るまでのピーク幅(時間)をまばたき速度と呼んでいます。強度は目が大きく開いている状態や、まぶたの開閉スピードが速い状態で高くなり、Margin reflex distanceと相関があります。速度はおおよそ目を閉じている時間(閉眼時間)を表しています。視線移動の場合はオーバーシュートの無いゆるやかに減衰するシグナルになります。

blink_signal

振動などでこれらのようなシグナルに酷似した波形が発生することがあります。JINS MEMEのまばたき判定率は静止時でノイズが無い時95%以上ですが、非静止時やメガネがずれやすい環境下では判定率は低下します。

歩行の検出

歩いたり走ったりした場合、加速度シグナルに以下のようなパターンが発生します。足が地面についた0.15-0.25秒後にwalkingフラグを1回立てます。

walking_flag

ノイズ状態の検出

眼電位シグナルは眉間と鼻あて部分のドライ電極で電位を測定します。そのため運動・顔をしかめる・食事・メガネに触ったりかけ直すなどの動作を行った時には以下のような眼電位シグナルが発生し、この状態の時はノイズ状態フラグが立てられます。ノイズ状態フラグは特定のシグナルレンジを超えている状態から約1秒程度立ち続けます。ノイズ状態の時のデータはまばたきや視線移動のデータが埋もれ、信頼性が低いため、使用しないことを推奨します。

noise_flag

装着状態の検出

加速度シグナルに動きがある時に装着、ほぼ動きが無い時に非装着と判定します。

  • メガネを静かな机の上に置くと90%以上非装着状態と判定されます
  • デスクワークの時には装着状態と判定されますが、まったく頭を動かさない場合、30%程度の確率で非装着と判定されることがあります
  • メガネをかけてなくても、電車・車・歩行の状態ではメガネが動き続けているので、装着と判定されます

20Hzデータへのサマライズ

上記のまばたき・視線移動イベント(未発生時は0出力)と加速度・角度を100Hz→20Hzに間引いて、データを出力します。

メガネのスリープ

メガネを逆さま(±45°程度)にするとBluetooth接続が切断されセンサーによるデータ取得が止まります。この状態では完全にデータを取得できないのでご注意ください。

sleep_state

角度の演算

MEMEアプリでは加速度データから演算、LoggerアプリではジャイロセンサーのデータをリファレンスSDK値をそのまま算出しています。

加速度データによる角度

  • MEMEアプリの画面上にしか表示されていませんので、同等の値をLogger等で必要な場合は独自に演算してください
  • 重力加速度を利用しroll(左右傾き)/pitch(前後傾き)を平均化された加速度(accX/accY/accZ)を使用して算出します
  • 0点補正とドリフト補正が不要です
  • 急速な回転がかかっている時、横にGがかかっている時(車で急加速・急減速時)、激しく走っている時はずれます
  • yaw(首の骨周りの回転角)は算出できません
  • 加速度の平均化は用途に合わせて移動平均の場合は0.5s-1.0s程度、加重平均の場合は直近の係数0.05-0.1程度で演算します
  • 別記事のcalcTiltの部分 にサンプルのロジックが記載されています

ジャイロセンサーによる角度

  • 用途に合わせた0点補正とドリフト補正が必要です(センサーのリファレンスSDK値をそのまま出力しています)
  • 急速な回転を補足するのに向いています

15/60秒間隔データの演算

まばたき間隔の算出

まばたき間隔は途中にノイズ区間を含まないものが集計対象になります。

blink_interval

まばたき統計量の演算

  • まばたき強度・速度・間隔の15/60秒間隔データへのサマライズは、その区間に発生したイベントのグループ化ではなく、直近イベントのバッファに対する処理となっています。バッファ長はおおよそ1区間内の平均イベント数+αに設定しており、区間の前のイベントが残ったり、区間のデータが全て残らないこともありますが、データが欠落しないことを重視しているためこのような処理になっています。
  • 異常値に引きずられることを防ぐため、バッファ追加時に規定しきい値を超えたピークの除外、集計時にバッファ内の最大・最小値付近のデータを省くことがあります。

buffering

各指標の特徴は以下になります。

  • まばたき強度平均:
    • 区間内のまばたき強度の平均です
    • 目を大きく見開いていたり活力がある状態ではまばたきが強くなるため、テンション・覚醒指標の元として使用されます
  • まばたき強度標準偏差
    • 区間内のまばたき強度の標準偏差です
    • まばたきの強さの変化は外部刺激やこころのざわつきに強く依存するため、安定度指標の元として使用されます
  • まばたき速度平均
    • 区間内のまばたき速度の平均です
    • 疲れや眠気で目がトロンとなってくるような現象に影響を受けるため、覚醒指標の元として使用されます
  • まばたき間隔平均
    • ノイズのない区間のまばたき間の秒数の平均を取ります
    • 一つのタスクに没頭しているとまばたきが減ることが知られており、没入指標の元として使用されます
  • まばたき回数
    • 計算に使用したまばたきの回数です
    • ノイズ時間内に発生したまばたきは捕捉できないため、まばたき回数の時間変化などの用途では瞬き間隔を使用することが推奨されます

※各指標、演算の元となる合計値やデータ数を残すことがあります。

Body指標の演算

15/60秒間隔データへの Summarize 時に以下の演算を行います。

  • 前傾・横傾角
    • 重力加速度から頭の傾きの絶対値(deg)を前方向・横方向それぞれ算出します
    • 各軸の移動平均を取ることで0.5秒未満の振動成分を減らしてからatan()関数で角度を算出しています
  • 姿勢安定性
    • 上記の振動成分を減らした前傾角・横傾角の20Hzでの標準偏差(deg)を算出しています
  • 振動幅
    • 歩行・走行時の振動幅平均(mm)をX/Y/Z軸それぞれ算出しています
    • 加速度による第一原理計算ではなく振動パターンからの推定になるため、歩走行と異なる波形の場合は正しく算出されないことがあります
  • ピッチ・歩数
    • 1分間の歩数・ピッチ(spm)を算出しています
    • 前段で検出した歩行フラグの合計を取ります
  • 着地強度
    • 歩行・走行時の1歩毎の着地衝撃最大値(G)の区間内全歩数の平均値を算出しています
  • 頭部運動
    • 横方向・縦方向に頭を動かした回数をカウントします
    • 0.07-0.3Gの加速度ピークを検出した時に1回とカウントされ、区間内のカウントの数を記録しています
    • 「複数の対象物に同時に注意を向けている状態」に影響を受けやすく、注意・コミュニケーションの高さと強く連動します

JINS MEMEアプリで使用されている以下の指標は詳細な算出ロジックは非公開となっています。

  • Toral Good Time(Body)
    • 静止時は前傾・横傾角の統合指標です。傾いていないとスコアが上がります
    • 歩行時は前傾・横傾角・振動幅(X/Z)の統合指標です。傾かずに、振動を抑えて歩くとスコアが上がります。

Mind指標の演算

MEMEアプリ/Loggerアプリでの15秒間隔データへの indexation の処理時に以下の演算を行います。

  • 没入(sc_fcs)
    • 原理測定(n=10-20)+フィールド測定(n=50-100)を実施し、クレペリンテストと突き合わせています。
    • まばたき間隔平均値を利用し「ある一つのタスクへの注意が続いている状態」を指標化しています。
    • まばたき間隔平均値が平均値付近より長いと没入度が強いと判定されます
    • スコアの目安
      • 35: まばたき間隔平均が通常時の1/3程度(低い)
      • 45: まばたき間隔平均が通常時と同等
      • 80: まばたき間隔平均が通常時の4倍程度(高い) ※ 通常時 は一般的なユーザー平均と数時間内平均付近を加味して決められます
  • 安定(sc_clm)
    • 原理測定(n=10-20)のみ実施しています
    • まばたき強度平均値を利用し「外部・内部刺激を受けずに安定している状態」を指標化しています
    • まばたき強度標準偏差を直近のまばたき強度平均値で規格化、自乗したものに対する負の1次式でスコアを算出します
    • スコアの目安(通常時において30-100の値を取るように調整してます)
      • 0: まばたき強度標準偏差がまばたき強度平均の50%程度(低い)
      • 50: まばたき強度標準偏差がまばたき強度平均の35%程度
      • 100: まばたき強度標準偏差がまばたき強度平均の15%程度(高い)
  • テンション(緊張, sc_tsn)
    • 原理測定(n=10-20)のみ実施しています
    • まばたき強度平均値を利用し「目が見開いている状態(濃いコミュニケーション、ハイテンション、緊張状態)」の強さを指標化しています
    • 直近のまばたき強度平均値を数時間内まばたき強度平均値で規格化したものに対する1次式でスコアを算出します
    • スコアの目安(通常時において30-100の値を取るように調整してます)
      • 25: まばたき強度が数時間内平均値の半分程度(低い)
      • 50: まばたき強度が数時間内平均値付近
      • 100: まばたき強度が数時間内平均値の2倍程度(高い)
  • 低覚醒(sc_slp, sc_slp_std)
    • 原理測定(n=10-20)+フィールド測定(n=50-100)を実施し、実運転中のビデオ撮影による客観値との突き合わせています。
    • まばたき強度平均値・まばたき速度平均値を利用し「目がトロンとなっている状態」を指標化しています
    • 実データとの合わせ込みで一部まばたき間隔も利用しています
    • テンションと似た傾向を示しますが、より5-10分の長周期で値が変動します
    • 通常状態(直近2-3時間)より相対的にまばたき強度平均値が低い・まばたき速度平均値が遅い状態が続くと覚醒が弱いと判定されます
    • 眉間の電極が浮いていると通常状態を算出する規格化処理が更新されないので高い値が出続けることがあります
    • 運転時覚醒は運転時の姿勢以外(下向き)などでは演算しないように厳しめのエラー処理を入れることで精度を担保しています
    • 通常時覚醒はデスクワークでも測定できるように前記フィルタ処理を除外して演算するようにしています(目が下向きになっていて、 眠そうな目 になっている時には覚醒が低いと判定されることがあります)
    • スコアの目安
      • 0: -0.6σ付近(覚醒高い)
      • 30: 数時間内の平均値
      • 70: +0.8σ付近(覚醒低い)

JINS MEMEアプリで使用されている以下の指標は詳細な算出ロジックは非公開となっています。

  • バイタリティ
    • テンション・低覚醒・頭部運動の複合指標です
  • Toral Good Time(Mind)
    • 没入・安定・バイタリティの複合指標で、2つ以上バランスが良く値が高い場合に高めに出ます

注意点

  • 15秒間隔データはスマートフォンアプリ、60秒間隔データはJINS MEME内で演算が行われます。プロセッサ・メモリの能力に大きな差異があり、集計間隔だけでなく演算自体も異なるため、単純な比較が難しい場合があります。データの比較は 15秒間隔データ同士、 60秒間隔データ同士で実施してください。

頭部運動イベントの演算

Loggerアプリでの headMotion の処理は以下のようになります。頭部運動のイベントデータはWebSocketなどで連携システムをトリガーするために使用することを想定しています(首を2往復以上縦に振ったらテレビをつける、など)。傾きや動きの時系列データが必要な場合は15/60秒間隔データを使用することを推奨します。

高速頭部運動

角速度がしきい値を超えた時にイベントを発行します。この高速頭部運動のみジャイロセンサーのデータを使用するので、使用前に必ず設定の「ジャイロ取得」をオンにしてください。

fast_head_motion

具体的なコードは以下で紹介されています。 https://qiita.com/komde/items/bd682da3d3e11aab325a

低速頭部運動(傾き)

角度がしきい値を超えた時にイベントを発行します。この角度は加重平均により0.5秒以内の速い振動には反応しにくくなっています。

slow_head_motion

低速頭部運動(回転)

傾きをベースにし、一定時間以内に forward, right, backward, left のvalue == 1が連続して発生した場合は subType=”clockwise”, value: 1 を発行、 forward, left, backward, right のvalue == 1が連続して発生した場合は subType=”anticlockwise”, value: 1 を発行します。

トリガーイベントの演算

Webhook APIでの trigger calculation の処理は以下のようになります。トリガーイベントはMEMEアプリからAPIに届いた15秒間隔データを元に演算を実施します。

フィルタ処理

isl==false (装着している状態)のデータのみ処理されます。

加重平均処理

急激に値が変化する指標に対する簡易的な平滑化処理として、加重平均をかけることができます。

  • coeff = 0.8 の場合(強めの加重平均)
    • 前回更新値: 88 , 最新値: 45 -> 更新値: 79.4(45 * 0.2 + 88 * 0.8)
    • 前回更新値: 79.4, 最新値: 32 -> 更新値: 70.0(32 * 0.2 + 79.4 * 0.8)
    • 前回更新値: 70 , 最新値: 91 -> 更新値: 74.2(91 * 0.2 + 70 * 0.8)
  • coeff = 0 の場合(加重平均なし)
    • 前回更新値: 88, 最新値: 45 -> 更新値: 45
    • 前回更新値: 45, 最新値: 32 -> 更新値: 32
    • 前回更新値: 32, 最新値: 91 -> 更新値: 91

判定

以下の条件のANDを取り、TRUEになった場合実際にトリガーを発行します。

  • しきい値
    • 指標(val)がしきい値(th)に対して、以下の指定した条件に合致しているかを確認します。
      • val <= th;
      • val >= th;
      • Math.abs(val) <= th;
      • Math.abs(val) >= th;
      • Math.abs(val) == th;
  • 前回との通知間隔
    • 前回の通知から指定ミリ秒の間隔をあけます。前回通知からここで指定した期間は、しきい値条件がTRUEでも通知がされません。