Monday, 14 January 2019

closed eyes detection


closed eyes detection

turn off the lights by closing your eyes

 --------------------------------------------------------------------------------

 

Brain waves - alpha waves 

 

Brain waves are produced by synchronised electrical pulses of neurons. Imagine you are at a party and everybody is having fun. You sit at the table alone and listen. You can hear that everybody is having fun, but you cannot interpret every conversation. If somebody makes a joke, you can hear the laugh, but you don't know what is it about. That is, what approximately brain waves represent. They can be measured by EEG, whose electrodes are placed on the scull.
Well known is alpha brain wave, with frequency from 8 to 13 Hz. Good intuition is: when eyes are open, brain is processing colored images and interpreting them up to about 150 frames per second. When eyes are closed, brain sees only darkness, the activity is decreased and brain switch to another mode of synchrony, which is called alpha. Most of this processes are located in occipital and parietal regions of the cerebral cortex. 


There are also other brain waves bandwidths: beta(13-30 Hz),  delta (1-5 Hz), theta (4-8 Hz).




Projects

 

Because, alpha waves are easy to detect, there are number of projects, which are using them to control cool stuff. For example Michael Reeves used them and beta brain waves to control speed of the car: Using Mind Control to Drive a Car . Also Wired made video about OpenBCI:  How to Control Things Using Your Brain (and Open-Source Hardware) , where were many stuff controlled by alpha waves.
Controlling something by tracking magnitude of alpha frequency is a good way to impress people, because many of them think, that when you close your eyes, you are focusing on something, and EEG can read what you think. 

Controlling light

 

I've decided to impress people by controlling ligh, with OpeBCI Ganglion, which is open sourced 4 channel EEG bluetooth device with CSR 4.0 dongle and Raspberry pi 3b+. I had few difficulties with connection - a lots of dropped packets, but I managed to solve it - see this thread in openbci forum.
My goal: create program, which can in real time determine if mine eyes are closed or open, based on magnitude of alpha frequency and turn on or off lights.

Recording and preprocessing data

 

For recording data I used OpenBCI_Python library and for data processig brain_waves_openbci, which I wrote for brain waves frequency analysis. It basically receives data, filters them, apply FFT (Fast Fourier Transform) and pass them to the callback function, which is specified by user. Learn more about this process here: eeg-data-processing-in-python
I placed only 1 electrode by 10-20 system on O1 position on skull. 


import brain_waves_openbci as waves
from openbci.ganglion import OpenBCIGanglion

eeg = OpenBCIGanglion()
channels_num = 4
fs = 200 # recording frequency of ganglion
br = waves.Brain_waves(eeg, channels_num, fs)

def nothing(sample):
    pass


br.start_streaming(nothing, None, 25, file_name = 'data/alpha_test.csv')

Brain_waves.start_streaming first argument is function / callback object to which magnitude of selected frequency bandwidth is passed. I wanted to only record data, so function does nothing. Second argument is bandwidth, which is also not needed (for now). If file_name is specified, recorded data are collected in csv file.
 

Selecting threshold

 

For selecting threshold , it is good to visualize data.

import matplotlib.pyplot as plt
import brain_waves_openbci as waves

channels_num = 4
fs = 200 
alpha_band = (8,13)

br = waves.Brain_waves(None, channels_num, fs)
band_vals, time = br.read_csv_waves('data/alpha_test.csv', alpha_band)
plt.plot(time,band_vals[0])
plt.show()
 

It is easy to see on the plot, that when I closed my eyes, the magnitude of alpha frequency increased. I selected threshold for closed eyes to be 0.34

Real time

 

I've connected light to a relay, which I wired to Raspberry pi 's GPIO pins. Raspberry pi connects to OpenBCI board, receives data in real time, process them,  compute magnitude of alpha frequency and if is more than threshold  switches relay.  I won't share the code, but instead of that there is a simple real time closed eyes analyzer for one channel.


import brain_waves_openbci as waves
from openbci.ganglion import OpenBCIGanglion

threshold = 0.34

