版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、<p> 畢業(yè)設(shè)計(jì)(論文)中文摘要</p><p> MIT-BIH心律失常心電圖分析軟件 摘要:MIT-BIH 心律失常數(shù)據(jù)庫是目前國際上公認(rèn)的可作為標(biāo)準(zhǔn)的心律失常分析數(shù)據(jù)庫之一。開始執(zhí)行軟件,需要導(dǎo)入外部數(shù)據(jù)文件,同時(shí)把病例信息保存至數(shù)據(jù)庫,方便以后對(duì)病例信息的管理。想要繪制波形并且顯示專家標(biāo)記,可以通過讀取自定義格式的二進(jìn)制文件,獲取心電兩導(dǎo)波形數(shù)據(jù)以及專家在特定時(shí)間點(diǎn)標(biāo)注的標(biāo)記,實(shí)現(xiàn)對(duì)應(yīng)波形與
2、相關(guān)專家標(biāo)記的同步,以及方便用戶分析兩導(dǎo)心電波形并且與專家做的標(biāo)記相比對(duì),了解各種心律失常類型的典型波形形態(tài)。至于對(duì)心律失常類型定位,瀏覽波形的同時(shí),可以選擇任意一種該病例中存在的心律失常類型,根據(jù)所選擇的心律失常類型發(fā)生的時(shí)間順序依次定位,定位顯示出對(duì)應(yīng)的心電波形。最后如果想對(duì)病例信息后臺(tái)管理,可以借助數(shù)據(jù)庫,實(shí)現(xiàn)病例中患者信息以及心律失常類型發(fā)生次數(shù)的統(tǒng)計(jì),并且實(shí)現(xiàn)對(duì)病例的波形回顧、查詢、刪除等功能。關(guān)鍵詞: MIT-BIH 心
3、律失常 兩通道心電數(shù)據(jù) 專家診斷標(biāo)記 MFC Access </p><p> 畢業(yè)設(shè)計(jì)(論文)外文摘要</p><p><b> 目 次</b></p><p><b> 1 引言1</b></p><p> 1.1 心電知識(shí)簡介1</p><p&g
4、t; 1.2 心電數(shù)據(jù)文件存儲(chǔ)格式簡介2</p><p> 2 MIT-BIH心律失常心電圖分析軟件整體設(shè)計(jì)3</p><p> 2.1 軟件主要功能3</p><p> 2.2 程序流程圖3</p><p> 3 頭文件的識(shí)讀5</p><p> 3.1 頭文件信息存儲(chǔ)格式5<
5、;/p><p> 3.2 讀取頭文件信息6</p><p> 4波形文件的識(shí)讀8</p><p> 4.1 繪制波形的主要技術(shù)指標(biāo)8</p><p> 4.2 讀取波形數(shù)據(jù)文件9</p><p> 4.3 繪制波形的實(shí)現(xiàn)過程10</p><p> 5 專家標(biāo)記文件的
6、識(shí)讀15</p><p> 5.1 專家標(biāo)記文件的讀取15</p><p> 5.2 專家標(biāo)記文件的顯示18</p><p> 5.3 心律失常類型時(shí)間定位22</p><p> 6 病例信息管理23</p><p> 6.1 打開數(shù)據(jù)庫23</p><p>
7、6.2 數(shù)據(jù)管理的主要功能23</p><p> 6.3 數(shù)據(jù)庫中字段的設(shè)置26</p><p> 7 系統(tǒng)測(cè)試26</p><p> 7.1 系統(tǒng)測(cè)試內(nèi)容27</p><p> 7.2 測(cè)試結(jié)果27</p><p><b> 結(jié) 論29</b></p>
8、;<p> 參 考 文 獻(xiàn)30</p><p><b> 致 謝31</b></p><p><b> 1 引言</b></p><p> 目前世界上公認(rèn)的心電數(shù)據(jù)庫有三個(gè),分別是美國麻省理工學(xué)院提供的MIT-BIH心電數(shù)據(jù)庫,和美國心臟學(xué)會(huì)提供的AHA以及歐洲的ST-T心電數(shù)據(jù)庫。其中MIT
9、-BIH數(shù)據(jù)庫近幾年應(yīng)用比較廣泛。為了方便研究,該數(shù)據(jù)庫的所有者也將越來越多的數(shù)據(jù)放到了互聯(lián)網(wǎng)上。該數(shù)據(jù)庫中的數(shù)據(jù)是通過錄制在磁帶上的模擬信號(hào)通過模數(shù)(A/D)轉(zhuǎn)換后的數(shù)字信號(hào)。在存儲(chǔ)時(shí)為了減少文件長度節(jié)省空間,采用了自定義的格式,無法使用通用的方法去讀取這些數(shù)據(jù),因此在一些網(wǎng)站上出現(xiàn)了讀取該文件的工具軟件和庫函數(shù),使用這些工具或函數(shù)就可以獲取所有的數(shù)據(jù)。但是如果每次都是用這些工具軟件或者庫函數(shù),不僅會(huì)增加程序的復(fù)雜度,而且使用也不靈活
10、。我們完全可以根據(jù)文件的格式讀出數(shù)據(jù),可以靈活的使用這些心電數(shù)據(jù)。</p><p> 該數(shù)據(jù)庫中包含48條病歷數(shù)據(jù),每條病歷均為30分鐘兩通道心電數(shù)據(jù),包含全程(30分鐘)專家診斷標(biāo)記。</p><p> MIT-BIH 數(shù)據(jù)庫近年來在心電圖產(chǎn)品認(rèn)證、心電圖教學(xué)等方面應(yīng)用比較廣泛,尤其是IEC60601-2-47、AAMI EC57等標(biāo)準(zhǔn)中明確規(guī)定使用該數(shù)據(jù)庫作為設(shè)備(軟件)心律失常自
11、動(dòng)分析功能的性能測(cè)試數(shù)據(jù)庫。</p><p> 1.1 心電知識(shí)簡介</p><p> (1)心電圖:心臟的電激動(dòng)過程影響著全身各部,使體表的不同部位發(fā)生了電位差,按照心臟激動(dòng)的時(shí)間順序,將此體表電位的變化記錄下來,形成一條連續(xù)曲線,即為心電圖。英文為electrocardiogram,簡寫為ECG。</p><p> 在正常情況下,每次心動(dòng)周期在心電圖上
12、均可出現(xiàn)相應(yīng)的一組波形。如圖1-1所示。</p><p> 圖 1-1 一個(gè)良好的心電波形圖</p><p> P波 心房除極時(shí)的電位變化</p><p> P-R間期 心房開始除極至心室開始除極的時(shí)間</p><p> QRS波群 全部心室除極時(shí)的電位變化</p><p>
13、; S-T段 心室復(fù)極時(shí)的電位變化(早期)</p><p> T波 心室復(fù)極時(shí)的電位變化(晚期)</p><p> Q-T間期 心室除極與復(fù)極的總時(shí)間</p><p> (2)導(dǎo)聯(lián)的定義:將兩電極置于人體的任意兩點(diǎn)與心電圖機(jī)相連,可描記出心電圖,電極與心電圖機(jī)鏈接的線路,稱作心電圖的導(dǎo)聯(lián)。</p>&l
14、t;p> 1.2 心電數(shù)據(jù)文件存儲(chǔ)格式簡介</p><p> 通過對(duì)MIT-BIH 心律失常數(shù)據(jù)庫中數(shù)據(jù)的直接識(shí)讀,使我們能更靈活地使用這些數(shù)據(jù),并可以對(duì)其進(jìn)行二次開發(fā)。一個(gè)完整的心電記錄由三部分組成:</p><p> (1)頭文件[.hea],以ASCII碼的形式存儲(chǔ),文件中存儲(chǔ)了病歷中患者的基本信息、用藥情況以及一些信號(hào)標(biāo)準(zhǔn);</p><p>
15、 (2)數(shù)據(jù)文件[.dat],按二進(jìn)制存儲(chǔ),每三個(gè)字節(jié)存儲(chǔ)兩個(gè)數(shù),分別表示兩導(dǎo)波形在某一時(shí)間點(diǎn)的電壓值,一個(gè)數(shù)12bit,存儲(chǔ)繪制兩導(dǎo)波形的數(shù)據(jù);</p><p> (3)注釋文件[.art],按二進(jìn)制存儲(chǔ),表示在特定時(shí)間點(diǎn)處專家標(biāo)注的診斷標(biāo)記;</p><p> 如圖1-2所示為三個(gè)文件之間的關(guān)系:</p><p> 圖1-2 數(shù)據(jù)庫中病例記錄的組成框圖&
16、lt;/p><p> 2 MIT-BIH心律失常心電圖分析軟件整體設(shè)計(jì)</p><p> 開發(fā)這款軟件可以作為研究心律失常的一個(gè)模型軟件,通過這款軟件可以瀏覽經(jīng)典的48條MIT-BIH心律失常病例的兩導(dǎo)心電波形。通過與專家標(biāo)記的比對(duì)方便我們學(xué)習(xí)了解各種常見心律失常類型的波形形態(tài),</p><p> 軟件負(fù)責(zé)管理指定路徑中存儲(chǔ)的心電數(shù)據(jù)和專家診斷標(biāo)記,數(shù)據(jù)庫系統(tǒng)中
17、維護(hù)著每一條病歷的相關(guān)信息,方便用戶對(duì)所有數(shù)據(jù)、信息等進(jìn)行查閱、維護(hù)等工作。</p><p> MIT-BIH 心律失常數(shù)據(jù)庫心電圖顯示軟件運(yùn)行于Windows XP/ SP2或更高版本操作系統(tǒng)之上,代碼的編寫采用C++語言,使用MFC作為程序開發(fā)框架、使用ADO組件操作Access 數(shù)據(jù)庫,對(duì)48條心律失常病例進(jìn)行維護(hù)管理。</p><p> 2.1 軟件主要功能 </p&g
18、t;<p><b> 1.導(dǎo)入病歷:</b></p><p> 將原始病歷數(shù)據(jù)導(dǎo)入軟件(把源文件復(fù)制到軟件指定的文件夾中),同時(shí)將病歷的信息以及專家分析結(jié)果的統(tǒng)計(jì)信息保存到數(shù)據(jù)庫中。</p><p><b> 2.病歷管理:</b></p><p> 采用列表的方式顯示已導(dǎo)入的病歷,提供對(duì)病歷及信息的
19、查詢、回顧、刪除等功能。</p><p><b> 3.病歷回顧:</b></p><p> 瀏覽心電波形、并且顯示對(duì)應(yīng)的專家分析診斷結(jié)果,可調(diào)整波形的走速與增益,并可通過選擇心律失常類型定位到指定時(shí)間。</p><p><b> 4.設(shè)置功能:</b></p><p> 用戶可對(duì)文字、波形
20、、心電圖背景格、定標(biāo)信號(hào)等指定顏色。</p><p> 2.2 程序流程圖</p><p> 如圖2-1所示,為軟件的程序流程圖,描述了軟件的整體執(zhí)行過程。</p><p> 圖2-1 MIT-BIH心律失常心電圖分析軟件程序流程圖</p><p> 3 頭文件的識(shí)讀 </p><p> 頭文件是由一行
21、或多行ASCII字符碼組成,至少包含一個(gè)記錄行,通常還包括信號(hào)技術(shù)規(guī)范行,片段技術(shù)規(guī)范行(對(duì)于多片段數(shù)據(jù)記錄)和信息注釋行。</p><p> 每條病歷都對(duì)應(yīng)一個(gè)頭文件,頭文件中包含了該條病歷中患者的一些基本信息,包含患者的性別、年齡、用藥情況等,以及采集信號(hào)時(shí)候的一些信號(hào)規(guī)范,比如采樣頻率、采集信號(hào)時(shí)的導(dǎo)聯(lián)編號(hào)、信號(hào)電壓基值等有效信息。在這款軟件中根據(jù)功能方面的要求讀取文件提取有效信息。將病歷的部分相關(guān)信息保
22、存至數(shù)據(jù)庫以及利用提供的一些信號(hào)規(guī)范繪制波形。</p><p> 3.1 頭文件信息存儲(chǔ)格式</p><p> 記錄行中從左到右依次記錄了信號(hào)的名稱、片段數(shù)(可選,對(duì)多片段記錄,且與名稱之間以“/”分隔)、信號(hào)數(shù)量、采樣頻率、計(jì)數(shù)頻率(可選)、計(jì)數(shù)基值(可選,與計(jì)數(shù)頻率配合使用且以圓括號(hào)而非空格分隔)、每信號(hào)采樣數(shù)、采樣開始時(shí)間(可選)、采樣開始日期(可選),這些字段之間除前面指明的
23、之外都是以空格分隔。</p><p> 緊跟記錄行的是信號(hào)技術(shù)規(guī)范行,該行主要包含了存儲(chǔ)信號(hào)的文件名、存儲(chǔ)格式、ADC增益、基線值、ADC分辨率、ADC零值、信號(hào)初始值等字段。片段技術(shù)規(guī)范行主要包括記錄名稱和每信號(hào)的采樣數(shù)兩個(gè)字段,該行只有在多片段記錄的頭文件中才有。</p><p> 信息注釋行一般在文件的最后,每行的開頭以“#”開始,內(nèi)容一般是說明患者的簡單情況。</p>
24、;<p> 下面以編號(hào)100的頭文件100.hea為例說明,文件的內(nèi)容如下:</p><p> 100 2 360 650000 0:0:0 0/0/0</p><p> 100.dat 212 200 l1 1024 995 -22131 0 MLII</p><p> 100.dat 212 200 11 1024 1011 20052 0
25、 V5</p><p> # 69 M 1085 1629 x1</p><p> # Aldoment.Inderal</p><p> 該頭文件的第一行為記錄行,指出該記錄為一個(gè)包含兩個(gè)采樣率為360HZ的信號(hào),每一信號(hào)的長度為65萬個(gè)采樣點(diǎn),采樣開始時(shí)間和日期沒有記錄。后面緊跟的兩行為信號(hào)技術(shù)規(guī)范說明行,從中可以看出,兩個(gè)信號(hào)都包含在文件100.dat中
26、,每一信號(hào)都是以12位的位壓縮格式(即“212”格式)進(jìn)行存儲(chǔ)的,兩個(gè)信號(hào)的增益都是每200ADC units/mv,ADC的分辨率為11位。ADC零值為1024,在這里基線值沒有明確給出,但可以認(rèn)為它等于ADC零值1024。兩個(gè)信號(hào)的第一采樣點(diǎn)的值分別為995和1011(可以看出這他們都略低于0V),65萬個(gè)采樣點(diǎn)的校驗(yàn)數(shù)分別為-22131和20052,輸入輸出可以以任何尺寸的塊來執(zhí)行,因?yàn)槲募?nèi)容說明了這兩個(gè)信號(hào)的該值都為0,信號(hào)描
27、述字段說明了這兩個(gè)信號(hào)分別采自MLII導(dǎo)聯(lián)和V5導(dǎo)聯(lián)。文件的最后兩行包含了注釋字符串,其中第一行說明了患者的性別和年齡以及記錄數(shù)據(jù),第二行列出了患者的用藥情況。</p><p> 3.2 讀取頭文件信息</p><p> 因?yàn)槊恳粋€(gè)病歷文件都是由三個(gè)基本文件組成的,一條完整的病歷信息的獲取需要同時(shí)讀取對(duì)應(yīng)的三個(gè)文件。當(dāng)導(dǎo)入繪制波形的文件(.dat)文件的同時(shí)對(duì)該文件的后綴名做處理,比
28、如當(dāng)導(dǎo)入100.dat時(shí),經(jīng)過處理同時(shí)導(dǎo)入了100.hea和100.atr文件。具體實(shí)現(xiàn)方法如下代碼所示:</p><p> int n_dot = Dsource.Find(".");</p><p> CString beforedot = Dsource.Left(n_dot);</p><p> Hsource = beforedo
29、t + ".hea";</p><p> m_Hdest = MyApp->m_savepath + dlg.GetFileTitle() + ".hea";</p><p> 通過WinHex軟件查看可以了解到48條病歷中的每一個(gè).hea文件雖然存儲(chǔ)的內(nèi)容不相同,但是在文件中存儲(chǔ)相同信息的位置順序是相同的。比如說文件中第一個(gè)有效數(shù)據(jù)固定
30、表示了病歷的編號(hào),這就方便了我們對(duì)文件的讀取。把讀取出的有用信息依次存放入一個(gè)結(jié)構(gòu)體中。方便使用并且把結(jié)構(gòu)體中的數(shù)據(jù)存入數(shù)據(jù)庫中。讀取頭文件信息的代碼及部分注釋信息如下所示:</p><p> ReadHea(CString Path)//讀頭文件</p><p><b> {</b></p><p> CFile hfile;//定義
31、一個(gè)文件類hfile</p><p> CString info[25];//定義一個(gè)數(shù)組,存放讀取出來的病例信息</p><p> int m = 0;</p><p> char pbuf[500];//接收讀取出的字節(jié)數(shù)據(jù)</p><p> CString str;</p><p> CString
32、single;</p><p> CString tempinfo;</p><p> memset(pbuf,0,sizeof(pbuf));//初始化字符數(shù)組</p><p> if (hfile.Open(m_Hdest,CFile::modeReadWrite) == NULL)</p><p><b> {<
33、;/b></p><p> return;//如果不能打開指定文件,就返回</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> hfile.Read(p
34、buf,sizeof(pbuf));//按字節(jié)讀取文件</p><p> char *hp;</p><p> hp = &pbuf[0];</p><p> for (int k = 0;k<=sizeof(pbuf);k++)</p><p><b> {</b></p>&l
35、t;p> if (m == 25)</p><p><b> {</b></p><p><b> break;</b></p><p><b> }</b></p><p> if ((int)*hp == 10||(int)*hp == 13)</p&
36、gt;<p><b> {</b></p><p><b> hp++;</b></p><p><b> }</b></p><p> if (*hp != ' '&&(int)*hp != 10&&(int)*hp !
37、= 13)</p><p><b> {</b></p><p> tempinfo = tempinfo + (CString)(*hp);</p><p><b> }</b></p><p><b> else</b></p><p>
38、;<b> {</b></p><p> info[m] = tempinfo; //把讀取出的信息存放到數(shù)組中</p><p> tempinfo = "";</p><p> m++;</p><p><b> }</b></p
39、><p><b> hp++;</b></p><p><b> }</b></p><p><b> }</b></p><p> m_case.m_ID = info[0];//把病歷信息存放到結(jié)構(gòu)體中</p><p> m_case.m_
40、dao0 = info[12];</p><p> m_case.m_dao1 = info[21];</p><p> m_case.m_Name = info[13];</p><p> if (info[24] == "F")</p><p><b> {</b></p>
41、<p> m_case.m_Sex = "女";</p><p><b> } </b></p><p><b> else</b></p><p><b> {</b></p><p> m_case.m_Sex = "男&q
42、uot;;</p><p><b> }</b></p><p> m_case.m_Age = atoi(info[23]);</p><p> hfile.Close();//關(guān)閉打開的文件,否則第二次導(dǎo)入文件會(huì)發(fā)生內(nèi)存溢出錯(cuò)誤</p><p><b> }</b></p>
43、<p><b> 波形文件的識(shí)讀</b></p><p> MIT-BIH 數(shù)據(jù)庫中的數(shù)據(jù)存儲(chǔ)格式有Format 8、Format16、Format 80、Format 212、Format 310等8種,具體到某一數(shù)據(jù)文件的存儲(chǔ)格式已在相應(yīng)的頭文件中說明,在每一種格式中都是將來自兩個(gè)或多個(gè)信號(hào)采樣得到的數(shù)據(jù)交替存儲(chǔ)。在這里僅介紹心律失常數(shù)據(jù)文件應(yīng)用最多的Format 212
44、格式的存儲(chǔ)方法。格式212是針對(duì)兩個(gè)信號(hào)的數(shù)據(jù)庫記錄,這兩個(gè)信號(hào)(為了方便起見,我們?cè)O(shè)定為信號(hào)0和信號(hào)1)的采樣數(shù)據(jù)進(jìn)行交替存儲(chǔ),每三個(gè)字節(jié)存儲(chǔ)兩個(gè)數(shù)據(jù),這兩個(gè)數(shù)據(jù)分別采樣自信號(hào)0和信號(hào)1,信號(hào)0的采樣數(shù)據(jù)取自第一字節(jié)對(duì)(共16位)的最低12位,信號(hào)1的采樣數(shù)據(jù)由第一字節(jié)對(duì)的剩余4位(作為組成信號(hào)1采樣數(shù)據(jù)的12位的高4位)和下一字節(jié)的8位(作為組成信號(hào)1采樣數(shù)據(jù)的12位的低8位)共同組成。兩個(gè)信號(hào)的所有數(shù)據(jù)都按照這種方法連續(xù)存儲(chǔ)。&l
45、t;/p><p> 如圖4-1所示顯示了100.dat的十六進(jìn)制內(nèi)容的一個(gè)片段。</p><p> 圖 4-1 數(shù)據(jù)文件100.dat的十六進(jìn)制顯示(片段)</p><p> 按照“212”的存儲(chǔ)格式,從第一字節(jié)讀起,每三個(gè)字節(jié)(24位)表示兩個(gè)值,第一組為“E3 33 F3”,兩個(gè)值則分別為Ox3E3和0x3F3,轉(zhuǎn)換為十進(jìn)制分別為995和1011,代表的信號(hào)幅
46、度分別為4.975mv(計(jì)算過程:讀出的數(shù)據(jù)/信號(hào)的增益值)和5.055mv,這兩個(gè)值分別是兩個(gè)信號(hào)的第一個(gè)采樣點(diǎn),后面依此類推,分別表示了兩個(gè)信號(hào)的采樣值。</p><p> 4.1 繪制波形的主要技術(shù)指標(biāo)</p><p> 采樣頻率:信號(hào)的采樣率(該軟件的采樣頻率為360HZ);</p><p> 走速 (走紙速度):屏幕上1mm約等于4個(gè)像素點(diǎn),以標(biāo)準(zhǔn)
47、走速25mm/s為例,每秒鐘在屏幕上顯示100個(gè)像素點(diǎn),小于信號(hào)采集時(shí)的360個(gè)點(diǎn)。所以繪制波形的時(shí)候需要隔點(diǎn)(360/100)讀取原始的采樣數(shù)據(jù)用于繪制波形(25mm/s、50mm/s)。</p><p> 增益 (靈敏度):(5mm/mV、10mm/mV、20mm/mV)繪制波形的時(shí)候根據(jù)增益值得出波形在垂直方向上的增量。</p><p> 由于走速的設(shè)置要求我們隔點(diǎn)讀取數(shù)據(jù),在軟
48、件中標(biāo)準(zhǔn)走速為25mm/s的時(shí)候隔點(diǎn)數(shù)目為3.6,這就需要把存儲(chǔ)波形數(shù)據(jù)的數(shù)組下標(biāo)定義成浮點(diǎn)類型,把誤差降低到最低。</p><p> 4.2 讀取波形數(shù)據(jù)文件</p><p> 繪制波形的數(shù)據(jù)量很大,每個(gè)波形文件中每導(dǎo)波形存儲(chǔ)了650000個(gè)像素?cái)?shù)據(jù),由于外部顯示設(shè)備的寬度限制,不可能一次顯示出所有波形文件,所以在軟件中每次只處理足夠顯示一屏的數(shù)據(jù)量,這就要求我們讀取波形文件的時(shí)候
49、根據(jù)走速設(shè)置每次讀取一定量的數(shù)據(jù),借助滾動(dòng)條顯示下一時(shí)間段的波形時(shí),再讀取文件處理該時(shí)間段的波形數(shù)據(jù)。具體實(shí)現(xiàn)代碼如下所示:</p><p> ReadDat(CString Path)//讀數(shù)據(jù)文件</p><p><b> {</b></p><p><b> m_0 = 0;</b></p>&
50、lt;p><b> m_1 = 0;</b></p><p> CFile dfile;</p><p> if(dfile.Open(Path,CFile::modeReadWrite|CFile::typeBinary) == NULL)</p><p><b> {</b></p><
51、;p><b> return;</b></p><p><b> }</b></p><p> int filelongth = dfile.GetLength();</p><p> unsigned char *pbuf=(unsigned char*)malloc(filelongth*sizeo
52、f(unsigned char));</p><p> int *mydata = (int*)malloc(filelongth*sizeof(int));</p><p> dfile.Read(pbuf,filelongth);</p><p> CSyssetDlg dlg;</p><p> for(float i = m
53、_nHScrollPos*(m_set.m_v*4)*(360/(m_set.m_v*4))*3;i < (m_nHScrollPos*m_set.m_v*4*(360/(m_set.m_v*4))+m_widthwave*(360/(m_set.m_v*4)))*3-1 && i <(filelongth); i = i++)//i表示文件中從0開始的字節(jié)的標(biāo)號(hào),每次只處理可以顯示一屏的數(shù)據(jù)</p&g
54、t;<p><b> {</b></p><p> mydata[(int)i] = pbuf[(int)i];//按字節(jié)讀取文件</p><p><b> }</b></p><p> for (float j = m_nHScrollPos*(m_set.m_v*4)*(360/(m_set
55、.m_v*4))*3+1;j < (m_nHScrollPos*m_set.m_v*4*(360/(m_set.m_v*4))+m_widthwave*(360/(m_set.m_v*4)))*3-2&& j <=(filelongth); j = j++)//j表示移動(dòng)讀數(shù)據(jù)移動(dòng)指針的位置</p><p><b> {</b></p><
56、p> int m = 15&mydata[(int)j];</p><p> int x0 = m*256+mydata[(int)j-1];</p><p><b> j++;</b></p><p> m_data0[m_0] = (float)x0/200-(float)5.120;//得到第
57、一導(dǎo)波形的畫波數(shù)據(jù)</p><p> m_0++;</p><p> int n = 240&mydata[(int)j-1];</p><p><b> n = n>>4;</b></p><p> int x1 = n*256+mydata[(int)j]; </p>
58、<p><b> j++;</b></p><p> m_data1[m_1] = (float)x1/200-(float)5.120;//得到第二導(dǎo)波形的畫波數(shù)據(jù)</p><p><b> m_1++;</b></p><p><b> }</b></p>&
59、lt;p> dfile.Close();</p><p> free(pbuf);</p><p> free(mydata);</p><p><b> }</b></p><p> 4.3 繪制波形的實(shí)現(xiàn)過程</p><p> 實(shí)現(xiàn)連續(xù)波形顯示,連續(xù)波形繪制主要思想是,利用
60、MoveTo和LineTo這兩個(gè)函數(shù),當(dāng)畫完一個(gè)新點(diǎn)后,要將這個(gè)新點(diǎn)的坐標(biāo)記錄下來,作為下一次畫線的起點(diǎn),這樣就解決了連續(xù)繪制波形。</p><p> 繪制波形的代碼如下所示:</p><p> DrawWave(CDC* pDC)//畫波形</p><p><b> {</b></p><p> CSysse
61、tDlg dlg;</p><p> CPen pen3;</p><p> pen3.CreatePen(PS_COSMETIC, 2, m_set.m_wavecolor);//創(chuàng)建波形畫筆</p><p> int startx = 40;</p><p> int endx = startx;</p><
62、;p><b> int endy;</b></p><p> int endy1;</p><p> int top0 = 250-m_nVScrollPos;</p><p> int top1 = 450-m_nVScrollPos;</p><p> m_widthwave = 100*(int)(
63、(pDC->GetDeviceCaps(HORZRES) - 44)/100);</p><p> for (float fi = 0;fi<m_0;fi = fi + (360/(m_set.m_v*4))) //點(diǎn)一下水平滾動(dòng)條時(shí)間是一秒</p><p><b> {</b></p><p> int i = (int)
64、fi;</p><p> if (i == 0)</p><p><b> {</b></p><p> if (m_data0[0]>0)</p><p><b> {</b></p><p> endy = top0 - abs((int)((m_d
65、ata0[0]*m_set.m_up*4)));//得到第一道波形位置點(diǎn)的縱坐標(biāo)值</p><p><b> } </b></p><p><b> else</b></p><p><b> {</b></p><p> endy = top0 + abs((int
66、)((m_data0[0]*m_set.m_up*4)));</p><p><b> } </b></p><p> pDC->MoveTo(startx,endy);</p><p><b> continue;</b></p><p><b> }</b&g
67、t;</p><p><b> else</b></p><p><b> {</b></p><p> if (m_data0[i]>0)</p><p><b> {</b></p><p> endy = top0 - abs((
68、int)((m_data0[i]*m_set.m_up*4)));</p><p><b> } </b></p><p><b> else</b></p><p><b> {</b></p><p> endy = top0 + abs((int)((m_data
69、0[i]*m_set.m_up*4)));</p><p><b> } </b></p><p> pDC->SelectObject(&pen3); </p><p> pDC->LineTo(endx,endy);</p><p><b> }</b></p&
70、gt;<p> endx = endx++;</p><p><b> }</b></p><p> endx = startx;//第一導(dǎo)波形輸出完后把end_x的坐標(biāo)設(shè)置成初始值 </p><p> for (float fii = 0;fii< m_1;fii = fii+(360/(m_set.m_v*4
71、)))</p><p><b> {</b></p><p> int ii = (int)fii;</p><p> if (ii == 0)</p><p><b> {</b></p><p> if (m_data1[0]>0)</p>
72、;<p><b> {</b></p><p> endy1 = top1 - abs((int)((m_data1[0]*m_set.m_up*4)));</p><p><b> } </b></p><p><b> else</b></p><p&
73、gt;<b> {</b></p><p> endy1 = top1 + abs((int)((m_data1[0]*m_set.m_up*4)));</p><p><b> } </b></p><p> pDC->MoveTo(startx,endy1);//心電數(shù)據(jù)中的第一個(gè)點(diǎn)做為起點(diǎn)<
74、/p><p><b> continue;</b></p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> if (m_data1[ii]&g
75、t;0)</p><p><b> {</b></p><p> endy1 = top1 - abs((int)((m_data1[ii]*m_set.m_up*4)));</p><p><b> } </b></p><p><b> else</b></p
76、><p><b> {</b></p><p> endy1 = top1 + abs((int)((m_data1[ii]*m_set.m_up*4)));</p><p><b> } </b></p><p> pDC->LineTo(endx,endy1);</p>
77、<p><b> }</b></p><p> endx = endx++;</p><p><b> }</b></p><p><b> }</b></p><p> 圖 4-2 100.dat的兩導(dǎo)波形片段</p><p>
78、; 如圖4-2所示的波形的采樣頻率為360HZ,走速為標(biāo)準(zhǔn)走速25mm/s,增益值為5mm/mV。背景格中每一個(gè)大格約為20個(gè)像素(5mm)。</p><p> 4.3.1 采用滾動(dòng)條控制顯示特定時(shí)間段的波形</p><p> 每一個(gè)病例信息文件都是由大量的像素點(diǎn)組成,由于屏幕的顯示寬度是有限的,不可能一次顯示出所有的波形文件,所以通過在視圖中加入水平滾動(dòng)條來控制波形的顯示,設(shè)置滑
79、塊在水平滾動(dòng)條上的位置表示波形的時(shí)間,運(yùn)行程序時(shí)調(diào)節(jié)滑塊的位置,可以顯示不同時(shí)間段的波形。如圖4-3所示為滾動(dòng)條的調(diào)節(jié)過程: </p><p> 圖4-3 繪制波形的過程(“nPos”為滑塊在水平滾動(dòng)條上的位置,“m_v”為波形的走速)</p><p> 設(shè)置水平滾動(dòng)條的代碼如下所示:</p><p> void CHeart_viewView::OnHScr
80、oll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)//水平滾動(dòng)條 </p><p><b> {</b></p><p> int nMin = 0;</p><p> int nMax = 0;</p><p> GetScrollRange(SB_HOR
81、Z, &nMin, &nMax);</p><p> switch(nSBCode)</p><p><b> {</b></p><p> case SB_LEFT:</p><p> m_nHScrollPos = max(m_nHScrollPos - 1, nMin);</p>
82、<p><b> break;</b></p><p> case SB_RIGHT:</p><p> m_nHScrollPos = min(m_nHScrollPos + 1, nMax);</p><p><b> break;</b></p><p> case S
83、B_LINELEFT:</p><p> m_nHScrollPos = max(m_nHScrollPos - 1, nMin);</p><p><b> break;</b></p><p> case SB_LINERIGHT:</p><p> m_nHScrollPos = min(m_nHScrol
84、lPos + 1, nMax);</p><p><b> break;</b></p><p> case SB_PAGELEFT:</p><p> m_nHScrollPos = max(m_nHScrollPos - 1, nMin);</p><p><b> break;</b>
85、</p><p> case SB_PAGERIGHT:</p><p> m_nHScrollPos = min(m_nHScrollPos + 1, nMax);</p><p><b> break;</b></p><p> case SB_THUMBTRACK:</p><p>
86、 m_nHScrollPos = nPos;</p><p><b> break;</b></p><p><b> default:</b></p><p><b> return;</b></p><p><b> }</b></p
87、><p> SetScrollPos(SB_HORZ,m_nHScrollPos,TRUE);</p><p> Invalidate(0);</p><p> CView::OnHScroll(nSBCode, nPos, pScrollBar);</p><p><b> }</b></p><
88、;p> void CHeart_viewView::SetHScrollPos()//設(shè)置數(shù)值</p><p><b> {</b></p><p> SCROLLINFO si;</p><p> si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;</p><p> s
89、i.nMin = 0;</p><p> si.nPage = 1;</p><p> si.nMax = 1805;</p><p> si.nPos = m_nHScrollPos;</p><p> SetScrollInfo(SB_HORZ,&si,TRUE);</p><p><b&g
90、t; }</b></p><p> 4.3.2 解決屏幕閃爍現(xiàn)象</p><p> 滾動(dòng)條可以很好的解決波形的顯示,通過調(diào)節(jié)水平滑塊可以方便快速的查看特定時(shí)間段的波形,但同樣也帶來了一個(gè)顯示效果上的問題,由于大量GDI繪圖,快速移動(dòng)滑塊的時(shí)候會(huì)造成屏幕的閃爍現(xiàn)象。解決這一問題采用了雙緩沖技術(shù)。</p><p> 雙緩沖技術(shù):大量GDI繪圖操作(
91、含有擦除操作)直接輸出到屏幕DC時(shí),造成屏幕閃爍。解決辦法:創(chuàng)建并使用后臺(tái)DC進(jìn)行繪制操作,然后將后臺(tái)DC中的內(nèi)容一次拷貝(貼圖)到屏幕DC上,即雙緩沖技術(shù)。相關(guān)實(shí)現(xiàn)代碼如下圖所示:</p><p> MemDC = new CDC;</p><p> MemBitmap = new CBitmap;</p><p> MemDC->CreateComp
92、atibleDC(pDC); </p><p><b> CRect rc;</b></p><p> GetClientRect(&rc);</p><p> MemBitmap->CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());</p><p>
93、; CBitmap *pOldBit = MemDC->SelectObject(MemBitmap);</p><p> MemDC->FillSolidRect(0,0,rc.Width(),rc.Height(),RGB(255,255,255));</p><p> CHeart_viewDoc* pDoc = GetDocument();</p>
94、<p> ASSERT_VALID(pDoc);</p><p> MemDC->SetBkMode(TRANSPARENT);</p><p> MemDC->SetTextColor(m_set.m_textcolor);</p><p> DrawWave(MemDC);</p><p> pDC-
95、>BitBlt(0,0,rc.Width(),rc.Height(),MemDC,0,0,SRCCOPY);</p><p> MemDC->DeleteDC();</p><p> MemBitmap->DeleteObject();</p><p> 5 專家標(biāo)記文件的識(shí)讀</p><p> 注釋文件記錄了心
96、電專家對(duì)相應(yīng)心電信號(hào)的診斷信息,主要有兩種格式:MIT格式和AHA格式。MIT格式是一種緊簇型格式,每一注釋的長度占用偶數(shù)個(gè)字節(jié)的空間,多數(shù)情況下是占用兩個(gè)字節(jié),多用于在線的注釋文件;而AHA格式的每一注釋占用16個(gè)字節(jié)的空間,多用于交換文件的情況。在這里簡要說明一下常用的MIT格式的存儲(chǔ)方式,每一注釋單元的前兩個(gè)字節(jié)的第一個(gè)字節(jié)為最低有效位,16位中的最高6位表示了注釋類型代碼,剩余的10位說明了該注釋點(diǎn)的發(fā)生時(shí)間或?yàn)檩o助信息,若為發(fā)
97、生時(shí)間,其值為該注釋點(diǎn)到前一注釋點(diǎn)的間隔(對(duì)于第一個(gè)注釋點(diǎn)為從記錄的開始到該點(diǎn)的間隔),若為輔助信息則說明了附加信息的長度。這兩種格式的在文件中的區(qū)分決定于前兩個(gè)字節(jié)的值,判斷是MIT格式還是AHA格式的條件是:若文件的第一字節(jié)不為0或第二字節(jié)等于“[”(0x5B)或“]”(0x5D),則該文件是以MIT格式存儲(chǔ)的,否則是按AHA格式存儲(chǔ)的。</p><p> 5.1 專家標(biāo)記文件的讀取</p>
98、<p> 下面以記錄100的注釋文件100.atr為例進(jìn)行說明,圖5-1顯示了100.atr的十六進(jìn)制內(nèi)容的一個(gè)片段。</p><p> 圖 5-1 注釋文件100.atr的十六進(jìn)制顯示(片段)</p><p> 從第一字節(jié)開始按照MIT格式進(jìn)行分析,首先讀出16位值0x7012,其高6位的值為0x1C(十進(jìn)制28),10位的值為0x12,該類型代碼為28,代表意義是節(jié)律
99、變化,發(fā)生時(shí)間在0.05秒(18/360Hz);接著讀出后面的16位值0xFC03,其高6位的值為0x3F(十進(jìn)制63),低10位的值為0x03,該類型代碼為63,代表的意義是在該16位值后附加了3個(gè)(低10位值代表的數(shù))字節(jié)的輔助信息,若字節(jié)個(gè)數(shù)為奇數(shù),則再附加一個(gè)字節(jié)的空值,在本例中就是“28 00 00 4E”;然后再從下一字節(jié)讀16位值0x043B,其高6位的值為1,低10位的值為0x3B(十進(jìn)制59),該類型碼1代表正常心搏,
100、發(fā)生時(shí)間為0.213秒((18+59)/360Hz);依次類推即可讀出所有的注釋,當(dāng)讀到的16位值為0時(shí),就表示到了文件尾。當(dāng)高6位為十進(jìn)制59時(shí),讀取之后第3個(gè)16位的高6位,作為類型代碼,讀取之后第二個(gè)16位+第一個(gè)16位*2^16;高6位為十進(jìn)制60,61,62時(shí),繼續(xù)讀下一個(gè)16位。讀取專家標(biāo)記文件的實(shí)現(xiàn)過程如下所示:</p><p> int *mode;</p><p>&
101、lt;b> int *t;</b></p><p><b> int *f;</b></p><p> int *sumt;</p><p> int v = 1;</p><p><b> int s;</b></p><p> CFile f
102、atr;</p><p> CString mask;</p><p> if (fatr.Open(m_Adest,CFile::modeReadWrite|CFile::typeBinary) == NULL)</p><p><b> {</b></p><p><b> return;</
103、b></p><p><b> } </b></p><p><b> else</b></p><p><b> {</b></p><p> int filelongth = fatr.GetLength();</p><p>
104、unsigned char *pbuf = (unsigned char*)malloc(filelongth*sizeof(unsigned char));//從腳標(biāo)為0的開始存</p><p> mode = (int*)malloc(filelongth*sizeof(int));</p><p> t = (int*)malloc(filelongth*sizeof(int))
105、;</p><p> f = (int*)malloc(filelongth*sizeof(int));</p><p> sumt = (int*)malloc(filelongth*sizeof(int));</p><p> fatr.Read(pbuf,filelongth);</p><p> int q = 0;</
106、p><p> int u = 0;</p><p> sumt[0] = 0;</p><p> if (pbuf[0] != 0 || pbuf[1] == 91 || pbuf[1] == 93)</p><p><b> {</b></p><p> for ( int k = 0;k
107、 < filelongth - 2;)//k是指向低字節(jié)的變量</p><p><b> {</b></p><p> int aa = pbuf[k+1]&252;//讀取數(shù)據(jù)碼的過程</p><p> mode[v-1] = aa>>2;</p><p> if (mode[
108、v-1] > 0 && mode[v-1] <= 41)</p><p><b> {</b></p><p> int cc = ((pbuf[k+1]&3)<<8) + pbuf[k];</p><p> sumt[v] = sumt[v-1] + cc;//獲取時(shí)間點(diǎn)信息&l
109、t;/p><p><b> v++;</b></p><p><b> q++; </b></p><p> k = k + 2;</p><p><b> continue;</b></p><p><b> }</b>
110、;</p><p> if (mode[v-1] == 59)</p><p><b> {</b></p><p> int low_8 = pbuf[k+2];</p><p> int heigt_8 = pbuf[k+3]<<8;//左移8位</p><p>
111、 int first = ((low_8 + heigt_8)*2)^16;</p><p> low_8 = pbuf[k+4];</p><p> heigt_8 = pbuf[k+5]<<8;</p><p> int second = low_8 + heigt_8;</p><p> t[q] = fi
112、rst + second;//計(jì)算時(shí)間</p><p> sumt[v] = sumt[v-1] + t[q];//獲取時(shí)間點(diǎn)信息</p><p><b> v++;</b></p><p><b> q++;</b></p><p> k = k + 6;//需要獲取時(shí)間</p>
113、;<p> continue; </p><p><b> }</b></p><p> if (mode[v-1] == 60||mode[v-1] == 61||mode[v-1] == 62)</p><p><b> {</b></p><p> k = k + 2;
114、//不獲取時(shí)間</p><p><b> continue;</b></p><p><b> }</b></p><p> if (mode[v-1] == 63)</p><p> {//需要計(jì)算輔助信息</p><p> int dd = ((pbuf[k+1
115、]&3)<<8) + pbuf[k];</p><p> if (dd%2 != 0)</p><p><b> {</b></p><p> k = k + dd + 3;</p><p><b> }</b></p><p><b>
116、 else</b></p><p><b> {</b></p><p> k = k + dd + 2;</p><p><b> }</b></p><p><b> u++;</b></p><p><b>
117、 continue;</b></p><p><b> }</b></p><p><b> }</b></p><p> s = v - 1;</p><p> int i = 0;//時(shí)間定位相關(guān)</p><p> memset(m_fix,0,s
118、izeof(m_fix));</p><p> for(v = 1;v <= s;v++)</p><p><b> {</b></p><p> if (mode[v-1] == m_fixmode && m_fixflag == 1)</p><p><b> {<
119、/b></p><p> m_fix[i] = (int)(sumt[v]/360);</p><p> m_fixi = i;//記錄存在的時(shí)間點(diǎn)的個(gè)數(shù)</p><p><b> i++;</b></p><p><b> }</b></p><p><
120、;b> }</b></p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p><b> return;</b></p><p>
121、;<b> }</b></p><p><b> }</b></p><p> 5.2 專家標(biāo)記文件的顯示</p><p> 每一屏波形有固定的時(shí)間間隔,但是對(duì)應(yīng)的每一屏標(biāo)記信號(hào)并沒有固定的時(shí)間間隔,也不存在發(fā)生的時(shí)間規(guī)律,但是需要與波形文件在時(shí)間上達(dá)到同步。所以在處理專家標(biāo)記文件的時(shí)候采用的篩選標(biāo)記的方法,在特
122、定時(shí)間段中篩選出符合條件的標(biāo)記文件,具體代碼如下所示:</p><p> for (v = 1;v <= s;v++)</p><p><b> {</b></p><p> int maskt;</p><p> if (m_set.m_v == 25)</p><p>
123、<b> {</b></p><p> maskt = (int)(m_widthwave/(m_set.m_v*4) + 0.5);//計(jì)算一屏的顯示時(shí)間</p><p><b> } </b></p><p><b> else</b></p><p><b&
124、gt; {</b></p><p> maskt = (int)(m_widthwave/(m_set.m_v*4) + 0.5);</p><p><b> }</b></p><p> if (sumt[v] >= (m_nHScrollPos)*360 && sumt[v] <= (mas
125、kt + m_nHScrollPos)*360)</p><p><b> {</b></p><p> switch(mode[v-1])</p><p><b> {</b></p><p> case 1: mask = "N";break;</p>
126、<p> case 2: mask = "L";break;</p><p> case 3: mask = "R";break;</p><p> case 4: mask = "a";break;</p><p> case 5: mask = "V";break;
127、</p><p> case 6: mask = "F";break;</p><p> case 7: mask = "J";break;</p><p> case 8: mask = "A";break;</p><p> case 9: mask = "S&
128、quot;;break;</p><p> case 10: mask = "E";break;</p><p> case 11: mask = "j";break;</p><p> case 12: mask = "/";break;</p><p> case 13:
129、 mask = "Q";break;</p><p> case 14: mask = "~";break;</p><p> case 16: mask = "|";break;</p><p> case 18: mask = "s";break;</p><
130、;p> case 19: mask = "T";break;</p><p> case 20: mask = "*";break;</p><p> case 22: mask = "\"";break;</p><p> case 23: mask = "="
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 心電圖分析與心律失常
- 異常心電圖心律失常
- 心電圖及心律失常
- 心電圖與心律失常
- 心律失常心電圖轉(zhuǎn)
- 常見心律失常心電圖分析簡化
- 心律失常心電圖表現(xiàn)
- 心律失常心電圖分析診斷與鑒別
- 心電圖心律失常的識(shí)別
- MIT-BIH生理信號(hào)管理及回放系統(tǒng).pdf
- 心律失常心電圖解法
- 常見心律失常的心電圖閱讀
- 常見心律失常的心電圖識(shí)別
- 心律失常的心電圖解析
- 基于心電圖分析的心律失常分類.pdf
- 心律失常分析
- 遺傳性心律失常心電圖特點(diǎn)
- 正常心電圖與常見心律失常心電圖對(duì)比學(xué)習(xí)
- 心電圖監(jiān)測(cè)、圍術(shù)期心律失常
- 常見心律失常心電圖診斷的誤區(qū)
評(píng)論
0/150
提交評(píng)論