mit-bih心律失常心電圖分析軟件畢業(yè)論文_第1頁
已閱讀1頁,還剩33頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論