QRS_DET

Transkrypt

QRS_DET
AKADEMIA GÓRNICZO-HUTNICZA
im. St. Staszica w Krakowie
WEAIiE, Katedra Automatyki
Laboratorium Biocybernetyki
Przedmiot: Przetwarzanie sygnałów w systemach diagnostyki medycznej.
QRS_DET
Temat projektu: Detekcja i synchronizacja reprezentacji uderzenia serca (zespołu QRS)
Raport końcowy
Wykonali: Kozera Tomasz,
Rębisz Paweł
V rok Informatyka Stosowana
Wydział EAIiE
prowadzący: dr hab. inŜ. Piotr Augustyniak
Wersja 1.0
Kraków, październik 2009 – styczeń 2010
-1-
Spis treści:
1
ABSTRAKT.................................................................................................................................................. 3
1.1
1.2
1.3
1.4
1.5
2
Główne cele i załoŜenia projektu .........................................................................................3
Opis wybranej metody .........................................................................................................3
Podsumowanie najwaŜniejszych osiągnięć i rezultatów......................................................3
Główne wnioski i ich znaczenie...........................................................................................3
Słowa kluczowe ...................................................................................................................3
WSTĘP.......................................................................................................................................................... 4
2.1
2.2
2.3
Główne cele i załoŜenia projektu .........................................................................................4
Opis wybranej metody .........................................................................................................4
Dyskusja alternatywnych rozwiązań....................................................................................6
3
KONCEPCJA PROPONOWANEGO ROZWIĄZANIA......................................................................... 6
4
REZULTATY I WNIOSKI ......................................................................................................................... 6
5
PODSUMOWANIE ..................................................................................................................................... 8
6
LITERATURA ............................................................................................................................................. 8
7
DODATEK A: OPIS OPRACOWANYCH NARZĘDZI I METODY POSTĘPOWANIA .................. 9
7.1
7.2
7.3
7.4
8
Opis plików aplikacji ...........................................................................................................9
UŜytkowanie aplikacji..........................................................................................................9
Interpretacja otrzymanych wyników..................................................................................12
Wyświetlenie otrzymanych wyników................................................................................12
DODATEK B: REALIZACJA PROPONOWANEGO ROZWIĄZANIA............................................ 14
8.1
Opis zastosowanej metody wraz z modyfikacjami usprawniającymi................................14
8.2
Napotkane problemy ..........................................................................................................15
8.2.1 Ekstrakcja danych z MIT-BIH..........................................................................................15
8.2.2 Problemy z wykrywaniem załamków ...............................................................................16
8.2.3 Problemy z aplikacją daubwave........................................................................................16
8.2.4 Niuanse języka C++..........................................................................................................16
8.2.5 Niuansów ciąg dalszy: problem z delete [].......................................................................17
8.2.6 Problem z ‘Build clean’ ...................................................................................................18
8.2.7 RozbieŜność działania.......................................................................................................19
9
DODATEK C. OPIS INFORMATYCZNY PROCEDUR...................................................................... 19
10
DODATEK D. SPIS ZAWARTOŚCI DOŁĄCZONYCH NOŚNIKÓW (DYSKIETEK, CD ROMU)19
-2-
1 Abstrakt
1.1
Główne cele i załoŜenia projektu
Celem projektu jest wybranie i zaimplementowanie algorytmu detekcji zespołów QRS w
sygnałach EKG. Wyniki pracy naleŜy sprawdzić na sygnałach bazy MIT-BIH dostępnych w ramach
witryny Physionet.org.
1.2
Opis wybranej metody
Wybrana przez nas metoda została zaprezentowana w pracy [1]. Głównym jej załoŜeniem jest
zastosowanie transformaty falkowej z uŜyciem falek Daubechies do wykrywania załamków P-QRST. Dokładny opis znajduje się w rozdziale 2.2.
1.3
Podsumowanie najwaŜniejszych osiągnięć i rezultatów
Zastosowana metoda okazała się być niewystarczająco skuteczna. Konieczne było
wprowadzenie własnych usprawnień, po których udało nam się uzyskać poprawność detekcji rzędu
95%.
Średni czas działania algorytmu dla 1024 próbek wynosi 383 ms.
Sprawność stworzonego algorytmu nie zaleŜy od częstotliwości próbkowania.
Algorytm został przetestowany na 46 sygnałach testowych z bazy danych MIT-BIH.
1.4
Główne wnioski i ich znaczenie
Przytoczona w pracy [1] metoda okazała się być mało skuteczna i podatna na ilość próbek
badanego sygnału. Konieczne było wprowadzenie własnych modyfikacji w celu poprawienia
działania algorytmu.
Metoda nie spełniła naszych oczekiwań – okazała się mieć niewystarczającą jakość detekcji,
jednocześnie będąc stosunkowo skomplikowaną metodą.
Wprowadzenie poprawek zajęło nam większą część pracy nad niniejszym projektem.
Dodatkowo IDE, z którego korzystaliśmy (Dev-Cpp) okazało się być mało funkcjonalne i
obarczone błędami (więcej w dziale 8).
1.5
Słowa kluczowe
EKG, detekcja QRS, zastosowanie falek Daubechies
-3-
2 Wstęp
2.1
Główne cele i załoŜenia projektu
Celem projektu jest wybranie i zaimplementowanie algorytmu detekcji zespołów QRS w
sygnałach EKG. Wyniki pracy naleŜy sprawdzić na sygnałach bazy MIT-BIH dostępnych w ramach
witryny Physionet.org.
2.2
Opis wybranej metody
Wybrana przez nas metoda została zaprezentowana w pracy [1]. Głównym jej załoŜeniem jest
zastosowanie transformaty falkowej z uŜyciem falek Daubechies do wykrywania załamków P-QRST.
Transformata falkowa jest splotem funkcji falkowej Ψ(t) z sygnałem x(t).
Ortonormalne dyskretne falki są skojarzone z funkcją skalującą φ(t). Po dokonaniu splotu
funkcji skalującej z sygnałem otrzymamy współczynniki aproksymacji S.
Dyskretna transformata falkowa moŜe być zapisana jako:
Tm, n =
∞
∫ x(t )ψ
m, n
(t )dt
(2.2.1)
−∞
Współczynniki aproksymacji w skali m i połoŜeniu n moŜna rozpisać jako:
S m, n =
∞
∫ x(t )ϕ
m, n
(t )dt
(2.2.2)
−∞
W praktyce, sygnał S0,n posiada skończoną długość N taką, Ŝe N = 2M. Zatem zakres
osiągalnych skal m wynosi 0 < m < M. Dyskretna aproksymacja sygnału x(t) wyraŜa się wzorem:
M
x0 (t ) = xM (t ) + ∑ d m (t )
(2.2.3)
m =1
gdzie średnia aproksymacja sygnału w skali M to
xM (t ) = S M , nϕ M , n (t )
(2.2.4)
a dokładna aproksymacja sygnału w skali m
d m (t ) =
2 M − m −1
∑T
n =0
ψ m,n (t )
(2.2.5)
m ,n
Dodając aproksymację sygnału w skali M do sumy wszystkich otrzymanych aproksymacji
sygnału we wszystkich osiągalnych skalach otrzymujemy aproksymację oryginalnego sygnału w
-4-
skali 0. Aproksymacja sygnału w określonej skali jest kombinacją aproksymacji i przybliŜenia w
niŜszej skali:
xm(t) = xm-1(t)-dm(t)
(2.2.6)
przykładowo, jeŜeli skala m=3 to
x3(t) = x0(t) – d1(t) –d2(t) – d3(t)
(2.2.7)
Oznacza to sukcesywne pozbywanie się informacji odnośnie wyŜszych częstotliwości z
oryginalnego sygnału w kaŜdym kroku. Nosi to nazwę wielorozdzielczej analizy sygnału przy
uŜyciu transformaty falkowej (multiresolution analysis of a signal using wavelet transform) i jest to
metoda wykorzystana w pracy [1].
Falki Daubechies moŜna podzielić na 10 grup D2-D20 (tylko liczby parzyste). Liczba
oznacza tutaj ilość współczynników falki. Wyznaczają one zdolność falki do reprezentacji sygnału
w formie wielomianu. JeŜeli dana jest grupa Dn to falka jest w stanie opisywać wielomiany rzędu
n
lub niŜszego.
2
W metodzie zaproponowanej w pracy [1] najpierw przystępujemy do wykrycia załamka R.
Jest on najbardziej charakterystyczny i najłatwiejszy do odnalezienia. Następnie, zwiększając
poziom szczegółowości (skalę falki), szukamy sąsiednich załamków (Q i S). Dalsza część metody
nie jest nam potrzebna w tej pracy (wykrycie załamków P i T).
W pracy [1] wykorzystano grupy D4 i D6 do detekcji załamków P-QRS-T. Wyniki
przytoczone są zadowalające – osiągnięto dokładność detekcji zespołów P-QRS-T rzędu 99.18%.
2.2.8 Schemat blokowy algorytmu zaproponowanego w pracy [1]
-5-
2.3
Dyskusja alternatywnych rozwiązań
Inne rozwaŜane przez nas metody opisane w pracach [2], [3] i [4] charakteryzują się gorszym
współczynnikiem detekcji zespołów QRS i niekiedy brakiem moŜliwości detekcji w sygnałach
próbkowanych częstotliwościami innymi niŜ ta którą narzuca dana metoda.
Przeglądając róŜne artykuły z zakresu zespołów QRS czy ogólnie badań EKG, zauwaŜyliśmy,
Ŝe bardzo często wykorzystuje się podejście bazujące na transformatach falkowych co potwierdza
celowość naszego wyboru.
3 Koncepcja proponowanego rozwiązania
Pierwszym etapem jest stworzenie oddzielnej aplikacji umoŜliwiającej wyświetlenie sygnału
EKG z zaznaczeniem załamków QRS. Program taki pomoŜe nam na etapie pisania aplikacji we
wstępnej analizie poprawności działania – umoŜliwi nam on wizualne sprawdzenie czy załamki są
poprawnie wykrywane, a w dalszej kolejności sprawdzenie czy pokrywają się one z faktycznymi
umiejscowieniami załamków, zaznaczonych w plikach dostarczonych z bazy MIT-BIH.
Kolejnym etapem jest stworzenie właściwej części aplikacji poczynając od procedur do
wczytywania danych z pliku z sygnałem, poprzez detekcję QRS aŜ do zapisania wyników do
struktury Beats.Det wraz z opcją eksportu do pliku.
Do wykrywania załamków QRS zostanie zastosowana falka Daubechies o poziomie skali m=3,
poniewaŜ zgodnie z wynikami ukazanymi w pracy [1] daje ona moŜliwość stosowania dobrej
detekcji (rzędu 99,18%) przy braku duŜych narzutów obliczeniowych. Do wykonania obliczeń
falkowych została uŜyta aplikacja ‘Daubwave’ Stevena Gollmera – pracownika Purdue University
of West Lafayette (strona internetowa projektu podana w [5]).
4 Rezultaty i wnioski
Po zastosowaniu detekcji zespołów QRS opisaną metodą okazało się, Ŝe wyniki są wysoce nie
zadawalające i rozbieŜne z danymi przytoczonymi w pracy [1]. W praktyce uzyskaliśmy detekcję
zespołów QRS na poziomie ok. 80-90%, a błędne wykrycie nieistniejących zespołów sięgało rzędu
5-10%.
Dokładna przyczyna rozbieŜności wyników nie jest dla nas jasna, aczkolwiek biorąc pod
uwagę drobne niuanse związane z aplikacją ‘Daubwave’ mamy podstawy ku temu by sądzić, iŜ
-6-
moŜe to być wina tej aplikacji (więcej na ten temat w rozdziale 8), natomiast metoda przytoczona w
[1] jako taka, moŜe być dobra.
W związku z wystąpieniem powyŜszego problemu musieliśmy zastosować środki mające na
celu korekcję błędnych detekcji, zaczynając od skorygowania wykrycia wierzchołków R.
W tym celu napisaliśmy procedury, które miały za zadanie przeszukanie sąsiedztwa rzekomego
wystąpienia wierzchołka R i sprawdzenie czy nie znajduje się on zbyt blisko innego juŜ wykrytego
wierzchołka, bądź teŜ czy w sąsiedztwie nie znajduje się punkt o większej amplitudzie. Dzięki
zastosowaniu takiego podejścia udało nam się zmniejszyć błąd detekcji z ok. 10-15% do ok. 95%
oraz błąd wykrywania nieistniejących załamków z ok. 5-10% do ok. 5%.
Następnym problemem okazało się wykrywanie załamków Q i S, które pomimo podobnych
zabiegów nie przyniosło widocznej poprawy. W związku z tym dokonaliśmy modyfikacji metody
polegającej na tym, Ŝe wierzchołki Q oraz S są wykrywane metodą znalezienia minimum lokalnego
funkcji sygnału odpowiednio po lewej lub prawej stronie wykrytego wierzchołka R. Efekty okazały
się bardzo dobre – o ile wierzchołek R jest wykryty poprawnie, to wierzchołki Q oraz S równieŜ są
wykrywane poprawnie.
Średni czas działania algorytmu dla 1024 próbek wynosi 383 ms, co daje czas rzędu 24,31 sek.
dla sygnału posiadającego 650 000 próbek (sygnały testowe z bazy MIT-BIH, 30 minutowe zapisy
EKG z próbkowaniem 360Hz).
Działanie algorytmu zostało sprawdzone dla róŜnych częstotliwości próbkowania (90, 180, 360
Hz) – sprawność algorytmu jest taka sama niezaleŜnie od częstotliwości.
Testy zostały wykonane na 46 sygnałach dostępnych w ramach bazy MIT-BIH.
Jako wnioski z powyŜszej pracy musimy stwierdzić, Ŝe zastosowana metoda nie osiągnęła
zamierzonych rezultatów a jej jakość detekcji jest niezadowalająca z medycznego punktu widzenia.
Błąd wykrywania zespołów QRS na poziomie 95% jest według nas niedopuszczalny w systemie
mającym na celu wykrywanie poprawnej pracy serca.
Kolejnym problemem jest to, Ŝe wykrywanie zespołów QRS powyŜszą metodą wnosi wymóg
aby ilość próbek badanego sygnału była niewiele mniejsza lub równa 2n, n ∈ N . W praktyce
okazało się, Ŝe jeŜeli liczba próbek jest niewiele większa niŜ 2n to detekcja działa źle – skuteczność
jest poniŜej 50%. Wynika to z faktu, Ŝe w przypadku niedostatecznej ilości próbek dostarczonych
do programu daubwave brakujące elementy są uzupełniane zerami i jeŜeli takich elementów jest
odpowiednio duŜo to otrzymane wyniki bardzo odbiegają od stanu faktycznego.
-7-
5 Podsumowanie
Metoda, którą wybraliśmy okazała się mało skuteczna i bardzo czuła na ilość próbek jaką
posiada badany sygnał. W celu usprawnienia detekcji musieliśmy zastosować szereg działań
korygujących, co pozwoliło na znaczną poprawę detekcji zespołów QRS.
Średni czas trwania detekcji dla 1024 próbek wynosi 383 ms.
Poprawność wykrywania
załamków QRS jest na poziomie 95%.
Metoda okazała się być mniej skuteczna niŜ przedstawiono w pracy [1]. Pomimo zastosowania
usprawnień metoda nie spełniła naszych oczekiwań.
6 Literatura
[1] S. Z. Mahmoodabadi, A. Ahmadian, M. D. Abolhasani, “ECG FEATURE EXTRACTION
USING DAUBECHIES WAVELETS”
[2] JC Hsieh, WC Tzeng, YC Yang, SM Shieh, „Detecting ECG Characteristic Points by Novel
Hybrid Wavelet Transforms: Evaluation of Clinical SCP-ECG Database„
[3] P Castiglioni, L Piccini, M Di Rienzo, “Interpolation Technique for Extracting Features from
ECG Signals Sampled at Low Sampling Rates”
[4] F Chiarugi, V Sakkalis, D Emmanouilidou, T Krontiris, M Varanini, I Tollis, “Adaptive
Threshold QRS Detector with Best Channel Selection Based on a Noise Rating System”
[5] strona projektu ‘Daubwave’ autorstwa Stevena Gollmera:
http://archives.math.utk.edu/software/msdos/modelling/daubwave/.html
[6] Baza danych MIT-BIH zawierająca sygnały w formacie 212:
http://physionet.org/physiobank/database/mitdb/
[7] Specyfikacja uŜytkowania aplikacji rdsamp:
http://www.physionet.org/physiotools/wag/rdsamp-1.htm
-8-
7
DODATEK A: Opis opracowanych narzędzi i metody postępowania
7.1 Opis plików aplikacji
W katalogu z aplikacją powinny znajdować się:
•
daubwave.exe – aplikacja autorstwa Stevena Gollmera (do pogrania z [5]) wykonująca
transformatę falkową falkami Daubechies,
•
rdsamp.exe
- aplikacja z witryny Physionet.org mająca na celu umoŜliwienie ekstrakcji
danych z bazy MIT-BIH do formatu tekstowego (aplikacja wymaga bibliotek: cygcrypto0.9.8.dll, cygcurl-4.dll, cygssh2-1.dll, cygssl-0.9.8.dll, cygwfdb-10-4.dll, cygwin1.dll, cygz.dll).
Opis rdsamp jest dostępny w [7],
•
qrs_det.exe – nasza aplikacja,
•
disp_dat.m - skrypt w Matlabie mający na celu wyświetlanie wyników działania aplikacji,
•
signals (katalog) – katalog zawierający badane sygnały w formie tekstowej bądź MIT-BIH
(zgodne z formatem 212 i posiadające kanał MLII; moŜliwe do pobrania z [6] - są to wszystkie
dostępne tam sygnały za wyjątkiem 102 i 104, które nie posiadają kanału MLII).
7.2 UŜytkowanie aplikacji
W celu dokonania detekcji zespołów QRS stworzyliśmy aplikację, którą moŜna uruchomić z
poziomu konsoli systemowej. Aplikacją jest plik qrs_det.exe. Po uruchomieniu bez Ŝadnych
parametrów otrzymamy informację na temat dostępnych opcji:
7.2.1 Zrzut ekranu o dostępnych opcjach
-9-
Aplikacja moŜe działać z plikami sygnału przygotowanymi w formie tekstowej (kaŜda
linijka to kolejne wartości próbki, typu float) lub z danymi dostępnymi w ramach bazy danych
MIT-BIH. Sygnały te moŜna pobrać z [6].
W przypadku pracy na sygnałach z bazy MIT-BIH konieczna jest konwersja z formatu 212
na format tekstowy. W tym celu uŜywana jest aplikacja rdsamp (opis w [7]). Ekstrakcja działa w
przypadku sygnałów posiadających kanał MLII, dlatego teŜ sygnały 102 i 104 dostępne w [6] nie są
obsługiwane. Tym nie mniej dostępnych jest 46 z 48 zamieszczonych sygnałów.
Pliki z sygnałami do badania muszą znajdować się w katalogu signals/.
W celu dokonania detekcji zespołów QRS na przykładowym pliku 100.dat (format MITBIH) naleŜy wywołać aplikację z parametrem będącym nazwą pliku bez rozszerzenia oraz opcją
‘-f360’. Opcja ta ustala częstotliwość próbkowania badanego sygnału (w Hz) – wszystkie sygnały
zawarte w [6] posiadają częstotliwość próbkowania równą 360 Hz. Zatem pełna komenda do
wywołania wygląda następująco:
qrs_det 100 –f360
Po uruchomieniu nastąpi ekstrakcja danych do formy tekstowej oraz detekcja zespołów
QRS.
7.2.2 Zrzut ekranu w czasie działania aplikacji
W przypadku gdy posiadamy dane gotowe w formie tekstowej naleŜy dodać jeszcze opcję
‘-t’, która informuje program o tym Ŝe dane są w formie tekstowej.
-10-
Gdy dane są w formie pliku z bazy MIT-BIH po skończeniu działa programu w katalogu
signals/ powstanie plik o nazwie takiej jak badany sygnał z dodatkiem ‘_extracted’ na końcu nazwy
(np.: ‘100_extracted.dat’ dla sygnału ‘100’). Plik ten zawiera dane w formie tekstowej
wyeksportowane z sygnału MIT-BIH, moŜna go zatem uŜywać w przyszłości. Dzięki temu nie
będzie konieczne kaŜdorazowe wyciąganie danych z plików MIT-BIH, co zajmuje dość duŜo czasu.
Dodatkową opcją programu jest wykonanie detekcji nie na całym sygnale lecz na
wyznaczonej części. UŜywa się do tego opcji ‘-b’ (begin) oraz ‘-e’ (end), po których podajemy
liczby (bez spacji) wyznaczające początek oraz koniec obszaru detekcji. Obszar ten jest podawany
w sekundach i jest obustronnie domknięty.
Przykład 1:
Uruchomienie aplikacji na danych MIT-BIH dla całego sygnału:
qrs_det 100 –f360
Przykład 2:
Uruchomienie aplikacji na danych w formie tekstowej dla całego sygnału:
qrs_det 100_extracted –f360 –t
Przykład 3:
Uruchomienie aplikacji na danych w formie tekstowej dla okresu od 30s do 190s:
qrs_det 100_extracted –f360 –t –b30 –e190
Przykład 4:
Uruchomienie aplikacji na danych w formie tekstowej dla okresu od 30s do 190s, z
częstotliwością próbkowania 200 Hz:
qrs_det 100_extracted –f200 –t –b30 –e190
Przykład 5:
Wyświetlenie informacji o składni parametrów programu:
qrs_det
lub
qrs_det -?
-11-
7.3 Interpretacja otrzymanych wyników
Wyniki znajdują się w katalogu output. Plik z wynikiem posiada rozszerzenie .qrs. Plik jest
plikiem tekstowym, w którym kaŜda kolejna linijka zawiera informację o kolejnych zespołach QRS
zgodnie z poniŜszą specyfikacją:
Q Qtime Qval R Rtime Rval S Stime Sval
gdzie:
•
Q, R, S – numer próbki w której występuje dany wierzchołek (int32),
•
Qtime, Rtime, Stime – czas wystąpienia wierzchołka podany w sekundach (float),
•
Qval, Rval, Sval – wartość sygnału w tym punkcie (float),
7.4 Wyświetlenie otrzymanych wyników
Do obejrzenia wyników słuŜy załączony skrypt w Matlabie (disp_dat.m). Przed uruchomieniem
naleŜy ustawić wartości zmiennych singalFile oraz detectionFile tak aby wskazywały odpowiednio
na plik z sygnałem w postaci tekstowej oraz plik z wynikami działania aplikacji.
Przykład ustawienia zmiennych dla wyświetlania wyników detekcji wykonanej na pliku 100 z
bazy MIT-BIH:
signalFile = 'signals/100_extracted.dat';
detectionFile = 'output/100.qrs';
Po ustawieniu zmiennych moŜna uruchomić skrypt. Wyświetlony zostanie wykres
przedstawiający sygnał oraz wykryte wierzchołki zespołów QRS.
-12-
7.4.1 Wykresy przedstawiające badany sygnał wraz z zaznaczonymi zespołami QRS
•
Kolorem niebieskim zaznaczono badany sygnał (wykres punktowy oraz liniowy),
•
Kolorem czerwonym zaznaczono wierzchołki Q,
•
Kolorem zielonym zaznaczono wierzchołki R,
•
Kolorem czarnym zaznaczono wierzchołki S,
-13-
8
DODATEK B: Realizacja proponowanego rozwiązania
8.1 Opis zastosowanej metody wraz z modyfikacjami usprawniającymi
PoniŜej zamieszczamy opis działania części programu odpowiedzialnej za przygotowanie
danych potrzebnych do rozpoczęcia rozpoznania załamków. Detekcja odbywa się w funkcji
QRS_DET(). PoniŜsze operacje mają na celu przygotowanie danych i parametrów w sposób
symulujący ustawienie tych informacji przez inne części wspólnej aplikacji „Analiza
Elektrokardiogramu”:
•
Sprawdzenie poprawności danych przekazanych z konsoli. W przypadku błędu wyświetlona
zostaje informacja o błędzie oraz składna opcji programu (help). Program kończy działanie.
•
Inicjalizacja wspólnych struktur programu „Analiza Elektrokardiogramu” danymi potrzebnymi
do działania niniejszej aplikacji (np.: typ rozszerzenia plików z danymi, maksymalna długość
sygnału).
•
Ewentualna ekstrakcja danych z pliku MIT-BIH do formy tekstowej.
•
Przepisanie przekazanych parametrów do struktury sterującej działaniem aplikacji QRS_DET.
•
Uruchomienie funkcji QRS_DET() odpowiedzialnej za działanie właściwej aplikacji.
•
Zwolnienie pamięci zajmowanej przez wspólne struktury danych.
•
Usunięcie plików tymczasowych.
Opis działania QRS_DET():
•
Pobranie danych sterujących ze struktury DetConf oraz danych z innych wspólnych struktur.
•
Sprawdzenie poprawności pobranych danych (np.: czy podany zakres czasowy jest poprawny).
•
Utworzenie tymczasowych katalogów do przechowania potrzebnych plików.
•
Ustalenie zakresu detekcji.
•
W pętli wykonywane są operacje mające na celu detekcję załamków QRS na zadanym
przedziale:
stworzenie tymczasowego pliku z próbkami z aktualnie badanego zakresu (konieczne
dla daubwave),
wywołanie na powyŜszym pliku aplikacji daubwave – detekcja załamków R metodą
falkową,
-14-
wywołanie metody weryfikującej i poprawiającej detekcję oraz zapisującej wyniki do
pliku tekstowego (funkcja detection(...)).
•
Zapisanie danych do wspólnych struktur.
PoniŜej znajduje się schemat blokowy działania funkcji detection(...). Jest to kluczowa funkcja
algorytmu w której odbywa się korekcja wyników uzyskanych przez daubwave:
F-DWT
Poziom szczeg .
R-DWT
Weź kolejny
domniemany R
T
Czy nowy R jest odległy od
poprzedniego o co najmniej 0.25
sek?
Jako R wybierz
maksimum lokalne
z sąsiedztwa
domniemanego R
Podniesienie
do kwadratu
Thresholding
5% z MAX
N
Znajdź Q jako
minimum lokalne
lewego
sąsiedztwa R
Znajdź S jako
minimum lokalne
prawego
sąsiedztwa R
Zapisz Q,R,S
8.1.1 Schemat blokowy funkcjonalności odpowiedzialnej za detekcję załamków QRS
8.2 Napotkane problemy
8.2.1 Ekstrakcja danych z MIT-BIH
Pierwszym powaŜnym problemem było skorzystanie z danych udostępnionych w [6]. Nie
udało nam się uzyskać informacji o formacie udostępnianego pliku .dat w ramach witryny
Physionet.org. Informacje te udało nam się znaleźć dopiero po wyszukaniu ich na innych stronach
internetowych. Tam teŜ znaleźliśmy informacje o aplikacji rdsamp udostępnianej w ramach witryny
Physionet.org (link w [7]). Tym nie mniej problemem okazało się jej skompilowanie ze względu na
brak duŜej ilości wymaganych bibliotek oraz liczne błędy kompilacji oraz linkowania.
Ponownie zmuszeni byliśmy do szukania pomocy poza witryną Physionet.org. W efekcie
udało nam się znaleźć skompilowaną i działającą wersję rdsamp wraz ze wszystkimi wymaganymi
bibliotekami.
-15-
8.2.2 Problemy z wykrywaniem załamków
Następnym problemem było niezadawalające działanie metody przytoczonej w [1]. W celu
poprawy działania algorytmu wprowadziliśmy własne usprawnienia do tej metody o czym moŜna
przeczytać w Rozdziałach 4 oraz 8.1.
8.2.3 Problemy z aplikacją daubwave
Aplikacja daubwave jak się okazało, jest bardzo czuła na rozmiar sygnału i w przypadku
gdy jest on nieznacznie większy od 2n, n ∈ N detekcja zaczyna odbywać się nieprawidłowo.
Początkowo nie wiedzieliśmy co jest przyczyną bardzo złych wyników wykrywania załamków.
Podejrzewaliśmy, Ŝe być moŜe uŜywaliśmy tej aplikacji w zły sposób (np.: podając złe parametry).
Okazało się, Ŝe w przypadku gdy liczba próbek jest za mała program uzupełnia sygnał zerami tak
by otrzymać liczbę próbek równą 2n. JeŜeli ilość tak dopisanych zer jest niewielka (np.: podajemy
1000 próbek, dopisane zostają 24 zera) to aplikacja generuje dobre wyniki. W przeciwnym
przypadku są one bardzo odległe od prawidłowych.
Rozwiązaniem problemu było podzielenie sygnału przekazywanego do daubwave na
częściowe sygnały o długości 1024 próbek.
8.2.4 Niuanse języka C++
W pewnym momencie pisania aplikacji występował u nas błąd, który objawiał się tym, Ŝe
wartość zmiennej nie była przepisywana do elementu tablicy. Sytuacja wyglądała następująco:
for(int i=0; i<cnt; i++){
cout << R[i] << endl;
//1
R[i] = i;
cout << R[i] << endl;
//2
}
Przy wykonywaniu powyŜszego kodu okazywało się, Ŝe wartości w R[i] były takie same w
1 jak w 2. Z praktycznego punktu widzenia wyglądało to tak jakby operacja przypisania wartości
nie miała miejsca.
Dokonaliśmy sprawdzenia czy tablica nie jest równa NULL i czy nie wychodzimy poza jej
zakres – wszystko było w porządku.
-16-
Rozwiązanie problemu trwało kilka dni. Okazało się, Ŝe zmienna której uŜywaliśmy do
określenia ilości pamięci potrzebnej do dynamicznego zaalokowania na tablicę R miała wartość
ujemną. Było to z kolei konsekwencją dzielenia przez 0.
To co jest dla nas bardzo ciekawe w tym problemie jest to, Ŝe podczas działania aplikacji nie
dostawaliśmy błędu dzielenia przez zero czy alokowania pamięci na ujemną liczbę bajtów. Jak się
okazało taki fakt rzeczywiście istnieje w języku C++ i jest moŜliwy do odtworzenia. PoniŜszy kod
wykonuje się bez Ŝadnych błędów, pomimo Ŝe występuje w nim dzielenie przez 0 oraz alokowanie
pamięci na ujemną liczbę bajtów:
int main(int argc, char *argv[]){
double b,d;
int c,a;
int* p;
a=10;
b=1;
d=0;
c = (int)( ( (double)(a)+b )/d );
//dzielenie przez 0
cout << c;
//wypisuje się -2147483648
p = new int[c];
//alokujemy pamięć na tablicę która ma -2147483648 elementów
delete [] p;
system("PAUSE");
return EXIT_SUCCESS;
}
8.2.5 Niuansów ciąg dalszy: problem z delete []
Kolejnym ciekawym problemem była sytuacja w której aplikacja kończyła się z błędem (bez
określenia typu błędu) w chwili gdy wykonywana była linijka
delete [] p;
Tutaj ponownie sprawdziliśmy wskaźniki oraz zakres tablicy. Wszystko wydawało się w
porządku i w efekcie doszliśmy do momentu w którym aplikacja kończyła się z błędem w poniŜszej
sytuacji:
int* p;
p = new int[2];
if(p!=NULL)
delete [] p;
//błąd
-17-
Problem ten równieŜ był cięŜki do wyśledzenia. Z pomocą przyszedł jeden z naszych
znajomych (doświadczony programista), który stwierdził Ŝe problem nie koniecznie musi leŜeć po
stronie delete []. W przypadku gdy istnieje problem z pamięcią znajdującą się na stosie i wykonamy
operację delete moŜe wystąpić błąd pamięci związany z tym co leŜy na stosie.
Okazało się, Ŝe znacznie wcześniej jedna z tablic była alokowana na zbyt małą ilość
elementów. To z kolei powodowało wyjście poza zakres tablicy w pewnych miejscach programu.
Błąd powodujący zaprzestanie działania aplikacji występował natomiast znacznie później, w innej
części kodu gdy operacja delete [] wykonywała działania na stosie.
8.2.6 Problem z ‘Build clean’
Jeden z problemów, który nastąpił w dość wczesnej fazie tworzenia projektu był problem
złej obsługi plików pośrednich przez IDE. Większość kompilatorów (z róŜnych języków
kompilowanych) posiada opcję ‘build clean’ (zwaną teŜ często ‘rebuild’, ‘clean’).
Generalnie rzecz biorąc w trakcie kompilacji, kompilator sprawdza czy dany plik źródłowy
się zmienił. JeŜeli tak to zostaje on skompilowany, jeŜeli nie to nie jest on ponownie kompilowany i
w efekcie pozostaje stary plik pośredni (.obj czy .o). Problem jest tutaj dwojaki.
Po pierwsze, nie zawsze kompilatory dobrze wykrywają czy plik się zmienił. W efekcie tego
plik .obj nie zostaje stworzony na nowo i uŜywana jest jego stara wersja.
Po drugie, często opcja ‘clean’, która powinna wymusić przekompilowanie wszystkich
plików i nadpisanie starych plików .obj nie działa poprawnie i niektóre z plików mogą pozostać w
starej wersji (moŜna to sprawdzić po dacie stworzenia pliku).
Efektem któregokolwiek z powyŜszych problemów jest sytuacja w której program przestaje
działać w ‘losowych’ momentach lub gdy dostajemy nagle duŜą ilość błędów linkowania, których
wcześniej nie mieliśmy. JeŜeli w takiej sytuacji ręcznie skasujemy pliki .obj i skompilujemy od
nowa cały projekt to wszystko działa w porządku.
Problem ten jest uciąŜliwy poniewaŜ jest cięŜki do zdiagnozowania a wina nie leŜy po
stronie programisty. Osobiście jak dotąd spotykaliśmy się z tym problemem dość często w róŜnych
językach programowania i róŜnych IDE/kompilatorach (Dev-Cpp, Visual Studio 6.0, Visual Studio
2003, Visual Studio 2007, Borland C++ Builder, NetBeans, Gnat).
W związku z tym, Ŝe problem ten był nam znany udało nam się go dość szybko
zdiagnozować. W efekcie stworzyliśmy plik .bat, który kasował wszystkie pliki pośrednie i plik
-18-
wykonywalny .exe. Przed kaŜdą kompilacją uruchamialiśmy powyŜszego batcha i dopiero wtedy
przystępowaliśmy do kompilacji.
8.2.7 RozbieŜność działania
W ramach pracy nad aplikacją zostaliśmy poproszeni przez kolegów z innych grup o
udostępnienie plików z wynikami detekcji zespołów QRS. Wyniki te były im potrzebne do
testowania swoich aplikacji.
Udostępniliśmy naszą aplikację kolegom tak aby mogli z niej korzystać. Okazało się, Ŝe u
nas aplikacja działa zawsze poprawnie natomiast u jednego z kolegów zawsze kończyła się z
błędem i to zawsze w tym samym momencie.
Problem przestał występować po przesłaniu nowego pliku wykonywalnego – w aplikacji nie
wprowadziliśmy Ŝadnych zmian. Usunęliśmy pliki pośrednie i skompilowaliśmy program na nowo.
Od tego momentu aplikacja zaczęła działać sprawnie.
Nie udało nam się odkryć przyczyny tego błędu. W związku z zaistniałą sytuacją dodaliśmy
do aplikacji logowanie wykonywanych operacji i następne wersje wysyłane do kolegów posiadały
juŜ taką funkcjonalność. Od tego czasu nie został do nas zgłoszony Ŝaden błąd.
9 DODATEK C. Opis informatyczny procedur
Ogólny opis rozwiązania wraz ze schematem moŜna znaleźć w Rozdziale 8.
Szczegółowy opis procedur znajduje się w zamieszczonej dokumentacji kodu źródłowego
aplikacji (patrz rozdział 10).
10 DODATEK D. Spis zawartości dołączonych nośników (dyskietek, CD
ROMu)
Spis plików na załączonym nośniku:
katalog BIN:
o daubwave.exe – aplikacja autorstwa Stevena Gollmera (do pogrania z [5]) wykonująca
transformatę falkową falkami Daubechies,
-19-
o rdsamp.exe - aplikacja z witryny Physionet.org mająca na celu umoŜliwienie
ekstrakcji danych z bazy MIT-BIH do formatu tekstowego (aplikacja wymaga
bibliotek: cygcrypto-0.9.8.dll, cygcurl-4.dll, cygssh2-1.dll, cygssl-0.9.8.dll, cygwfdb10-4.dll, cygwin1.dll, cygz.dll. Biblioteki te znajdują się w katalogu BIN wraz z
aplikacją),
o qrs_det.exe – nasza aplikacja,
o disp_dat.m - skrypt w Matlabie mający na celu wyświetlanie wyników działania
aplikacji,
o signals (katalog) – katalog zawierający badane sygnały w formie tekstowej bądź MITBIH (zgodne z formatem 212 i posiadające kanał MLII, do pobrania z [6], wszystkie
dostępne badania za wyjątkiem 102 i 104, które nie posiadają kanału MLII).
Dane z bazy MIT-BIH posiadają nazwy typu 100.hea, 100.atr, 100.dat natomiast
sygnały wyeksportowane z powyŜszej bazy mają nazwy typu 100ex.dat,
katalog DOC:
o QRS_DET_-_raport_częściowy.doc – raport częściowy z pracy nad projektem,
o QRS_DET_-_raport_końcowy.doc – aktualnie czytany dokument,
o QRS_DET_DOC – katalog zawierający dokumentację kodu źródłowego aplikacji,
katalog LIT:
o 0157.pdf – pdf zawierający pracę [4],
o 0751.pdf – pdf zawierający pracę [2],
o 481.pdf – pdf zawierający pracę [3],
o daubechies.pdf – pdf zawierający pracę [1],
katalog SRC:
o katalog QRS_DET – katalog ze źródłami projektu oraz plikiem projektu do Dev-Cpp,
o katalog daubwave – katalog ze źródłami oraz plikiem projektu i dokumentacją do
aplikacji daubwave
-20-

Podobne dokumenty