eeg = OpenBCIGanglion()
channels_num = 4
fs = 200
band = (8,13)
br = waves.Brain_waves(eeg, channels_num, fs)

def check_magnitude(sample):
    if sample[0] > threshold:
        print('eyes are closed')
    else:
        print('eyes are open')

br.start_streaming(check_magnitude, band, 25)



...

 


Are you too lazy to turn the lights off ? Or do you wanna save electricity by turning on the lights only when needed ? This is for you!
.
.
.
Just kidding, this is useless.

Feel free to use brain_waves_openbci to make something better than this.

Wednesday, 28 November 2018

eeg data processing in python

eeg data processing in python

introduction - basics

 --------------------------------------------------------------------------------

My first task with eeg (OpenBCI Ganglion: https://openbci.com ) was to do the basic live visualization (as OpenBCI_GUI: https://github.com/OpenBCI/OpenBCI_GUI ), which receives, interprets, filters data and additionaly create a fft plot, all in python. For now, lets focus on data processing.

data

 There are many datasets of eeg data: https://github.com/meagmohit/EEG-Datasets , but I recommend for learning to record data on your own. Data recorded with openbci devices, looks like this: https://github.com/J77M/eeg-datasets or https://github.com/Vyachez/Project_BCI/tree/master/SavedData . If you recorded data or used one of the datasets, raw data should be in this form:  (n+k)xm  matrix, where m is the number of time points, n is the number of channel data and k is aditional (time, id, ...).


Lets insert data: https://github.com/J77M/eeg-datasets/blob/master/alpha-one-channel/01.csv 
Visualization of channel with index 0:

 

filters

Most used basic filters for eeg are: notch and bandpass (bandpass is composed of lowpass and highpass).
Bandpass is filtering frequency above or under given band, if minimum value is bigger than 0, then bandpass removes DC offset (which is a mean amplitude of signal displacement from zero). Notch is filtering just given frequency value - usually frequency of AC power supply - in US 60 Hz and in Europe 50 Hz. Because it makes big noise in data and must be filtered out.

Filters designed in python: bandpass is a 5th order IIR butterworth filter and notch is 3th order IIR butterworth filter.
(fs = recording frequency -> for this data fs = 200Hz)


def bandpass(start, stop, data, fs):
    bp_Hz = np.array([start, stop])
    b, a = signal.butter(5, bp_Hz / (fs / 2.0), btype='bandpass')
    return signal.lfilter(b, a, data, axis=0)


def notch(val, data, fs):
    bp_stop_Hz = [float(val)] + 3.0 * np.array([-1, 1])
    b, a = signal.butter(3, bp_stop_Hz / (fs / 2.0), 'bandstop')
    fin = signal.lfilter(b, a, data)
    return fin


Visualization of channel 0 after applied notch with value = 50  and bandpass with band = (7,13) :
(in this case the result is same if notch would not be applied - after bandpass signal has only frequencies from 7 Hz to 13 Hz, so filtering 50 Hz does nothing)

FFT

Fast Fourier Transform. Good basic explanation: https://www.youtube.com/watch?v=spUNpyF58BY
Other easy to watch video with basics:  https://www.youtube.com/watch?v=z7X6jgFnB6Y

One option is to put into fft all our data, and the result will be frequencies of all our data, which is in most cases useless (can be used in frontal asymmetry - detecting emotions states). Better way to analyze frequencies is to split data into n chunks and then put each one into fft and analyze it. From the result we can see dynamic changing of frequencies in our brain.
We can conduct Fourier transform at any sampling rate,but more samples for fft we have, more is it precise. The resolution of fft can be calculated: resolution = fs / chunk lenght , if we will choose the chunk lenght to be 200 samples, then resolution will be 1Hz. It means there will be difference between frequency components which are at least this far apart. For better precision, chunk of lenght 400 samples = 2 seconds is good option.

visualization of fft of all chunks:

JUPYTER NOTEBOOK:  

https://github.com/J77M/blg-plusdata/blob/master/eeg-data-processing-in-python/process_data.ipynb


JM

closed eyes detection

closed eyes detection turn off the lights by closing your eyes  --------------------------------------------------------------------...