VTK:一个面向对象的可视化类库(zz)
(高雋 黃偉 合肥工業大學計算機與信息學院 合肥 230009)
??????? 摘要 Visualization Toolkit 是一個面向對象的可視化類庫,它為從事可視化應用程序開發的廣大科研工作者提供直接的技術支持。VTK 具有及其強大的功能,不僅提供了強大的可視化功能,而且還提供了強大的圖像處理以及有線元分析的功能,能夠對標量場,矢量場以及張量場數據進行重建。對于廣大從事可視化應用研究以及可視化應用程序與系統開發的科研工作者來說,VTK 具有非常重要的意義。本文介紹了VTK 的機制特點和框架,并簡要介紹了一個VTK 在醫學可視化應用中的實現。
關鍵詞 科學計算可視化、面向對象程序設計、Visualization Toolkit、3D 重建、CT
1. 引言
?????? 科學計算可視化(Visualization in Scientific Computing) 是1987 年由B.H.McCormick等人根據美國國家科學基金會召開的“科學計算可視化研討會”的內容撰寫的一份報告中正式提出來的[7][8]。 隨后,美國西歐日本各著名大學、研究所、超級計算機中心、各大公司紛紛進行科學計算可視化理論和方法的研究,科學計算可視化迅速成為計算機科學中一個熱門的研究領域。
?????? 可視化是運用計算機圖形學和圖像處理技術,將科學計算過程中及計算結果的數據轉換為圖形及圖像在屏幕上顯示出來并進行交互處理的理論,方法和技術[11]。 近些年來隨著計算機硬件水平的提高和可視化理論方法的不斷完善,可視化在許多領域都得到了廣泛的應用,如有限元分析,計算機斷層掃描CT 及核磁共振MRI 數據的可視化等[9]。但是隨著可視化技術在許多其它領域的廣泛應用,也暴露出一些急待解決的問題。因為對于許多并不是專業從事可視化研究的科研人員來說,雖然他們對于可視化也有很強烈的需求,但是由于對可視化程序的開發并不熟悉,因而在其研究工作中面臨著不少現實的困難。如果能有一個專門的可視化開發工具,能夠簡化可視化程序的開發,將會極大的提高我們的工作效率。
?????? 本文介紹了一個基于Windows/Unix 環境的面向對象的可視化開發工具VisualizationToolkit,它將一些常用的算法和在可視化程序的開發過程中會經常遇到的細節屏蔽起來,以類庫的形式給我們的開發工作以直接的支持,極大的簡化了我們的開發工作和提高了我們的工作效率。
2. 可視化開發工具Visualization Toolkit
?????? 隨著可視化技術在各個學科領域的廣泛應用,對于廣大從事可視化研究領域的科研人員來說,迫切需要一種功能強大的可視化開發工具來給我們的研究工作提供強有力的支持。我們在本文中采用的是Will Schroeder, Ken Martin, Bill Lorensen 等人用C++語言開發的一個基于Windows 和Unix 環境的面向對象的可視化工具Visualization Toolkit。
???????Visualization Toolkit 把可視化開發過程中的一些細節屏蔽起來,以類庫的形式給從事可視化程序開發的研究者提供支持,使我們可以方便快捷的開發出高性能的可視化應用程序。
2.1 Visualization Toolkit 的機制
??????? Visualization Toolkit 是一個用于可視化應用程序構造與運行的支撐環境。它是在三維函數庫OpenGL 的基礎上,采用面向對象的設計方法發展起來的。它將我們在可視化開發過程中會經常遇到的細節屏蔽起來,并將一些常用的算法封裝起來。比如Visualization Toolkit 將我們在表面重建中比較常見的Marching Cubes 算法封裝起來,以類的形式給我們以支持。這樣我們在對三維規則點陣數據進行表面重建時,就不必再重復編寫Marching Cubes 算法的代碼,而直接使用Visualization Toolkit 中已經提供的vtkMarchingCubes 類。
??????? Visualization Toolkit 采用的是Pipeline 機制,幾乎可以對任何類型的數據進行處理,并提供了許多相應的類對各種類型的數據進行轉換或處理。根據所要處理的原始數據類型的不同和所使用的算法以及所要達到的結果,我們可以設計和建立起自己的可視化流程,并由此選擇不同的數據處理和轉換的類,用數據通道將這些類連接起來,將原始數據類型轉換為所采用的算法模塊可以直接進行處理的數據類型,最終得到我們所需要的可視化的結果。而且所有的類和算法模塊都是可擴充的,用戶可以將自己開發的類或模塊轉換成系統可以接受的形式,并可替換或擴充原有的類。所以Visualization Toolkit 是一個開放的系統,可以擴展到任何應用領域。
2.2 Visualization Toolkit 的特點
?????? Visualization Toolkit 是給從事可視化應用程序開發工作的研究人員提供直接的技術支持的一個強大的可視化開發工具。它以用戶使用的方便性和靈活性為主要原則,具有如下的特點:
1. 具有強大的三維圖形功能Visualization Toolkit 既支持基于體素Voxel-basedrendering 的體繪制Volume Rendering [4] ,又保留了傳統的面繪制,從而在極大的改善可視化效果的同時,又可以充分利用現有的圖形庫和圖形硬件。
???????2. Visualization Toolkit 的體系結構使其具有非常好的流streaming 和高速緩存caching 的能力。在處理大量的數據時不必考慮內存資源的限制。
?????? 3. Visualization Toolkit 能夠更好的支持基于網絡的工具,比如Java 和VRML。 隨著Web 和Internet 技術的發展Visualization Toolkit 有著很好的發展前景。
???? ??4. 能夠支持多種著色如OpenGL 等。
?????? 5. Visualization Toolkit 具有設備無關性使其代碼具有良好的可移植性。
?????? 6. Visualization Toolkit 中定義了許多宏。這些宏極大的簡化了編程工作并且加強了一致的對象行為。
?????? 7. Visualization Toolkit 具有更豐富的數據類型,支持對多種數據類型進行處理。
?????? 8. 既可以工作于Windows 操作系統又可以工作于Unix 操作系統極大的方便了用戶。
目前與Visualization Toolkit 類似的可視化系統還有AVS89 和Haber91。其中AVS89是第一個商業可視化系統。AVS89 和Haber91 都采用的是抽象的數據模型,這雖然使它們有更廣泛的數據表達能力和更大的靈活性,但這也使得它們更容易導致計算機代碼和接口的混亂,而且也會使得使用者由于誤解而造成誤操作。Visualization Toolkit 采用的是更具體的數據模型,一方面是為了是用戶更容易掌握和使用,另一方面是因為VisualizationToolkit 數據模型已經足夠支持我們的可視化實踐。
3. Visualization Toolkit 的框架結構
?????? 用面向對象技術的對象模型圖表示Visualization Toolkit 的框架結構如圖1 所示:
?
Visualization Toolkit 采用的是流水線pipeline 的機制,根據所獲得的原始數據的類型以及所要得到的顯示結果,我們可以選擇適當的算法,并構建起自己的可視化流程。在用可視化工具Visualization Toolkit 對體數據進行可視化的過程中,首先應按照所設計的可視化過程對原始數據進行處理,將其轉換為適當的數據形式并映射為幾何數據,然后將幾何數據的屬性告訴將要在窗口中顯示的演員actor。
?????? Visualization Toolkit 一個很特別的地方是對于任何進行可視化的數據,它都是通過演員在窗口中表現出來的。
?????? vtkObject 是Visualization Toolkit 類庫的基類,它為整個可視化流程提供基本的方法。vtkSource 是vtkObject 的派生類和vtkFilter 的父類,它為整個可視化流程的開始(比如讀取數據等)定義具體的行為和接口。vtkFilter 是vtkSource 的派生類,它對數據進行各種處理,將原始數據經過各種filter 的處理后,轉換為可以直接用某種算法模塊對其進行處理的形式。vtkMapper 也是vtkObject 的派生類,它將經過各種filter 處理后的應用數據映射為幾何數據,為原始數據與圖像數據之間定義了接口。vtkActor 類用來表達繪制場景中的一個實體,也就是繪制場景中的演員,它通過SetMapper()方法將幾何數據的屬性告訴演員,然后通過vtkRender 類將結果在窗口中顯示出來。
?
4. 利用Visualization Toolkit 對數據進行可視化的實例
??????? 使用Visualization Toolkit 對數據進行可視化十分方便,程序的結構也正如我們所設計的可視化流程一樣,十分簡潔明了。下面我們將利用Visualization Toolkit, 就可視化應用研究中一個十分熱門的領域——計算機斷層掃描CT, 簡單剖析一下利用VisualizationToolkit 進行數據可視化的實現[1]~[3]。
????? ? 我們將要進行處理的CT 數據是一個人體頭部的切片數據,共有93 個切片。切片的間距是1.5mm ,每個切片由有12 個灰度級的間距為0.8 毫米的256*256 像素構成[6] 。我們打算由這些切片數據恢復出皮膚和骨骼的表面。為此我們首先應選取合適的算法,考慮到我們所處理的數據量是非常龐大的,超過了12 兆比特,而且我們只打算對表面進行重建,所以我們選擇基于表面重建的經典算法Marching Cubes 算法。而對于Marching Cubes算法,Visualization Toolkit 中已經有封裝好的vtkMarchingCubes 給予支持,這樣就進一步簡化了我們的工作。
?????? Marching Cube 算法是Lorensen 等人于1987 提出的,是三維數據場等值面生成的經典算法,是體素單元內等值面抽取技術的代表,并一直沿用至今。
?????? Marching Cube 算法的基本思想是在數據體中將位于兩個相臨切片上的8 個相臨的體素構成一個立方體(cube) ,逐個處理數據場中的立方體,分類出與等值面相交的立方體,采用插值計算出等值面與立方體邊的交點。根據立方體每一頂點與等值面的相對位置,將等值面與立方體邊的交點按一定方式連接生成等值面,作為等值面在該立方體內的一個逼近表示[7][10]。
4.1 讀取數據
?????? 首先,我們要做的事情是讀取切片數據,并將其轉換為我們的開發工具VisualizationToolkit 所支持的一種數據表達形式;然后根據其物理結構建立起相應的模型,我們給CT數據建立的是比較抽象的等值面模型;最后將物理組件與抽象的模型結合在一起來建立對CT 數據的可視化,以幫助用戶正確理解數據。我們所要進行處理的是有結構點陣數據,其拓撲和幾何都是隱含知道的,所以我們只需要知道數據的維數、數據源和數據空間。利用Visualization Toolkit 中的vtkVolume16Reader 我們可以很方便的讀取切片數據,只需要告訴讀取數據對象我們的CT 數據的一些參數,如切片之間的間距、切片上像素之間的間距以及所讀取切片的起始段(如從第1 個切片到45 個切片),讀取數據的代碼如下所示:
?
vtkVolume16Reader?*Reader?=?vtkVolume16Reader::New();???????????? //建立一個讀取對象???????Reader->SetDataDimensions(256,256);?????????????????????????????????//設置數據的維數
???????Reader->SetDataByteOrderToLittleEndian?();
???????Reader->SetFilePrefix?("..?/..?/..?/vtkdata/headsq/quarter");??????//設置所讀取切片數據文件的路徑
??????Reader->SetImageRange(1,?93);???????????????????????????????????????????//設置讀取切片的起始段
??????Reader->SetDataSpacing?(0.8,?0.8,?1.5);???????????????????????????????//設置切片之間的間距和像素之間的間距?
?
4.2 提取等值面
?????? 下面我們就可以用Marching Cubes 算法對所讀取的數據進行處理了。首先利用vtkMarchingCubes 類來提取出某一CT 值的等值面,但這時的等值面其實仍只是一些三角面片,還必須由vtkStripper 類將其拼接起來形成連續的等值面。這樣就把讀取的原始數據經過處理轉換為應用數據,也即由原始的點陣數據轉換為多邊形數據然后由vtkPolyDataMapper 將其映射為幾何數據,并將其屬性賦給窗口中代表它的演員,將結果顯示出來。
?
//?從切片數據中提取出皮膚?????vtkMarchingCubes?*skinExtractor?=?vtkMarchingCubes::New();?????? //建立一個Marching?Cubes?算法的對象
?????skinExtractor->SetInput(Reader->GetOutput());??????????????????????????//獲得所讀取的CT?數據
?????skinExtractor->SetValue(0,?500);??????????????????????????????????????????????//提取出CT?值為500?的皮膚
?????vtkStripper?*skinStripper?=?vtkStripper::New();???????????????????????????//建立三角帶對象
?????skinStripper->SetInput(skinExtractor->GetOutput());????????????????? ?//將生成的三角片連接成三角帶
?????vtkPolyDataMapper?*skinMapper?=?vtkPolyDataMapper::New();???? //建立一個數據映射對象
?????skinMapper->SetInput(skinStripper->GetOutput());??????????????????? ?//將三角帶映射為幾何數據
?????vtkActor?*skin?=?vtkActor::New();???????????????????????????????????????????//建立一個代表皮膚的演員
?????skin->SetMapper(skinMapper);????????????????????????????????????????????????//獲得皮膚幾何數據的屬性
?????skin->GetProperty()->SetDiffuseColor(1,?.49,?.25);?????????????????? ??//設置皮膚顏色的屬性
?????skin->GetProperty()->SetSpecular(.3);????????????????????????????????????//設置反射率
?????skin->GetProperty()->SetSpecularPower(20);???????????????????????????//設置反射光強度?
?
利用同樣的方法,我們也可以提取出骨骼的等值面。只是骨骼的CT 值是1150 左右而已。所以只要在SetValue()方法中將參數設置為1150 就可以了。而且Visualization Toolkit支持多表面重建,所以在實際應用中我們可以設置多個參數值,提取出多個等值面并同時顯示出來。在這個應用實例中我們只對皮膚和骨骼地的等值面進行了重建。
4.3 顯示結果
?????? 通過前面這些工作,我們基本上已經完成了對數據的讀取處理映射等步驟,下面我們就要對數據進行顯示了。
?????vtkRenderWindow?*renWindow?=?vtkRenderWindow::New();?????????????????????//建立繪制窗口
?????renWindow->AddRenderer(ren);??????????????????????????????????????????????????????????//將繪制者加入繪制窗口
?????vtkRenderWindowInteractor?*iren?=?vtkRenderWindowInteractor::New();?? //對繪制結果進行交互操作
?????iren->SetRenderWindow?(renWindow);?????????????????????????????????????????????????//?告訴繪制者將要在繪制窗口中進行顯示的演員
?????ren->AddActor(skin);???????????????????????????????????????????????????????????????????????//皮膚
?????ren->AddActor(bone);?????????????????????????????????????????????????????????????????????//骨骼?
?
5. 結束語
?????? Visualization Toolkit 是采用C++語言設計的一個基于Windows/Unix 環境的面向對象對象的可視化類庫,具有十分強大的可視化功能。與MFC 強大的圖形界面功能相結合,可以方便快捷的開發出高性能的可視化程序,并且可以在不同的開發環境下使用,如Microsoft Visual C++ Borland C++等。對于一般的用戶,它屏蔽了一些常見算法和復雜的數據處理過程,使不具備可視化程序開發經驗的用戶也可以方便快捷地編制可視化程序。同時對于具有可視化程序開發經驗的用戶,VTK也提供了相應的方法使用戶可以對其進行改進,以支持對可視化程序的行優化,在開發可視化程序的過程中具有十分重要的意義。
參考文獻
[1] Sabe P. A Rendering Algorithm for Visualization 3D Scalar Fields. Computer Graphics, August 1988,22(4):
51~58
[2] W.C.Lin, C.C.Liang, C.T.Chen, Dynamic elastic interpolation for 3D medical image reconstruction from
serial cross sections, IEEE Trans. On Medical Imaging, Vol.7, No.3, 1988,225~232
[3] G.T.Herman and H.K.Lin, Three-dimensional display of human organs from Computed Tomograms, CVGIP9, 1979, 1-21
[4] Krueger W, Volume rendering and feature enhancement, Computer Graphics, 1990,24(5): 21~26
[5] Max N. Area and Volume Coherence for Efficient Visualization of 3D Scalar Functions. Computer Graphics,
1990, 24(5): 27~33
[6] Will Schroeder, Ken Martin, Bill Lorensen, Visualization Toolkit 2nd Edition - An Object-Oriented
Approach to 3D Graphics, Prentice Hall, 1988
[7] 管偉光:《體視化技術及其應用》北京 電子工業出版社1998
[8] 管偉光:《體數據可視化及其在醫學中的應用》中國科學院自動化所博士論文1995
[9] 呂維雪:《醫學圖像處理》北京 高等教育出版社1989
[10] 唐澤圣:《三維數據場可視化》北京 清華大學出版社1999
[11] 石教英、蔡立文:《科學計算可視化算法與系統》北京 科學出版社1996
【Jati 注】
//在我的VTK?5.0.2中,相應的測試程序代碼如下:
#include?"vtkVolume16Reader.h"
#include?"vtkRenderWindowInteractor.h"
#include?"vtkRenderer.h"
#include?"vtkRenderWindow.h"
#include?"vtkMarchingCubes.h"
#include?"vtkStripper.h"
#include?"vtkActor.h"
#include?"vtkPolyDataMapper.h"
#include?"vtkProperty.h"
//讀取RAW文件,提取等值面。
int?main()
{
??????vtkVolume16Reader?*reader=vtkVolume16Reader?::New();
??????reader->SetDataDimensions(64,64);
??????reader->SetDataByteOrderToLittleEndian();
??????reader->SetFilePrefix("D://headsq//quarter");
??????reader->SetImageRange(1,93);
??????reader->SetDataSpacing(3.2,3.2,1.5);
??????vtkMarchingCubes?*boneExtractor=vtkMarchingCubes::New();
??????boneExtractor->SetInput((vtkDataObject?*)reader->GetOutput());
??????boneExtractor->SetValue(0,500);
??????vtkStripper?*boneStripper=vtkStripper::New();
??????boneStripper->SetInput(boneExtractor->GetOutput());
?
???????vtkPolyDataMapper?*boneMapper=vtkPolyDataMapper::New();
???????boneMapper->SetInput(boneStripper->GetOutput());
???????vtkActor?*bone=vtkActor::New();
???????bone->SetMapper(boneMapper);
???????bone->GetProperty()->SetDiffuseColor(.1,.94,.52);
???????bone->GetProperty()->SetSpecular(.3);
???????bone->GetProperty()->SetSpecularPower(20);
???????vtkRenderer?*ren=vtkRenderer::New();
???????vtkRenderWindow?*renWindow=vtkRenderWindow::New();
???????renWindow->AddRenderer(ren);
???????vtkRenderWindowInteractor?*iren=vtkRenderWindowInteractor::New();
???????iren->SetRenderWindow(renWindow);
???????ren->AddActor(bone);
???????iren->Initialize();
???????iren->Start();
???????reader->Delete();
???????iren->Delete();
???????return?0;
}
http://www.cnblogs.com/jati/archive/2008/05/11/1192327.htm posted on 2008-11-27 14:45 GXW 閱讀(...) 評論(...) 編輯 收藏
轉載于:https://www.cnblogs.com/Fancyboy2004/archive/2008/11/27/1342284.html
總結
以上是生活随笔為你收集整理的VTK:一个面向对象的可视化类库(zz)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电话骗术升级了,提高警惕! (转自公司
- 下一篇: 只能打开一进程