AKADEMIA GÓRNICZO-HUTNICZA im. St. Staszica w Krakowie WEAIiE, Katedra Automatyki Laboratorium Biocybernetyki Przedmiot: Przetwarzanie sygnałów w systemach diagnostyki medycznej Temat: Detekcja i synchronizacja reprezentacji uderzeń serca (zespół QRS) QRS_DET Wykonali: Sławomir Goszcz, Kamil Kokoć V rok IS konsultant: dr hab. inż. Piotr Augustyniak Spis treści 1 Abstrakt...2 2 Wstęp...3 2.1 Cele i założenia projektu...3 2.2 Zarys proponowanego rozwiązania...7 2.3 Dyskusja alternatywnych rozwiązań...8 3 Koncepcja proponowanego rozwiązania...8 3.1 Wstęp...8 3.2 Opis Faz działania algorytmu...8 Wstępne przetwarzanie sygnału...9 1. Filtracja dolnoprzepustowa...9 2. Filtracja górnoprzepustowa...10 3. Pochodna sygnału...11 4. Podniesienie sygnału do kwadratu...12 5. Okno czasowe...12 Wykrywanie pików...13 1. Utrudnienia w wykryciu sygnału...14 Znak zaufania...15 Reguły decyzyjne...16 3.3 Nasze modyfikacje algorytmu...16 Filtry...16 Wzór na pochodną...17 Detekcja załamków S...17 Detekcja załamków Q...17 Detekcja długości zespołu...17 Synchronizacja...18 4 Rezultaty i wnioski...18 4.1 Sygnał nr 1...18 4.2 Sygnał nr 2...22 4.3 Sygnał nr 3...23 4.4 Podsumowanie...24 5 Podsumowanie...24 6 Literatura...24 7 DODATEK A: Opis opracowanych narzędzi i metody postępowania...25 7.1 Instalacja...25 7.2 Opis warunków w których program był testowany...25
8 DODATEK B: Realizacja proponowanego rozwiązania...25 8.1 Wymagania sprzętowe...25 8.2 Opis funkcyjny programu...25 9 DODATEK C. Spis zawartości dołączonych nośników...27
1 Abstrakt Algorytmy detekcji zespołu QRS są dziś bardzo powszechnie stosowane w diagnostyce medycznej. Problemy związane z detekcją załamka są dość dobrze zdefiniowane i opisane, korzystając z tej wiedzy nasz projekt ma za zadanie stworzenie prostego narzędzia, które pozwala na odczyt danych z plików WFDB znajdujących się w bazie MIT- BIH zawierających zapis sygnałów ECG oraz detekcje załamków QRS z użyciem algorytmu zaprezentowanego przez Panów Hamiltona i Tompkinsa a następnie zapis położenia odnalezionych zespołów QRS w pliku tekstowym. Metoda Hamiltona i Tompkinsa została zaprezentowana przez nich w roku 1986 w pracy Quantitative Investigation of QRS Detection Rules Using the MIT/BIH Arrhythmia Database jest stosunkowo dobrze działającą acz już powoli odchodzącą do lamusa metodą detekcji QRS.
2 Wstęp Jak już wspomnieliśmy problem detekcji zespołu QRS jest dość dobrze zdefiniowanym i opisanym problemem. Tworząc naszą aplikację musieliśmy wybrać spośród kilku metod detekcji reprezentacji uderzeń serca w badaniu ECG. W poniższych podrozdziałach zaprezentowaliśmy cechy jakie nasz projekt będzie posiadał. Należy zaznaczyć bardzo ważną kwestię, która miała kiedyś jak i dziś duże znaczenie: do tej pory nie stworzono perfekcyjnego działającego w czasie rzeczywistym algorytmu detekcji zespołu QRS. My mamy łatwiejsze zadanie ponieważ badamy sygnał już zapisany i utrwalony w postaci plików komputerowych. Pomimo stosowanych w praktyce systemów rozpoznających fale elektrokardiograficzne czy też arytmie serca, detekcja zespołu QRS nadal jest przedmiotem badań wielu naukowców. Powodem takiej sytuacji, oprócz złożoności sygnału i różnorodności morfologicznej załamków EKG, są pojawiające się liczne szumy i artefakty, które znacznie utrudniają analizę sygnału. Wskazane powyżej względy narzucają również bardzo surowe wymagania wobec tych algorytmów. Dlatego też musi je cechować nie tylko duża szybkość, ale także doskonała (prawie stuprocentowa) dokładność, efektywność oraz wydajność. Algorytmy detekcji zespołu QRS są bowiem punktem wyjściowym w całej analizie sygnału elektrokardiograficznego. Ich dokładność wpływa znacząco na jakość działania całego systemu analizującego sygnał EKG. 2.1 Cele i założenia projektu Celem naszego projektu jest stworzenie aplikacji w języku C++ posiadającej następujące funkcjonalności: Odczyt danych z pliku WFDB zawierającego informacje o zapisie ECG. Dokonanie wstępnej filtracji sygnału. Detekcja zespołów QRS. Zapis informacji o odnalezionych załamkach do odpowiedniej struktury. Do stworzenia aplikacji postanowiliśmy wykorzystać język C++ ze względu na jego duże możliwości w tym zakresie jak również możliwość prostszego wykonywania pewnych operacji (np. odczyt/zapis do pliku) niż w przypadku języka ANSI-C. Dzięki możliwości stosowania klas w C++ nasz program jest uporządkowany i istnieje możliwość wyodrębniania poszczególnych modułów do innych celów np. modułu odczytu z plików WFDB. Założyliśmy również, że środowiskiem programistycznym w jakim powstanie nasza aplikacja będzie MS Visual Studio 2005 Express Edition darmowe środowisko dostarczane przez firmę Microsoft, wybraliśmy je ze względu na duże ułatwienia jakie oferuje programistom w kodowaniu i budowaniu aplikacji. Nie bez znaczenia jest także fakt, że produkt Microsoft'u posiada bardzo dobrą dokumentację, która była nam bardzo pomocna w tworzeniu projektu. Zastosowanie tego rozwiązania wymusza stosowanie systemu operacyjnego Windows, który jest obecnie obecny w większości dostępnych komputerów. Nasz wybór kierowany jest też chęcią skorzystania z rozwiązania stabilnego, które jest z powodzeniem stosowane nie tylko w środowiskach open source.
Dodatkowo taki wybór kompilatora umożliwia nam przenośność aplikacji, ponieważ system Windows dostępny jest też w dzisiejszych czasach na platformach mobilnych. Przechodząc do meritum naszego zadania czyli samej detekcji zespołu QRS należy wyjaśnić czym jest zespół QRS. Trzy sąsiadujące ze sobą punkty elektrokardiogramu, które tworzą wychylenie w kształcie wąskiego impulsu określa się jako zespół QRS, gdzie: Załamek Q - pierwsze ujemne wychylenie elektrokardiogramu Załamek R - pierwsze dodatnie wychylenie elektrokardiogramu Załamek S - ostatnie ujemne wychylenie elektrokardiogramu w zespole Odzwierciedla elektryczną aktywność serca podczas skurczu komorowego. Reprezentuje pobudzenie, czyli depolaryzację komór. Jego ukształtowanie zależy od odprowadzenia i już w prawidłowych warunkach ulega znacznym wahaniom, które wiążą się z powyżej wymienionymi właściwościami sygnału (z położeniem serca i skręcaniem dookoła jego osi). Zespół QRS charakteryzuje się najwyższym wychyleniem i najkrótszym czasem trwania, co sprawia, że posiada on szerokie widmo częstotliwościowe. Charakterystyczny kształt tego zespołu oraz czas jego pojawiania się dostarcza najwięcej informacji diagnostycznych o bieżącym stanie serca i dlatego też jest punktem wyjściowym do klasyfikacji schematu cyklu sercowego. Służy też jako podstawa do automatycznego określania rytmu. Wykrycie zespołu QRS dostarcza podstawowych zasad i informacji dla prawie wszystkich automatycznych algorytmów analizy EKG. Czas trwania i wysokość zespołu QRS zależy od wielu czynników. Przyjmuje się jednak, iż dla osoby dorosłej i zdrowej średni czas trwania powinien obejmować 7 18 mm, zaś wysokość 0,7 1,8 mv. Natomiast czas szerzenia się depolaryzacji komór nie powinien przekroczyć 90 ms (jest zależny od częstości rytmu serca)
Zespół QRS poniżej widoczny na rysunku oznaczony jako QRS Complex: Rys.1. Schematyczna reprezentacja ECG Jak widać zespół QRS jest kluczowym elementem wymaganym w trafnej diagnostyce chorób serca. Algorytmy detekcji i klasyfikacji zespołu QRS to dosyć szeroka dziedzina wiedzy i jak do tej pory stały się przedmiotem badań wielu autorów. Najbardziej ogólna klasyfikacja to podział tych algorytmów na trzy duże grupy algorytmów opartych o: sztuczne sieci neuronowe, pochodne sygnału, przekształcenia falkowe. Ciekawy podział w swojej pracy doktorskiej prezentuje dr inż. Agnieszka Duraj:
1. algorytmy działające w dziedzinie czasu (ang. algorithms based on time domain), 2. algorytmy działające w dziedzinie częstotliwości (ang. algorithms based on frequency domain), 3. algorytmy działające w dziedzinie czasowo częstotliwościowej (ang. algorithms based on time and frequency domain), 4. algorytmy opierające się na sztucznej inteligencji: a) sieci neuronowe (ang. algorithms based on neural network models), b) klasyfikatory maksymalnoodległościowe (ang. support vector machine), c) algorytmy genetyczne (ang. genetic algotithms), 5. i inne rozwiązania algorytmiczne. Obecnie stosowane są trzy główne metody detekcji załamków: Metoda Transformaty Długościowej(LT) Metoda Hamiltona i Tompkinsa Metoda Dyskretnej Transformaty Falkowej (DWT) Najnowszą i jednocześnie najlepszą metodą jest metoda korzystająca z Dyskretnej Transformaty Falkowej, pozwala ona na przedstawienie sygnału zarówno w dziedzinie częstotliwości jak i czasu, jednocześnie taka reprezentacja pozwala na rozłożenie sygnału na składowe o różnej rozdzielczości co pozwala na bardzo szczegółowe badanie sygnału. Drugą znaną metodą jest metoda Transformaty Długościowej (DT) zaproponowana w pracy A comparison of the length and energy transformations for the QRS detection [1], metoda ta działa według schematu: Przeprowadzenie filtracji (zmniejszane są min. załamki P i T oraz wycinane szumy). Wartości poszczególnych próbek są podnoszone do kwadratu aby usunąć ujemne i uwydatnić małe wartości. Sygnał jest wygładzany za pomocą 4 sekundowego okna uśredniającego. W decyzyjnej części algorytmu wykorzystywana jest adaptacyjna funkcja progowa, która odnajduje w sygnale wygładzonym załamki QRS. Ze względu na wykorzystanie metody progowej, aby nie nastąpiło błędne wykrycie szumów jako załamków QRS oraz nie nastąpiło rozdzielenie poszczególnych zespołów QRS na kilka stosuje się morfologiczne metody otwarcia i zamknięcia do uniknięcia tego typu błędów. Metoda ta daje dość dobrą skuteczność przy stosunkowo niewielkiej wymaganej mocy obliczeniowej. Zastosowaną przez nas metodą jest metoda Hamiltona i Tompkinsa, wybrana została przez nas głównie z powodu dość dużej dostępności materiałów na jej temat (udało nam się skorzystać ze źródła jakim jest praca samych autorów metody w której w szczegółowy sposób opisują jej działanie), a także jej spora dokładność. Nie bez znaczenia jest też problem rejestracji sygnałów, które to związane są z dyskretną
reprezentacją sygnału elektrokardiograficznego. Na pewno inaczej postępowalibyśmy w przypadku ciągłej reprezentacji sygnału. Próbkowanie związane jest ograniczeniem pasma częstotliwościowego od góry, czyli zmianą ciągłej funkcji sygnału analogowego w funkcję istniejącą tylko w chwili próbkowania. Wynika to bezpośrednio z twierdzenia Shannona, które mówi, że częstotliwość próbkowania musi być co najmniej dwa razy większa od częstotliwości najwyższej składowej fourierowskiej wchodzącej w skład próbkowanego sygnału ciągłego. Na nasze potrzeby użyliśmy bazy danych MIT/BIH, które przechowują poprawne dane, a co za tym idzie i poprawnie zdefiniowany sygnał. 2.2 Zarys proponowanego rozwiązania Metoda stworzona w roku 1986 roku przez Panów Patricka S. Hamiltona i Willisa J. Tompkinsa z Uniwersytetu w Pensylwanii stosowana jest z powodzeniem do dziś w urządzeniach oraz aplikacjach analizujących sygnały ECG. Schemat działania metody jest dosyć prosty: Filtracja wstępna na którą składają się: Użycie filtru dolnoprzepustowego Użycie filtru górnoprzepustowego (otrzymany zostaje sygnał y[n]) Spochodnienie sygnału po czasie Podniesienie sygnału do kwadratu Dokonanie wygładzenia sygnału poprzez 32 próbkowe uśredniające okno czasowe.( otrzymany zostaje sygnał z[n]) Wykrywane są piki w sygnale z[n] za pomocą funkcji progu dostosowanej do maksymalnej wartości sygnału, dodatkowo wykorzystywane są specjalne algorytmy wykorzystujące sprawdzanie odległości pomiędzy poszczególnymi pikami na usunięcie fałszywych wykryć zespołów QRS. Określanie tzw. (punktów zaufania) fiducial marks w sygnale y[n] określające położenie załamków QRS. Wykorzystywane są dodatkowe algorytmy optymalizujące proces wykrywania załamków QRS i usuwające fałszywe wykrycia zespołów. Metoda Tompkinsa i Hamiltona jest stosunkowo dokładna i daje dobre wyniki wykrywalności załamków - niektóre źródła podają, że nawet na poziomie 99%. W pracach naukowych algorytm Hamiltona oraz Tompkinsa jest bardzo często cytowany, a do tej pory bardzo często podejmowane są próby wprowadzenia drobnych jego modyfikacji, które mogą choć w nieznaczny sposób podnieść jakość zaproponowanego przez nich rozwiązania. 2.3 Dyskusja alternatywnych rozwiązań Alternatywne rozwiązania dla naszego projektu to przede wszystkim skorzystanie z pozostałych metod dostępnych w literaturze, czyli metody Dyskretnej Transformaty Falkowej bądź Transformaty Długościowej. Transformata Długościowa nie została przez nas wykorzystana ze względu na brak
dostępu do fachowych źródeł z nią związanych, mieliśmy dostęp jedynie do pobieżnych informacji na temat sposobu w jaki algorytm LT działa bez szczegółów które pozwoliłyby na implementację metody. Dyskretna Transformata Falkowa nie została przez nas wykorzystana głównie przez fakt, że metodą tą zajęła się druga grupa wykonująca również projekt QRS_DET i chcieliśmy w ten sposób nie powielać, a urozmaicić nasze reprezentacje rozwiązania powierzonego nam zadania. Podczas naszych intensywnych poszukiwań natknęliśmy się na zupełnie inne rozwiązanie algorytmiczne i podejście do problemu. Do detekcji i analizy zespołów QRS zostały użyte ukryte modele Markowa (ang. Markov hidden models), które w literaturze informatycznej występują pod nazwą probabilistycznych automatów z wyjściem. Okazały się one bardzo dużym sukcesem w badaniach, ale dalej są słabo opisane. Metoda ta polega na wykryciu sekwencji danych poprzez zastosowanie funkcji prawdopodobieństwa. Parametry funkcji odpowiadają za różne właściwości statystyczne obserwowanych danych. Dzięki temu może być wyznaczony nie tylko zespół QRS, ale również fale P i T. Niestety przy stosowaniu tej metody należy przeprowadzić ręczną segmentację i wykonać szereg prób przed analizą zapisu, co nie jest proste w przypadku sygnałów elektrokardiograficznych. 3 Koncepcja proponowanego rozwiązania 3.1 Wstęp Metoda Tompkinsa i Hamlitona została przez nas wybrana głównie ze względu na chęć wykorzystania alternatywnego rozwiązania problemu detekcji załamków QRS. Wiemy, że grupa równolegle tworząca podobny projekt wykorzystała metodę Dyskretnej Transformaty Falkowej, ze względu na ten fakt chcieliśmy skonfrontować wyniki działania obydwu metod. Algorytm Tompkinsa i Hamiltona jest dość dobrze udokumentowany przez co jego implementacja nie była trudna. 3.2 Opis Faz działania algorytmu W poniższym rozdziale opiszemy krok po kroku zasadę działania algorytmu stworzonego przez Panów Tompkinsa i Hamiltona. Każdy algorytm detekcji załamków QRS można podzielić na dwa etapy: 1. Etap preprocessingu, w czasie którego wykonywane jest liniowe i nieliniowe filtrowanie sygnału 2. Etap decyzyjny, w którym dokonywana jest detekcja załamków QRS na podstawie przefiltrowanego wcześniej sygnału Nie inaczej jest z naszym algorytmem. Poniżej znajduje się dokładny opis zastosowanych narzędzi i przekształceń sygnału, które w wyniku dają wektor wynikowy zawierający informacje o wykrytych załamkach QRS. Wstępne przetwarzanie sygnału Etapy wstępnego przetwarzania sygnału ukazuje poniższy rysunek:
rys. 1. Proces wstępnego przetwarzania sygnału W omówieniu procesu filtracji wstępnej będziemy się posługiwać przykładem następującego sygnału ECG pobranego ze strony physionet.org: rys.2. Sygnał wejściowy ECG 1 Filtracja dolnoprzepustowa Jak widać sygnał jest filtrowany na samym początku za pomocą filtra dolnoprzepustowego którego równanie różnicowe ma postać: y nt =2y nt T y nt 2T x nt 2x nt 6T x nt 12T T - okres próbkowania, n - numer próbki, x(n) sygnał wejściowy. Dla potrzeb naszego projektu wystarczy nam jedynie indeksowanie za pomocą numerów próbek, z pominięciem okresu próbkowania: y nt =2y n 1 y n 2 x n 2x n 6 x n 12 Opóźnienie filtra wynosi 12 próbek, filtr pozwala na usunięcie częstotliwości powyżej 11 Hz. Pozwoliło to nam na wstępne usunięcie szumu z sygnału ECG. W wyniku działania filtra dolnoprzepustowego otrzymaliśmy następujący sygnał wyjściowy:
rys.3. Sygnał po filtracji filtrem dolnoprzepustowym 2 Filtracja górnoprzepustowa Następnie wykorzystany zostaje filtr górnoprzepustowy z następującym równaniem różnicowym: x nt 32T y nt = y nt T x nt /32 x nt 16T x nt 17T 32 T - okres próbkowania, n - numer próbki, x(n) sygnał przefiltrowany filtrem dolnoprzepustowym. Jak wyżej w naszym projekcie zastosowaliśmy indeksowanie jedynie numerem próbki: y nt = y n 1 x n /32 x n 16 x n 17 x n 32 32 W wyniku działania filtra górnoprzepustowego otrzymaliśmy następujący sygnał:
3 Pochodna sygnału rys.4. Sygnał po filtracji filtrem górnoprzepustowym Po wstępnym przefiltrowaniu filtrami górno i dolnoprzepustowymi otrzymujemy wyjściowy sygnał y(n), który będzie wykorzystany w procesie wykrywania załamków QRS. Następnie otrzymujemy pochodną sygnału, wykorzystane zostaje do tego następujące równanie różnicowe: 2x nt x nt T x n 3T 2x nt 4T y nt = 8 T - okres próbkowania, n - numer próbki, x(n) sygnał przefiltrowany filtrem górnoprzepustowym. Jako wynik otrzymaliśmy sygnał będący pochodną sygnału wejściowego: rys.5. Pochodna sygnału przefiltrowanego
4 Podniesienie sygnału do kwadratu Każda z próbek sygnału jest następnie podnoszona do kwadratu aby usunąć wartości ujemne sygnału i uwydatnić jego wartości: y nt =[ x nt ] 2 Otrzymany wynikowy sygnał reprezentuje poniższy rysunek: rys.6. Kwadrat pochodnej sygnału 5 Okno czasowe Po podniesieniu do kwadratu sygnał zostaje poddany obróbce za pomocą okna czasowego, długość okna podana przez autorów algorytmu to 32 próbki - niestety jest to ilość niewystarczająca w naszym algorytmie ze względu na fakt, że autorzy dokumentu[1] pracowali na sygnałach o częstotliwości próbkowania 200 Hz, natomiast obecnie na stronie physionet.org dostępne sygnały posiadają częstotliwość 720 Hz. Ustalona przez nas długość okna to 216 próbek - okazała się ona wystarczająca: nt y nt = 1 216 x=nt 216T Wygładza to sygnał i na wyjściu otrzymujemy już całkowicie przetworzony sygnał z(n): x
rys. 7. Sygnał po przejściu uśredniającego okna czasowego W wyniku działania preprocessingu otrzymujemy cztery różne sygnały: sygnał wejściowy pierwotny sygnał ECG x(n) pierwsza pochodna sygnału wejściowego y(n) sygnał po wstępnej filtracji z(n) sygnał y(n) podniesiony do kwadratu i wygładzony oknem czasowym Posiadając taki zestaw danych możemy przejść do następnego etapu czyli wykrywania pików. Wykrywanie pików Aby skutecznie wykryć załamki QRS wymagane jest wykrywanie pików w przetworzonym sygnale z(n). Typowy przykład uzyskanej w procesie preprocessingu struktury symbolizującej załamek QRS w sygnale z(n) ukazuje poniższy rysunek:
Przybliżone położenie piku R Początek załamka QRS Nieprawidłowy pik, który nie może zostać wykryty rys.8. Struktura reprezentująca załamek QRS w sygnale z(n) Zgodnie z opisem umieszczonym przez Panów Hamiltona i Tompkinsa, na podstawie tej struktury jesteśmy w stanie określić dokładne położenie poszczególnych elementów załamka QRS: Długość zbocza rosnącego odpowiada za długość załamka QRS. Widoczny punkt przegięcia na zboczu rosnącym pokazuje położenie piku R w sygnale 1 Utrudnienia w wykryciu sygnału Niestety wykrycie sygnału nie jest możliwe za pomocą prostego algorytmu wykrywającego lokalne maksima - wynika to z faktu, że typowe algorytmy detekcji pików wykrywają fałszywie dwa piki (widoczne w strukturze) przez co załamek QRS zostaje nieprawidłowo rozpoznany. Hamilton i Tompkins opracowali specjalny algorytm, który eliminuje wykrywanie nieprawidłowych pików jako należących do załamka QRS. W tym przypadku algorytm wykrywa piki w sygnale z(n). Zasada działania algorytmu jest dość prosta: 1. Algorytm detekcji przechowuje maksymalne wartości uzyskane w sygnale po wykryciu ostatniego piku. 2. Wykrycie nowego piku jest możliwe w momencie kiedy sygnał osiągnie wartości mniejsze od maksymalnej wartości wykrytej od momentu wykrycia poprzedniego piku lub wartości piku. Jak widać detekcja jest możliwa dopiero po osiągnięciu przez sygnał połowy zbocza opadającego przez co wyeliminowany zostaje fałszywy pik. Kolejnym problemem są sygnały ECG posiadające wyeksponowany załamek T przyjmujący duże wartości i mogący spowodować opóźnienie w wykryciu kolejnego załamka QRS (z powodu swojej wysokiej wartości nie będzie spełniony opisany powyżej warunek nr 2). Aby usunąć to opóźnienie odblokowane zostaje wykrycie załamka QRS w momencie kiedy upłynie 175 ms (125 próbek) od pojawienia się ostatniego dodatniego zbocza w sygnale z(n).
Jako wynik napisanej przez nas metody otrzymaliśmy następujący wektor: rys.9.detekcja pików w sygnale z(n) Znak zaufania Poprzedni podrozdział pokazał w jaki sposób wykrywany jest pik w sygnale z(n). Następnym elementem, który należy wykryć w sygnale z(n) jest pik R. Jak pokazuje rysunek nr 2 pik R znajduje się w połowie zbocza rosnącego w sygnale z(n). Aby dokładniej określić położenie piku R wykorzystywany jest sygnał y(n) wstępnie przefiltrowany przez filtry dolno i górnoprzepustowy. W sygnale y(n) oznaczany jest tzw. znak zaufania - określa on położenie najwyższego piku w odległości 225 to 125 ms od wykrytego piku w sygnale z(n). Dzięki wykryciu punktów zaufania właściwie udało nam się odnaleźć piki R sygnału.
Rys.10. Wykrycie znaków zaufania - załamków R Ostatecznie diagram kolejnych faz algorytmu wygląda następująco: rys. 3. Diagram algorytmu Reguły decyzyjne W wyniku detekcji pików oraz stworzenia wektora znaków zaufania jesteśmy w stanie stworzyć zaproponowany przez autorów algorytmu wektor zdarzeń zawierający następującą strukturę: x położenie piku w sygnale z(n) y położenie znaku zaufania dla powyższego piku Dzięki takiemu wektorowi jesteśmy w stanie określić które z pików są załamkami QRS a które są wynikiem powstałych w sygnale szumów. W tym celu posłużyliśmy się metodą progowania, która usuwa piki mniejsze niż 5% maksymalnej wartości piku. Metoda ta sprawdziła się dla testowanych sygnałów.
3.3 Nasze modyfikacje algorytmu Ze względu na fakt, że dokument Quantitive Investigation of QRS Detection Rules Using MIT/BIH Arrhythmia Database został wydany w 1986 roku, część metod zastosowanych przez Panów Tompkinsa i Hamiltona jest już w dzisiejszych czasach delikatnie mówiąc przestarzała. Postanowiliśmy zmienić kilka rzeczy w ich algorytmie tak aby był wygodniejszy do stosowania dziś. Filtry Staraliśmy się zastosować opisane powyżej filtry dolno i górnoprzepustowe do naszego algorytmu, jednak ze względu na fakt, że są to filtry o nieskończonej odpowiedzi impulsowej co czyni je niestabilnymi z powodu zastosowania sprzężenia zwrotnego postanowiliśmy wykorzystać filtry o skończonej odpowiedzi impulsowej. W momencie powstawania artykułu [1], komputery miały relatywnie małą moc obliczeniową i stosowanie filtrów IIR było podyktowane ich mniejszą złożonością obliczeniową oraz mniejszym zapotrzebowaniem na pamięć. W dzisiejszych czasach filtry FIR są częściej stosowane ze względu na swoje zalety: Implementacja filtrów FIR może być łatwo zrównoleglona, a niektóre procesory wręcz wspomagają operacje sumy iloczynów, pozwalając obliczać wynik filtracji w znikomej liczbie cykli zegara Projektowanie filtrów FIR jest znacznie łatwiejsze niż filtrów IIR Filtry FIR są zawsze stabilne, gdyż w ich funkcji transmitancji występują tylko zera, a nie ma rekursywności mogącej spowodować niestabilność W wielu zastosowaniach (przetwarzanie bieżącego sygnału w blokach, przetwarzanie obrazów) skończona odpowiedź impulsowa jest bardzo pożądana Wzór na pochodną Wykorzystaliśmy w projekcie prostszą metodę obliczania zmiennej sygnału dyskretnego wykorzystującą wzór: y[n]=x[n] x[n 1] Empirycznie sprawdziliśmy, że działa równie dobrze w naszym projekcie. Detekcja załamków S Byliśmy zmuszenie zaimplementować własną metodę odnajdywania załamków S ze względu na fakt, że metoda Panów Tompkinsa i Hamiltona nie uwzględnia takich szczegółów. Nasza metoda opiera się na prostym algorytmie: Przesuwając się w przód od wykrytych w sygnale z(n) pików o maksymalnie 140 ms znajdujemy minimalną wartość sygnału y(n). Metoda daje doświadczalnie dość dobre rezultaty choć nie jest idealna. Detekcja załamków Q Detekcja załamka Q przebiegła w podobny sposób co detekcja załamka S. Postępowaliśmy zgodnie z następującym algorytmem:
Biorąc pod uwagę kolejne wykryte w wektorze y(n) punkty zaufania szukaliśmy minimum lokalnego w odległości 200 ms do tyłu od danego piku. W rozdziale czwartym omówiona zostanie szerzej skuteczność tej metody. Detekcja długości zespołu Długość załamka jest przez nas wykrywana na podstawie punktów charakterystycznych w sąsiedztwie pików w sygnale z(n). Poniższy rysunek ukazuje sposób w który wykrywamy koniec i początek zespołu QRS: Wykryty PIK Zakończenie zespołu QRS Początek zespołu QRS Postanowiliśmy korzystając ze zdefiniowanych pików przeszukać ich otoczenie i znaleźć pierwszy punkt, którego wartość jest mniejsza niż połowa wartości piku jest to przybliżone zakończenie zespołu QRS. Początek zespołu jest przez nas wykrywany poprzez znalezienie minimum w odległości 216 próbek na lewo od piku. W wyniku działania naszego algorytmu otrzymaliśmy następujące rezultaty: Synchronizacja Synchronizacja sygnału jest dokonywana na podstawie wykrytych pików w sygnale z(n). Algorytm znajduje w sygnałach podobne piki i ustala średnią odległość pików od siebie a następnie ustalane jest przesunięcie sygnałów względem siebie tak aby możliwe było pokrycie się jak największej ilości pików. 4 Rezultaty i wnioski Poniższe rysunki obrazują możliwości jakie daje algorytm przez nas zaimplementowany. Wykonaliśmy próbę na 3 sygnałach dostępnych na stronie physionet.org. Postanowiliśmy każdy z obrazów omówić osobno i wymienić wady i zalety naszego algorytmu. 4.1 Sygnał nr 1 Sygnał nieprzetworzony ma postać:
Widać, że niektóre zespoły QRS znacząco różnią się od pozostałych, dodatkowo występuje tutaj problem nieuwydatnionych załamków Q. Wstępne przetworzenie sygnału przekształciło go w w następujący sposób: 1. Sygnał y(n): 2. Sygnał z(n):
Jak widać struktury odpowiadające za wykrycie zespołów QRS są dobrze oznaczone. Kolejny etap to wykrycie pików: Jak widać piki nie zostały dobrze wykryte, pojawiły się dwa dodatkowe piki, które wynikają z faktu, że sygnał ECG nie posiada uwydatnionych załamków S. Wykrycie załamków Q,R i S: Wykryto pięć prawidłowych załamków QRS, nieprawidłowe wykrycia wynikają z powodu pojawienia się fałszywych pików w sygnale z(n). Możliwe jest usunięcie takich fałszywych pików np. przez zastosowanie specjalnego algorytmu, który sprawdza, czy zespoły QRS nie nachodzą na siebie i łączyć w jedno zespoły nachodzące na siebie. 4.2 Sygnał nr 2 Sygnał nieprzetworzony ma postać:
Wśród zespołów o dużych załamkach R połączonych z jednocześnie bardzo uwydatnionymi załamkami Q występują niewielkie zespoły QRS, ewidentnie widać że w pracy serca pacjenta występują nieprawidłowości. Aby oszczędzić zbędnych szczegółów umieściliśmy wykres wykrytych załamków Q,R i S: Jak widać jedynie cztery zespoły zostały wykryte prawidłowo. Należy jednak zwrócić uwagę, że nieprawidłowe wykrycie nastąpiło dla załamków Q, załamki R i S zostały wykryte prawidłowo. Nieprawidłowe wykrycie załamka Q jest spowodowane zbyt małym czasem wyszukiwania minimum za załamkiem R. 4.3 Sygnał nr 3 Sygnał nieprzetworzony ma postać:
Wykrycie załamków: Podobnie jak w sygnale nr 2 wystąpił problem zbyt krótkiego czasu poszukiwania wstecz załamka Q, Pozostałe załamki zostały dobrze wykryte. 4.4 Podsumowanie Nasz algorytm dość dobrze radzi sobie z różnego rodzaju sygnałami ECG. Jednak empiryczne ustalenie np. czasu poszukiwania Q wstecz mogłoby w wielu przypadkach dać lepsze wyniki.
5 Podsumowanie Praca z algorytmem stworzonym przez Panów Tompkinsa i Hamiltona była dla nas bardzo pouczająca, dodatkowo mogliśmy wykazać się inwencją i zmodyfikować ich metodę wykrycia zespołów QRS, tak by była możliwość wykrycia również położenia poszczególnych elementów zespołu i jego długości. Stopień realizacji celów projektu możemy określić jako w miarę pełny. Metody nie są doskonałe i kolejne grupy pracujące nad naszym algorytmem mają możliwość ulepszenia jego działania. Proponujemy również zapoznanie się z raportem grupy, która równolegle tworzyła algorytm detekcji zespołów QRS z wykorzystaniem stosunkowo nowej metody Transformaty Falkowej - możliwe że ich metoda jest wydajniejsza i pozwala z lepszym przybliżeniem określać położenia załamków. 6 Literatura [1] Patrick S. Hamilton, Willis J. Tompkins, Quantitive Investigation of QRS Detection Rules Using the MIT/BIH Arrythmia Database, IEEE Transactions on biomedical Engineering, Vol. BME-33, No. 12 December 1986 7 DODATEK A: Opis opracowanych narzędzi i metody postępowania Program został przez nas napisany w języku C++ z wykorzystaniem biblioteki standardowej. Dzięki temu jest możliwe odpalenie go zarówno pod systemem Windows jak i systemami Uniksowymi (np. Linux). 7.1 Instalacja Aby możliwe było uruchomienie programu wymagane jest pobranie aplikacji wfdb dostępnej na stronie: http://www.physionet.org/physiotools/wfdb.shtml#sources oraz instalacja jej na podstawie poniższych instrukcji: Linux - http://www.physionet.org/physiotools/wfdb-linux-quick-start.shtml Windows - http://www.physionet.org/physiotools/wfdb-windows-quick-start.shtml Biblioteka jest wykorzystywana jedynie do odczytu informacji o sygnale z plików DAT i HEA - żadne z jej elementów nie zostały wykorzystane w naszym algorytmie detekcji zespołów QRS. Instalacja jest bardzo prosta: należy rozpakować plik qrs_det.zip za pomocą archiwizatora danych a następnie wybrać odpowiedni dla swojego systemu katalog np. windows. W nim znajduje się plik wykonywalny qrs_det, który należy uruchomić z odpowiednimi parametrami opisanymi poniżej: 7.2 Opis warunków w których program był testowany Program był testowany zarówno w systemie Windows jak i Linux, jednak zaleca się korzystanie z systemu Linux ze względu na większą liczbę testów przeprowadzonych właśnie na nim.
8 DODATEK B: Realizacja proponowanego rozwiązania 8.1 Wymagania sprzętowe Minimalna konfiguracja na której testowana była nasza aplikacja to: Procesor AMD Turion 1,6 GHz ( 2 rdzenie) Pamięć operacyjna Przestrzeń dyskowa 1 GB Min. 100 MB Oczywiście nie wykluczamy możliwości odpalenia aplikacji na słabszej konfiguracji sprzętowej, niestety ze względu na brak dostępu do sprzętu nie mieliśmy możliwości testów na takowej. 8.2 Opis funkcyjny programu Rozdział poniższy zawiera opis poszczególnych metod i klas wykorzystywanych przez naszą aplikację: 1. RDSAMPWrapper klasa zapewnia metody pozwalające na odczyt informacji z plików HEA i DAT. OpenHeaFile(string file_name) otwiera i odczytuje informacje z pliku HEA na temat sygnału. Open(string file_name) metoda otwiera i odczytuje dane z pliku DAT i zapisuje próbki w pliku tekstowym, z którego są one następnie sczytywane przez program. 2. SignalFileProcessor klasa dostarcza metod operujących na plikach tekstowych wykorzystywanych bezpośrednio przez program Open(string file_name) otwarcie i odczyt z pliku tekstowego sygnału, który następnie zostanie wykorzystany w programie. Read() - Metoda odpowiedzialna za odczyt informacji z pliku tekstowego (wywoływana w metodzie Open()). 3. PreProcessing Klasa to zbiór metod pozwalających dokonać wstępnego przetworzenia sygnału. DoOperations() - wykonuje pełny preprocessing sygnału czyli filtrację dolnoprzepustową, górnoprzepustową, pochodną i podniesienie do kwadratu i okno czasowe LowPassFilter() - przepuszcza sygnał przez dolnoprzepustowy filtr o skończonej odpowiedzi impulsowej. Filtr obcina częstotliwości powyżej 11 Hz. Wynikowy sygnał zapisuje w wektorze this->value_low_pass. HighPassFilter() - przepuszcza sygnał przez górnoprzepustowy filtr o skończonej odpowiedzi impulsowej. Filtr obcina częstotliwości poniżej 5 Hz. Wynikowy sygnał zapisuje w wektorze this->value_high_pass. Derivative() - tworzy sygnał będący pochodną sygnału wejściowego, zapisuje jej wartość w wektorze this->value_derivative. Square() - podnosi sygnał wejściowy do kwadratu i zapisuje jego wartości w
wektorze this->value_square. TimeWindow() - Wykonuje okno uśredniające okno czasowe na sygnale wejściowym i zapisuje je w wektorze this->value_time_window. Normalize(vector<float> & source) Wykonuje normalizację na podanym wektorze, przez normalizację rozumiemy znalezienie wartości maksymalnej wektora i podzielenie wszystkich jego wartości przez wartość maksymalną. (Metoda Pomocnicza) 4. EventVector Klasa reprezentująca Wektor zdarzeń w sygnale, przy jej pomocy jesteśmy w stanie wykryć piki w sygnale przetworzonym przez preprocessing oraz punkty zaufania w sygnale przefiltrowanym DoOperations() - Wykonuje na wektorze wejściowym operacje odnalezienia pików oraz operacje wykrycia punktów zaufania PeakDetector() - Wykrywa piki w sygnale wejściowym FiducialMarkLocation() - Wykrywa punkty zaufania w wektorze wejściowym FindQPoints() - Wykrycie załamków Q w danym sygnale. FindSPoints() - Wykrycie załamków S w danym sygnale. FindQRSStart() - Wykrycie początku załamka QRS. FindQRSEnd() - Wykrycie zakończenia załamka QRS. Synchronize() - metoda pozwala zsynchronizować sygnał z sygnałami podanymi jako argument (wszystkie sygnały zostaną zsynchronizowane). 5. Config zapis i udostępnianie wektora wykrytych zespołów QRS do struktury save() - metoda zapisuje otrzymany wektor do struktury wymaganej przez pozostałe zespoły 9 DODATEK C. Spis zawartości dołączonych nośników Do raportu dołączona zostanie płyta CD zawierająca program wraz z dokumentacją techniczną.