Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
14
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

【脳波測定】Pythonライブコーディングで集中力を音でフィードバックするシステム

MA2018にも応募・展示しています。

FESTA会場で、脳波測定デモやります。
youtubeにビデオプロトタイプもありますので、こちらも見ていってください。

注意

この記事のプログラムはPython2です。

動機

自分の集中力の度合いを脳波から知ることができることを知り、測ってみたいと思ったことがきっかけ。
python2.7系はあまり触ったことがなかったので、こちらのリンクを参考にしました。
MindWaveからPythonを使って脳波の値を取得し、好きなプログラムで利用する方法 - Ambivalent Wanderer

使用する脳波センサ

Amazon | NeuroSky社製 MindWave Mobile 2 脳波センシングヘッドセット [Brainwave Starter Kit][型番80027-032][正規輸入品] | 脳トレ・学習ゲーム | ホビー
images.jpeg
NeuroSky社が開発した脳波センサ
・α波、β波、θ波、γ波などの波形が一通り取れる。
・独自のアルゴリズムで、集中度(attention)、瞑想度(meditation)を取得できる。

使用する開発環境

Python2.7系
専用のライブラリであるthinkgearをpip2でインストール
Bluetooth

セットアップ

基本的に、mindwaveに付属している説明書の手順に沿えば、MacでもWindowsでもiOSでもAndroidでも接続することはできます。

PCの場合、ThinkGearConnectorというアプリがプラットフォームになっているようです。

脳波の値は、Bluetoothによるシリアル通信でまずここで取得され、他のアプリへと送信されます。

その値をpython2で処理するためにthinkgearライブラリを導入。

ちなみに、python3でも同様のライブラリが存在しますが、ストリングエラーを解決した上で実際に動かしてみても、脳波の値を取得できませんでした。ライブラリそのものが古くて、最新のPython3系に対応できていないのかもしれません。

$ pip2 install thinkgear

と入力してthinkgearライブラリをMacにインストール
次に、

$ ls /dev/tty.*

と入力して、Bluetooth接続されている機器一覧を取得。

その中から、tty.MindWave~となっている値をコピペして、次のプログラムで脳波の値を取得します。

mind.py
import thinkgear

PORT = '/dev/tty.MindWaveMobile-SerialPo'
for packets in thinkgear.ThinkGearProtocol(PORT).get_packets():
    for p in packets:
        if isinstance(p, thinkgear.ThinkGearRawWaveData):
            continue
        print p

パッケージの内容変更

thinkgear.py

import sys

import serial

import StringIO

import struct

from collections import namedtuple

import logging
import logging.handlers

##中略

class ThinkGearPoorSignalData(ThinkGearData):
    '''POOR_SIGNAL Quality (0-255)'''
    code = 0x02
    _strfmt = 'POOR SIGNAL: %(value)s'
    _decode = staticmethod(ord)


class ThinkGearAttentionData(ThinkGearData):
    '''ATTENTION eSense (0 to 100)'''
    code = 0x04
    _strfmt = 'ATTENTION eSense: %(value)s'
    _decode = staticmethod(ord)


class ThinkGearMeditationData(ThinkGearData):
    '''MEDITATION eSense (0 to 100)'''
    code = 0x05
    _strfmt = 'MEDITATION eSense: %(value)s'
    _decode = staticmethod(ord)


class ThinkGearRawWaveData(ThinkGearData):
    '''RAW Wave Value (-32768 to 32767)'''
    code = 0x80
    _strfmt = 'Raw Wave: %(value)s'
    _decode = staticmethod(lambda v: struct.unpack('>h', v)[0])
    # There are lots of these, don't log them by default
    _log = False


EEGPowerData = namedtuple('EEGPowerData', 'delta theta lowalpha highalpha lowbeta highbeta lowgamma midgamma')
class ThinkGearEEGPowerData(ThinkGearData):
    '''Eight EEG band power values (0 to 16777215).

    delta, theta, low-alpha high-alpha, low-beta, high-beta, low-gamma, and
    mid-gamma EEG band power values.
    '''

    code = 0x83
    _strfmt = 'ASIC EEG Power: %(value)r'
    _decode = staticmethod(lambda v: EEGPowerData(*struct.unpack('>8L', ''.join( '\x00'+v[o:o+3] for o in xrange(0, 24, 3)))))


def main():
    global packet_log
    packet_log = []
    logging.basicConfig(level=logging.DEBUG)

    for pkt in ThinkGearProtocol('/dev/rfcomm9').get_packets():
        packet_log.append(pkt)

if __name__ == '__main__':
    main()

今回は、ATTENTIONとMEDITATIONの出力を、冒頭の数値が1か2かによって分類するプログラムを作成したので、それぞれ以下のようにしました。

ATTENTION: _strfmt = '1%(value)s'

MEDITATION: _strfmt = '2%(value)s'

#その他のパラメータ
_strfmt = ''

今回は、音で集中力を知ることができるシステムを制作するために、thinkgear同様、pipからsynthesizerライブラリをインストールして、脳波を楽器にする。

neurobot.py
#coding:utf-8
#タイマーかけて、1分間で何回100に到達できるかを競っても面白い。
import thinkgear
from synthesizer import Player, Synthesizer, Waveform

# オーディオデバイス出力用クラス
player = Player()
# 引数を指定しなければデフォルトの出力デバイスが選択されます
player.open_stream()
synth = Synthesizer(osc1_waveform=Waveform.sine, osc1_volume=1.0, use_osc2=False)


attention = 0
meditation = 0

PORT = '/dev/tty.MindWaveMobile-SerialPo'

for packets in thinkgear.ThinkGearProtocol(PORT).get_packets():
    for pkt in packets:
        if isinstance(pkt, thinkgear.ThinkGearRawWaveData):
            continue

        t = str(pkt)

        if t != '':
            differencer = t[0:1]
            if int(differencer) == 1:
                attention = t[1:]
            #if int(differencer) == 2:
            #   meditation = t[1:]

        if int(attention) == 0:# or int(meditation) == 0:
            continue
        print "attention", attention
        #print "meditation", meditation

        attention = int(attention)
        #meditation = float(meditation)
        player.play_wave(synth.generate_constant_wave((attention * 5), 0.1))

集中したら音が高くなっていきます!

脳波を音に翻訳して、あなただけの音を鳴らしてみましょう!
どんな時に音が高くなるのかいろいろ試してみようと思います。

この他にも、脳波を使えば、こんなこともできるようですね。究極のデバイス、究極のインターフェースになるかも⁉︎
「脳波でうごくVTuber」の作り方 - Qiita

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
14
Help us understand the problem. What are the problem?