ふと思い立ってMindWave Mobileをヤフオクで落としました。140億個とも言われるニューロンが同時多発で動いている脳。その中の1つの電気信号をとっただけで何か分かるなんて毛頭信じちゃいないんですが、眠ってるかどうかくらいは分かるんじゃないかと思って実験してみようと思ったわけです。
とりあえず動かしてみよう。でももうずいぶん昔のデバイスだから、誰かパケット解析くらい実装してないかな・・と見まわして、とりあえず最初にみつけたPythinkgearがpipで入るらしいので入れてみました。動かそうとしたら、pipで入ったくせにPython 3に対応してなくてエラーが出るとか散々だったんですが、まぁついでだしとポーティングしておきました。
これで、Pythonから脳波(の一部)をとれるようになったみたいです。
使い方としては、Neurosky製のDeveloperツールをインストールして、BluetoothでMindWaveをPCと接続して、ThinkGear Connectorという仮想シリアルポートを作成するツールを立ち上げたら以下のコードでOKみたいです。
ただ、ThinkGear Connectorからデータを吐き出させるとき、Devツール内のVisualizerとかで一旦デバイスの信号クオリティを確認してからつないだほうが手戻りがなくて良かったです。他の記事によると、最初からシリアルポートから読みだそうとしてもダメだったけど、こういったアプリで信号を確認してからだとうまくいったみたいな記述も見かけました。アプリ側からデバイスに対して何か設定を流したりしてるんですかね?
まぁとりあえず、深い睡眠のときにあらわれるというデルタ波の強度。
import thinkgear
import logging
def main():
#logging.basicConfig(level=logging.DEBUG)
for pkt in thinkgear.ThinkGearProtocol('COM5').get_packets():
for d in pkt:
if isinstance(d, thinkgear.ThinkGearPoorSignalData) and d.value > 10:
print("Signal quality is poor.")
if isinstance(d, thinkgear.ThinkGearEEGPowerData):
print("Delta value: {}".format(d.value.delta))
if __name__ == '__main__':
main()
こちらは、1秒に1度出力される値です。この”強度”というのは、Neurosky製アルゴリズムが計算した値で、単位はないらしいです。なので、他の波形の値や他の時間の値と比較するという使い方らしい。なかなか扱いに困る。でも生体信号ってこんなもんなんだろうなぁ。
デルタ波以外にも、シータ波、低アルファ波、高アルファ波、低ベータ波、高ベータ波、低ガンマ波、中ガンマ波がとれます。指定方法はこれ。
そして、生の計測した脳波をcsvに落とすコード。
import thinkgear
import datetime
def main():
file_path = "raw.csv"
wflag = False
with open(file_path, mode="w") as f:
f.write("datetime, raw_wave")
for pkt in thinkgear.ThinkGearProtocol('COM5').get_packets():
for d in pkt:
if isinstance(d, thinkgear.ThinkGearPoorSignalData) and d.value < 10:
wflag = True
if wflag and isinstance(d, thinkgear.ThinkGearRawWaveData):
f.write("{},{}\n".format(datetime.datetime.now(), d.value))
if __name__ == '__main__':
main()
512[Hz]くらいで16bitの生の波形が取得できます。何気に凄くないかこれ。
その他、集中度合いやリラックス度合いも取れるようになってます。
このあたりは、Neuroskyのドキュメントと合わせて読むかんじで。
ところで、寝オチたのを検知して目覚ましをかけるみたいな使い方ができないかと思って購入してみたわけですが、実際にこのヘッドセットをつけると、頭が締め付けられて装着は1時間が限界。とても居眠りどころじゃないというのはどうしたらいいんでしょうか。