Zapisz jako PDF

Transkrypt

Zapisz jako PDF
Pomiar Elektrookulogramu
Spis treści
1 Wstęp
1.1 Ćwiczenie I
1.2 Ćwiczenie II
1.3 Ćwiczenie III
1.4 Ćwiczenie IV
1.4.1 Napisz moduł:
1.4.2 Przetestuj moduł
Wstęp
Kolejnym narządem, w którym znajdują się generatory czynności bioelektrycznej jest oko. W
narządzie tym zachodzą skomplikowane procesy biochemiczne i elektryczne, umożliwiające
widzenie. Procesy te zostaną omówione na oddzielnym wykładzie, w tym miejscu zaś wymienimy
tylko te zjawiska, które mają wpływ na powstawanie w oku czynności elektrycznej.
1. Jednym z najważniejszych części oka jest siatkówka, której zadaniem jest odbieranie bodźców
świetlnych oraz zamiana ich na sygnały elektryczne, przekazywane dalej do kory wzrokowej. W
siatkówce płynie nieustannie prąd, którego natężenie zmienia się wraz z intensywnością
padającego na nią światła. Związane z tym sygnały bioelektryczne można rejestrować za
pomocą elektrod umieszczonych na powierzchni oka lub nawet za pomocą elektrod
umieszczonych na powierzchni skóry wokół oka. Tak zarejestrowany sygnał elektryczny,
powstały w oku w trakcie widzenia, nazywamy Elektroretinogramem (ERG). Sygnał ten ma
amplitudę od kilku nanowoltów do kilku μV i jest wykorzystywany w diagnostyce wielu chorób
siatkówki.
2. Rogówka (zewnętrzna warstwa oka znajdująca się w jego przedniej części) jest naładowana
dodatnio względem siatkówki umiejscowionej po przeciwnej stronie oka. Rogówka wraz z
siatkówką tworzą zatem w przybliżeniu układ dipola elektrycznego. W momencie ruchu okiem,
dipol ten zmienia orientację w przestrzeni, zaburzając rozkład natężenia pola elektrycznego.
Związany z tym sygnał o amplitudzie kilku miliwoltów można zmierzyć za pomocą elektrod
umieszczonych na skórze wokół oka. Widoczny jest ona także na elektrodach umieszczonych
na powierzchni głowy w trakcie pomiary czynności elektrycznej mózgu. Sygnał ten, czyli
elektryczny zapis ruchu gałek ocznych, nazywamy Elektrookulogramem (EOG). Czynność
elektryczną związaną z ruchem gałek ocznych obserwuje się również w trakcie mrugania,
kiedy to gałki oczne skręcają nieco ku górze (tzw. zjawiska Bella), a także w trakcie badań
diagnostycznych zaburzeń snu (w różnych etapach snu występują wolne lub szybkie ruchy
gałek ocznych).
Sygnał EOG można też wykorzystać do konstrukcji interfejsów [[1]].
1. Ruch oka sterowany jest za pomocą mięśni. W trakcie rejestracji Elektrookulogramu widoczne
będą również wyładowania elektryczne związane z działaniem mięśni.
Ćwiczenie I
Wykonaj pomiar Elektrokulogramu za pomocą dwóch par elektrod połączonych w montażu
dwubiegunowym.
Jedną parę elektrod umieść poniżej i powyżej oka, drugą w pobliżu lewej i prawej skroni.
Skonfiguruj program do rejestracji i przeglądania mierzonego sygnału w czasie rzeczywistym.
Wykonaj ruch oczami w górę i opisz zarejestrowany sygnał.
Wykonaj ruch oczami w dół i opisz zarejestrowany sygnał.
Wykonaj mrugnięcie i opisz zarejestrowany sygnał.
Przeczytaj fragment tekstu, zaobserwuj efekty związane z ruchem sakadowym oka.
Zarejestruj sygnały w wyżej wymienionych sytuacjach. Wyświetl te sygnały w programie napisanym
samodzielnie, bez stosowania filtra grórnoprzepustowego.
Ćwiczenie II
Powtórz ćwiczenie I, łącząc elektrody z monopolarnymi wejściami wzmacniacza, elektrodę
odniesienia umieść na lewym płatku uszu lub wyrostku sutkowatym.
Ćwiczenie III
Napisz program wyświetlający na macierzy 5x5 następujące sekwencje:
kwadrat środkowy - kwadrat górny - kwadrat środkowy
kwadrat środkowy - kwadrat prawy - kwadrat środkowy
kwadrat środkowy - kwadrat dolny - kwadrat środkowy
kwadrat środkowy - kwadrat lewy - kwadrat środkowy
Zapisuj do pliku tekstowego czasy i kody poszczególnych sekwencji.
Wyświetl te sygnały w programie napisanym samodzielnie, bez stosowania filtra
grórnoprzepustowego.
Zaprojektuj detektor, wykrywający, która sekwencja została wykonana.
Ćwiczenie IV
Zrealizuj prosty system do rejestracji ruchu gałki ocznej, tzw. Eye tracker. w tym celu:
Napisz moduł:
Korzystając detektora sekwencji napisanego w ramach ćwiczenia III napisz moduł
wykrywający sekwencje w czasie rzeczywistym. Niech Twój moduł wypisuje wynik detekcji na
konsolę. Opis korzystania i pisania modułów do systemu OBCI znajduje się [tutaj]. W
dużym skrócie to co należy zrobić to:
W katalogu domowym utwórz podkatalog:
~/obci/scenarios
w katalogu tym umieść plik:
eog.ini
powinien on zawierać następującą treść:
[peers]
scenario_dir=
;***********************************************
[peers.mx]
path=multiplexer-install/bin/mxcontrol
;***********************************************
[peers.config_server]
path=control/peer/config_server.py
;***********************************************
;***********************************************
[peers.amplifier]
path = drivers/eeg/cpp_amplifiers/amplifier_tmsi.py
;ponizsza sciezka pokazuje na plik zaierajacy nasze ustawienia parametrow
wzmacniacza
config=~/obci/scenarios/eog_local_params.ini
[peers.analysis]
path=~/obci/analysis/eog_realtime.py
config=~/obci/analysis/eog_realtime.ini
W powyższym pliku zadeklarowaliśmy, że lokalne parametry dla wzmacniacza znajduję się w
pliku:
~/obci/scenarios/eog_local_params.ini
zatem musimy ten plik wytworzyć i wypełnić go np. taką treścią:
[local_params]
channel_names=gora;dol;lewa;prawa
active_channels=0;1;2;3
sampling_rate=256
W pliku ze scenariuszem zadeklarowaliśmy też, że nasz moduł analizy danych znajduje się w
pliku:
~/obci/analysis/eog_realtime.py
tak więc musimy ten plik stworzyć i tam właśnie wpisać algorytm detekcji. Dla zachowania
konwencji w tym samym katalogu powinien znajdować się plik na ewentualne parametry dla modułu
eog_realtime.py. Musi on się nazywać tak samo, tyle, że ma rozszerzenie .ini. Musimy więc
wytworzyć pusty plik:
~/obci/analysis/eog_realtime.ini
Ponieważ nasz algorytm musi on się komunikować z resztą systemu obci trzeba go opakować w
poniższy kod-szkielet:
#!/usr/bin/env python
# -*- coding: utf-8 -*import random, time, numpy
from multiplexer.multiplexer_constants import peers, types
from obci.control.peer.configured_multiplexer_server import
ConfiguredMultiplexerServer
from obci.configs import settings, variables_pb2
from collections import deque
import obci.utils.openbci_logging as logger
#LOGGER = logger.get_logger("sample_analysis", "info")
LOGGER = logger.get_logger("sample_analysis", "debug")
class SampleAnalysis(ConfiguredMultiplexerServer):
"""A class responsible for handling signal message and making proper
decision.
The class inherits from generic class for convinience - all technical
stuff
is being done in this super-class"""
def __init__(self, addresses):
"""Initialization - super() and ready() calls are required..."""
super(SampleAnalysis, self).__init__(addresses=addresses,
type=peers.ANALYSIS)
self.ready()
LOGGER.info("Sample analysis init finished!")
def handle_message(self, mxmsg):
"""The only required function in the class
that will be fired every time message is received"""
if mxmsg.type == types.AMPLIFIER_SIGNAL_MESSAGE:
# Got proper message, let`s unpack it ...
# Messages are transmitted in bunches so lets define SampleVector
# in order to unpack bunch of Sample messages ...
l_vect = variables_pb2.SampleVector()
l_vect.ParseFromString(mxmsg.message)
# Now we have message unpacked, lets iterate over every sample
...
for s in l_vect.samples:
# Every sample has two fields:
# timestamp - system clock time of a moment of Sample`s
creation
# channels - a list of values - one for every channel
LOGGER.debug("Got sample with timestamp: "+str(s.timestamp))
# One can copy samples to numpy array ...
a = numpy.array(s.channels) # w tym miejscu mamy w tablicy a
"paczke" próbek (domyślnie 4próbki ) ze wszystkich zadeklarowanych kanalow
#################### TU TRZEBA WPISAC SWOJ KOD BUFOROWANIA i ANALIZY
##############
print a #na dobry poczatek wypiszmy probki
####################################################################
# Or just iterate over values ...
for ch in s.channels:
LOGGER.debug(ch)
# Having a new bunch of values one can fire some magic analysis
and
# generate decision ....
# Below we have quite simple decision-maker - it generates a
random
# decision every ~100 samples-bunch
########## TU NA PODSTAWIE ANALLIZY PODEJMUJEMY DECYZJE I MOZEMY JA PRZEKAZAC
DO RESZTY SYSTEMU OBCI ######################
########## W TYM PRZYKLADZIE JEST TO LOSOWA DECYZJA ##############
########## W TYM CWICZENIU WYSTARCZY JESLI WYPISZECIE DECYZJE NA EKRAN
###########
if random.random() > 0.99:
# Here we send DECISION message somewhere-to-the-system ...
# It's up to scenario's configuration how the decision will
be used ...
# Eg. it might be used by LOGIC module to push some button in
speller.
self.conn.send_message(message = str(random.randint(,7)),
type = types.DECISION_MESSAGE,
flush=True)
else:
LOGGER.warning("Got unrecognised message type: "+str(mxmsg.type))
# Tell the system 'I`ll not respond to this message, I`m just
receiving'
self.no_response()
if __name__ == "__main__":
# Initialize and run an object in order to have your analysis up and
running
SampleAnalysis(settings.MULTIPLEXER_ADDRESSES).loop()
Aby uruchomić nasz scenariusz trzeba wywołać:
obci launch ~/obci/scenarios/eog.ini
Zatrzymanie scenariusza robimy tak:
obci kill eog
W tym momencie komunikaty ze wszystkich modułów wypisywane są na jednej konsoli. Przydatne
jest korzystanie z obiektu 'LOGGER' zamiast funkcji 'print' - w konsoli mamy informację o źródle
komunikatu i jego czasie.
OpenBCI działa tak, że jeśli w jednym module pojawi się błąd, to wszystkie inne moduły są
zamykane, stąd komunikat podobny do poniższego sugeruje, że w którymś module wystąpił błąd. W
takim wypadku należy przejrzeć konsolę i wyszukać komunikat błędu. Niezbędne jest ustawienie
bufora konsoli na 'nieograniczony' wykonując: Edycja->Preferencje
profilu->Przewijanie->Nieograniczone .
Przetestuj moduł
Umieść elektrody do rejestracji ruchu gałki ocznej jak w ćwiczeniu I i przetestuj działanie
modułu. Miłej zabawy :-)

Podobne dokumenty