本發(fā)明屬于計算機應(yīng)用程序開發(fā)的領(lǐng)域,特別涉及一種將dicompyler的圖像讀取到C++圖像類的方法。
背景技術(shù):
目前,dicompyler是一個基于DICOM標準的可擴展的開源放射治療研究開發(fā)工具包,同時它也是一個跨平臺的DICOM RT閱讀器。dicompyler是用Python開發(fā)的,其中使用了PIL(Python Imaging Library,Python圖像庫)來存儲、顯示DICOM RT的醫(yī)學圖像。
PIL提供了廣泛的文件格式支持,高效的內(nèi)部數(shù)據(jù)表示和相當強大的圖像處理能力,再加上Python是一門語言簡易、開發(fā)簡單、跨平臺性良好以及公用庫多的編程語言,更重要的是Python的開發(fā)效率高,綜合上述兩個優(yōu)勢,dicompyler深受廣大醫(yī)學圖像研究者的熱愛。
但是,由于Python是一門解釋型的語言,也就是說Python開發(fā)的功能模塊沒有經(jīng)過編譯的過程,各功能模塊依賴于Python解釋器而運行,所以Python功能模塊的執(zhí)行效率不高。為了提高程序的執(zhí)行效率,可以選擇將Python的功能模塊嵌入到C++應(yīng)用程序中,而這就延伸到了如何利用C++調(diào)用dicompyler功能模塊,更進一步的是利用C++調(diào)用Python的PIL功能模塊。
因此,需要提供一種將dicompyler的圖像讀取到C++圖像類的方法,既提高了程序的開發(fā)效率,也保證了程序的執(zhí)行效率,同時也縮短了應(yīng)用程序的開發(fā)周期。
技術(shù)實現(xiàn)要素:
本發(fā)明的目的在于克服現(xiàn)有技術(shù)的缺點與不足,提供一種將dicompyler的圖像讀取到C++圖像類的方法,其具有方法靈活、內(nèi)存管理安全的優(yōu)點。
為此,本發(fā)明采用如下方案:
一種將dicompyler的圖像讀取到C++圖像類的方法,其包括以下步驟:
a、初始化連接器的連接參數(shù);
b、初始化Python解釋器,并加載精簡后的dicompyler功能模塊;
c、獲取dicompyler功能模塊的圖像對象,并獲取圖像尺寸以及圖像模式;
d、利用Python提供的C-API間接觸發(fā)數(shù)據(jù)轉(zhuǎn)換函數(shù),將圖像數(shù)據(jù)轉(zhuǎn)換為字符串的形式,并得到經(jīng)過封裝的字符串對象;
e、利用上一步得到的字符串對象以及Python提供的參數(shù)解析函數(shù),提取字符串對象的字符串數(shù)據(jù),并將字符串數(shù)據(jù)讀入到C/C++的內(nèi)存數(shù)組中;
f、將內(nèi)存數(shù)組的圖像數(shù)據(jù)復(fù)制到C++的圖像類里面,根據(jù)獲取的圖像尺寸設(shè)置圖像類的尺寸大小,必要時根據(jù)圖像模式設(shè)置顏色表,最終完成DICOM RT數(shù)據(jù)的讀取。
優(yōu)選的,所述的步驟a中,所述的連接參數(shù)就是清單依賴項(manifestdependency)的參數(shù),包括連接器的類型、名稱、版本處理器架構(gòu)以及公匙的標記。
優(yōu)選的,所述的步驟b中,精簡后的dicompyler功能模塊包括dicomparser、dvhdoses和dvhcalc三個模塊,而加載dicompyler功能模塊的步驟如下:
b1、執(zhí)行初始化函數(shù)用以初始化Python解釋器;
b2、判斷Python解釋器是否成功初始化,如果初始化失敗,退出程序;否則,繼續(xù)下面的步驟;
b3、執(zhí)行模塊加載函數(shù)用以加載功能模塊,并得到該模塊對象。
優(yōu)選的,所述的步驟c中,獲取dicompyler功能模塊的圖像對象的步驟如下:
c1、利用步驟b3得到的模塊對象,提取其中的字典對象;
c2、利用步驟c1得到的字典對象,尋找自定義類的入口,得到一個類接口對象;
c3、實例化步驟c2得到的類接口對象,得到類實例對象;
c4、類實例對象執(zhí)行圖像獲取函數(shù)即可得到圖像對象。
優(yōu)選的,所述的步驟d中,將圖像數(shù)據(jù)轉(zhuǎn)換為字符串的形式是通過步驟c4所得到的圖像對象的tostring()函數(shù)實現(xiàn)的,該函數(shù)將數(shù)據(jù)封裝到一個字符串對象中。tostring()函數(shù)內(nèi)部實現(xiàn)步驟如下:
d1、根據(jù)字符串對象的數(shù)據(jù)成員以及圖像數(shù)據(jù)的大小,申請一段大小足夠的內(nèi)存塊;
d2、將數(shù)據(jù)復(fù)制到申請的內(nèi)存塊的數(shù)據(jù)區(qū)域。
優(yōu)選的,所述的步驟e中,將字符串數(shù)據(jù)讀入到C/C++的內(nèi)存數(shù)組的步驟如下;
e1、聲明一個指向字符類型的指針;
e2、結(jié)合步驟d所得到的字符串對象以及參數(shù)解析函數(shù),解析字符串對象,解析完畢之后,步驟e1聲明的指針就指向字符串對象的數(shù)據(jù)內(nèi)存;
e3、申請一段大小足夠的內(nèi)存空間,將步驟e1聲明的指針所指向的數(shù)據(jù)復(fù)制到該內(nèi)存空間。
優(yōu)選的,所述的步驟f中,所述的C++的圖像類可以選用CImage、CBitmap或者QImage,設(shè)置深度值、顏色表等相關(guān)參數(shù),以完成DICOM RT的數(shù)據(jù)讀取。
本發(fā)明與現(xiàn)有技術(shù)相比,具有如下優(yōu)點和有益效果:
本發(fā)明提出了一種利用C++讀取dicompyler的圖像對象的圖像數(shù)據(jù)的方法,實現(xiàn)了利用dicompyler讀取的DICOM RT醫(yī)學圖像與C++可執(zhí)行程序在圖像提取以及圖像處理方面的交互,充分發(fā)揮了dicompyler對DICOM RT醫(yī)學圖像的充分支持,使得在程序開發(fā)過程中,既提高了程序的開發(fā)效率,也保證了程序的執(zhí)行效率,同時也縮短了應(yīng)用程序的開發(fā)周期。具有極大的實用性,適用于各種軟件,尤其是醫(yī)學圖像處理軟件開發(fā)的設(shè)備。
附圖說明
圖1是本發(fā)明的實現(xiàn)流程圖。
具體實施方式
下面結(jié)合附圖對本發(fā)明作進一步詳細的描述,但本發(fā)明的實施方式不限于此。
dicompyler除了包含DICOM RT數(shù)據(jù)讀取模塊外,還包含了其他輔助的用戶界面功能模塊,為了簡化開發(fā)過程,必須對整個dicompyler功能模塊進行簡化,而簡化的方式就是利用Python支持的面向?qū)ο蟮木幊谭绞?,?gòu)建出自定義模塊,具體步驟如下:
1、保留dicompyler的三個核心模塊,分別是DICOM RT解析模塊dicomparser、劑量體積直方圖模塊dvhdoses以及劑量體積直方圖計算模塊dvhcalc;
2、在上述三個模塊的基礎(chǔ)上自定義名為Patient.pyc的功能模塊,該模塊里面自定義了名為Patient的類,該類就是圖像數(shù)據(jù)轉(zhuǎn)化的核心類,其中定義了獲取圖像、圖像大小、圖像模式等操作。
由于dicompyler功能模塊使用了VS2008編譯,為了能夠成功加載dicompyler功能模塊,必須在加載前設(shè)置清單依賴項(manifestdependency)的參數(shù),具體參數(shù)為type='win32',name='Microsoft.VC90.CRT',version='9.0.21022.8',processorArchitecture='x86',publicKeyToken='1fc8b3b9a1e18e3b'。
為了利用C++加載自定義的功能模塊,必須先調(diào)用Py_Initialize()函數(shù)初始化Python解釋器,然后調(diào)用Py_IsInitialized()函數(shù)判斷Python解釋器是否成功初始化,如果初始化失敗,則直接退出程序,否則,繼續(xù)下面的步驟。
Python解釋器成功初始化后,就要加載Patient.pyc功能模塊和獲取模塊里面的圖像對象實例,具體的步驟如下:
1、以"Patient"為參數(shù)調(diào)用PyImport_ImportModule()函數(shù)加載Patient.pyc模塊,該函數(shù)返回對應(yīng)的模塊對象;
2、以步驟1得到的模塊對象為參數(shù)調(diào)用PyModule_GetDict()函數(shù),該函數(shù)返回描述模塊對象內(nèi)部包含的屬性以及功能的字典對象;
3、以步驟2得到的字典對象和自定義的類名Patient為參數(shù)調(diào)用PyDict_GetItemString()函數(shù),該函數(shù)返回類接口對象,該類接口對象是Patient.pyc功能模塊自定義的類;
4、以步驟3得到的類接口對象和NULL為參數(shù)調(diào)用PyObject_CallObject()函數(shù),該函數(shù)返回類實例對象;
5、以步驟4得到的類實例對象、"GetImage"字符串、"(i)"和0為參數(shù)調(diào)用PyObject_CallMethod()函數(shù),該函數(shù)返回圖像對象,其中的"GetImage"字符串就是自定義類內(nèi)部的圖像獲取函數(shù)。
成功獲取了圖像對象后,首先要獲取圖像對象的尺寸以及模式以便設(shè)置C++圖像類的參數(shù),步驟如下:
1、利用圖像對象和PyObject_GetAttrString()函數(shù)獲取圖像對象的尺寸屬性,該尺寸屬性是一個字符串對象,然后執(zhí)行PyArg_Parse()函數(shù)解析字符串對象,即可獲取圖像對象的寬和高,利用獲取的寬和高創(chuàng)建C++圖像類實例;
2、利用圖像對象和PyObject_GetAttrString()函數(shù)獲取圖像對象的模式屬性,該模式屬性是一個字符串對象,然后執(zhí)行PyArg_Parse()函數(shù)解析字符串對象,即可獲取圖像對象的模式,如果模式為L,表明圖像是單通道8bit的灰度圖像,如果模式為RGB,表明圖像是3通道24bit的圖像;
接下來是關(guān)鍵的數(shù)據(jù)提取部分,以圖像對象以及"tostring"字符串為參數(shù)調(diào)用PyObject_CallMethod()函數(shù),該步驟的作用是間接觸發(fā)圖像對象的tostring()函數(shù),也就是將數(shù)據(jù)圖像轉(zhuǎn)換為字符串的形式,從而得到字符串對象,因為圖像數(shù)據(jù)以及字符串數(shù)據(jù)在計算機內(nèi)存里面的取值范圍都是[0,255],所以這種轉(zhuǎn)換是可行的,更重要的是Python本身提供與C/C++交互的字符串處理函數(shù)。tostring()函數(shù)內(nèi)部實現(xiàn)步驟如下:
1、根據(jù)字符串對象的數(shù)據(jù)成員以及圖像數(shù)據(jù)的大小,申請一段大小足夠的內(nèi)存塊;
2、將數(shù)據(jù)復(fù)制到申請的內(nèi)存塊的數(shù)據(jù)區(qū)域。
由于所得到的字符串對象是經(jīng)過封裝后的數(shù)據(jù)結(jié)構(gòu),將字符串對象中的字符串數(shù)據(jù)提取并讀入到C/C++的內(nèi)存數(shù)組的步驟如下;
1、聲明一個指向字符類型的指針;
2、結(jié)合上述所得到的字符串對象以及參數(shù)解析函數(shù),解析字符串對象,解析完畢之后,上述步驟聲明的指針就指向字符串對象的數(shù)據(jù)內(nèi)存;
3、申請一段大小足夠的內(nèi)存空間,將上述步驟聲明的指針所指向的數(shù)據(jù)復(fù)制到該內(nèi)存空間。
將圖像數(shù)據(jù)讀入到C/C++的內(nèi)存后,C/C++應(yīng)用程序即可操作這些數(shù)據(jù),為了能夠?qū)⒆罱K的DICOM RT數(shù)據(jù)顯示出來,可以選用CImage、CBitmap或者QImage等相關(guān)的圖像類,并把上述讀取出來的圖像數(shù)據(jù)復(fù)制到圖像類的數(shù)據(jù)空間。
以上所述,僅為本發(fā)明較佳的實施方式,但本發(fā)明的實施方式并不受上述實施例的限制,其他的任何未背離本發(fā)明的精神實質(zhì)與原理下所作的改變、修飾、替代、組合、簡化,均應(yīng)為等效的置換方式,都包含在本發(fā)明的保護范圍之內(nèi)。