6
6
import pyqtgraph as pg
7
7
import pylsl
8
8
import sys
9
- from scipy .signal import butter , filtfilt , iirnotch
9
+ from scipy .signal import butter , iirnotch , lfilter , lfilter_zi
10
10
from scipy .fft import fft
11
+ import math
11
12
12
13
class EEGMonitor (QMainWindow ):
13
14
def __init__ (self ):
@@ -73,8 +74,6 @@ def __init__(self):
73
74
print (f"Sampling rate: { self .sampling_rate } Hz" )
74
75
75
76
# Data and Buffers
76
- self .filter_buffer_size = 30 # Minimum length for filtfilt
77
- self .filter_buffer = deque (maxlen = self .filter_buffer_size )
78
77
self .one_second_buffer = deque (maxlen = self .sampling_rate ) # 1-second buffer
79
78
self .buffer_size = self .sampling_rate * 10
80
79
self .moving_window_size = self .sampling_rate * 2 # 2-second window
@@ -86,6 +85,9 @@ def __init__(self):
86
85
self .b_notch , self .a_notch = iirnotch (50 , 30 , self .sampling_rate )
87
86
self .b_band , self .a_band = butter (4 , [0.5 / (self .sampling_rate / 2 ), 48.0 / (self .sampling_rate / 2 )], btype = 'band' )
88
87
88
+ self .zi_notch = lfilter_zi (self .b_notch , self .a_notch ) * 0
89
+ self .zi_band = lfilter_zi (self .b_band , self .a_band ) * 0
90
+
89
91
# Timer for updating the plot
90
92
self .timer = pg .QtCore .QTimer ()
91
93
self .timer .timeout .connect (self .update_plot )
@@ -99,16 +101,13 @@ def update_plot(self):
99
101
if samples :
100
102
for sample in samples :
101
103
raw_point = sample [0 ]
102
- self .filter_buffer .append (raw_point )
103
104
104
- # Apply the filters if the buffer is full
105
- if len (self .filter_buffer ) == self .filter_buffer_size :
106
- notch_filtered = filtfilt (self .b_notch , self .a_notch , list (self .filter_buffer ))[- 1 ]
107
- band_filtered = filtfilt (self .b_band , self .a_band , list (self .filter_buffer ))[- 1 ]
108
- else :
109
- continue
105
+ notch_filtered , self .zi_notch = lfilter (self .b_notch , self .a_notch , [raw_point ], zi = self .zi_notch )
106
+ band_filtered , self .zi_band = lfilter (self .b_band , self .a_band , notch_filtered , zi = self .zi_band )
107
+ band_filtered = band_filtered [- 1 ] # Get the current filtered point
110
108
111
- self .eeg_data [self .current_index ] = band_filtered # Plot the filtered data
109
+ # Update the EEG plot
110
+ self .eeg_data [self .current_index ] = band_filtered
112
111
self .current_index = (self .current_index + 1 ) % self .buffer_size
113
112
114
113
if self .current_index == 0 :
@@ -139,12 +138,16 @@ def process_fft_and_brainpower(self):
139
138
self .brainwave_bars .setOpts (height = brainwave_power )
140
139
141
140
def calculate_brainwave_power (self , fft_data , freqs ):
142
- delta_power = np .sum (fft_data [(freqs >= 0.5 ) & (freqs <= 4 )] ** 2 )
143
- theta_power = np .sum (fft_data [(freqs >= 4 ) & (freqs <= 8 )] ** 2 )
144
- alpha_power = np .sum (fft_data [(freqs >= 8 ) & (freqs <= 13 )] ** 2 )
145
- beta_power = np .sum (fft_data [(freqs >= 13 ) & (freqs <= 30 )] ** 2 )
146
- gamma_power = np .sum (fft_data [(freqs >= 30 ) & (freqs <= 45 )] ** 2 )
147
-
141
+ delta_power = math .sqrt (np .sum (((fft_data [(freqs >= 0.5 ) & (freqs <= 4 )])** 2 )/ 4 ))
142
+ theta_power = math .sqrt (np .sum (((fft_data [(freqs >= 4 ) & (freqs <= 8 )])** 2 )/ 5 ))
143
+ alpha_power = math .sqrt (np .sum (((fft_data [(freqs >= 8 ) & (freqs <= 13 )])** 2 )/ 6 ))
144
+ beta_power = math .sqrt (np .sum (((fft_data [(freqs >= 13 ) & (freqs <= 30 )])** 2 )/ 18 ))
145
+ gamma_power = math .sqrt (np .sum (((fft_data [(freqs >= 30 ) & (freqs <= 45 )])** 2 )/ 16 ))
146
+ print (f"Delta" , delta_power )
147
+ print (f"Theta" , theta_power )
148
+ print (f"Alpha" , alpha_power )
149
+ print (f"Beta" , beta_power )
150
+ print (f"Gamma" , gamma_power )
148
151
return [delta_power , theta_power , alpha_power , beta_power , gamma_power ]
149
152
150
153
if __name__ == "__main__" :
0 commit comments