VTK 體繪制_體繪制管線&圖形渲染管線


1.幾何渲染與體繪制

1.1 幾何渲染

前面練習的渲染技術都是幾何渲染技術。所謂的幾何渲染技術,就是通過繪制幾何圖元(頂點、線段、面片等)來渲染數據,例如:繪制圖像需要在空間中建立一個四邊形圖元,然后以紋理映射的方式將該圖像貼圖到該圖元上進行渲染;而三維模型的繪制通常會分解為一系列的多邊形面片進行繪制。這種通過生成中間幾何圖元來進行渲染的方法稱為幾何渲染。
幾何渲染的速度比較快,但是不能顯示體數據的內部細節。例如:在渲染人的三維CT體數據時,通過幾何渲染只能在切片圖像之間進行切換,而不能對體數據內部細節進行立體觀察。

1.2 體繪制

體繪制技術,更多的時候,我們把它稱為三維重建(區別於投影圖像的三維重建),是一種直接利用體數據來生成二維圖像的繪制技術。與面繪制不同,體繪制不需要提取體數據內部的等值面,它是對三維體數據進行采樣和合成的過程。體數據能過通過設置不透明度值來顯示體數據內部的不同成分和細節,例如顯示人體CT圖像的不同器官和組織。

2.圖形渲染管線

在進行體繪制管線學習之前,很有必要回顧一下前面的VTK可視化管線的基本組成。
我習慣把渲染窗口vtkRenderWindow看做一個劇院,劇院中一般需要燈光(vtkLight)、相機(vtkCamera)和舞台(vtkRenderer)來呈現精彩的演出。
舞台上負責表演的自然就是演員(vtkActor),而且演員往往不止一個,可以根據需要為舞台加入更多的演員(vtkActor)。
每個演員又各具特色,而用來表示其特色的則是vtkProperty(負責控制值顏色、材質和不透明度等);
每個vtkActor的數據和渲染信息存儲在一個vtkMapper對象中,負責將原始數據轉換為渲染所需要的圖元數據。

3.體繪制管線

從可視化管線的組成上來講,體繪制的渲染管線與幾何渲染管線基本一致,先通過一個實例進行初步認識:
 1 #include <vtkAutoInit.h>
 2 VTK_MODULE_INIT(vtkRenderingOpenGL);  3 VTK_MODULE_INIT(vtkRenderingVolumeOpenGL); //錯誤:no override found for 'vtkRayCastImageDisplayHelper'.
 4 VTK_MODULE_INIT(vtkRenderingFreeType);  5 VTK_MODULE_INIT(vtkInteractionStyle);  6  
 7 #include <vtkSmartPointer.h>
 8 #include <vtkStructuredPoints.h>
 9 #include <vtkStructuredPointsReader.h>
 10 #include <vtkFixedPointVolumeRayCastMapper.h>
 11 #include <vtkColorTransferFunction.h>
 12 #include <vtkPiecewiseFunction.h>
 13 #include <vtkRenderer.h>
 14 #include <vtkRenderWindow.h>
 15 #include <vtkRenderWindowInteractor.h>
 16 #include <vtkVolumeProperty.h>
 17 #include <vtkAxesActor.h>
 18 #include <vtkOrientationMarkerWidget.h>
 19  
 20 int main(int argc, char *argv[])  21 {  22     vtkSmartPointer<vtkStructuredPointsReader> reader =
 23         vtkSmartPointer<vtkStructuredPointsReader>::New();  24     reader->SetFileName("mummy.128.vtk");  25     reader->Update();  26  
 27  
 28     vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> volumeMapper =
 29         vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New();  30     volumeMapper->SetInputData(reader->GetOutput());  31  
 32     //設置光線采樣距離  33     //volumeMapper->SetSampleDistance(volumeMapper->GetSampleDistance()*4);  34     //設置圖像采樣步長  35     //volumeMapper->SetAutoAdjustSampleDistances(0);  36     //volumeMapper->SetImageSampleDistance(4);
 37     /*************************************************************************/
 38     vtkSmartPointer<vtkVolumeProperty> volumeProperty =
 39         vtkSmartPointer<vtkVolumeProperty>::New();  40     volumeProperty->SetInterpolationTypeToLinear();  41     volumeProperty->ShadeOn();  //打開或者關閉陰影測試
 42     volumeProperty->SetAmbient(0.4);  43     volumeProperty->SetDiffuse(0.6);  //漫反射
 44     volumeProperty->SetSpecular(0.2); //鏡面反射  45     //設置不透明度
 46     vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =
 47         vtkSmartPointer<vtkPiecewiseFunction>::New();  48     compositeOpacity->AddPoint(70, 0.00);  49     compositeOpacity->AddPoint(90, 0.40);  50     compositeOpacity->AddPoint(180, 0.60);  51     volumeProperty->SetScalarOpacity(compositeOpacity); //設置不透明度傳輸函數  52     //compositeOpacity->AddPoint(120, 0.00);//測試隱藏部分數據,對比不同的設置  53     //compositeOpacity->AddPoint(180, 0.60);  54     //volumeProperty->SetScalarOpacity(compositeOpacity);  55     //設置梯度不透明屬性
 56     vtkSmartPointer<vtkPiecewiseFunction> volumeGradientOpacity =
 57         vtkSmartPointer<vtkPiecewiseFunction>::New();  58     volumeGradientOpacity->AddPoint(10, 0.0);  59     volumeGradientOpacity->AddPoint(90, 0.5);  60     volumeGradientOpacity->AddPoint(100, 1.0);  61     volumeProperty->SetGradientOpacity(volumeGradientOpacity);//設置梯度不透明度效果對比  62     //設置顏色屬性
 63     vtkSmartPointer<vtkColorTransferFunction> color =
 64         vtkSmartPointer<vtkColorTransferFunction>::New();  65     color->AddRGBPoint(0.000, 0.00, 0.00, 0.00);  66     color->AddRGBPoint(64.00, 1.00, 0.52, 0.30);  67     color->AddRGBPoint(190.0, 1.00, 1.00, 1.00);  68     color->AddRGBPoint(220.0, 0.20, 0.20, 0.20);  69     volumeProperty->SetColor(color);  70     /********************************************************************************/
 71     vtkSmartPointer<vtkVolume> volume =
 72         vtkSmartPointer<vtkVolume>::New();  73     volume->SetMapper(volumeMapper);  74     volume->SetProperty(volumeProperty);  75  
 76     vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();  77     ren->SetBackground(0, 1, 0);  78     ren->AddVolume(volume);  79  
 80     vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New();  81     rw->AddRenderer(ren);  82     rw->SetSize(640, 480);  83     rw->Render();  84     rw->SetWindowName("VolumeRendering PipeLine");  85  
 86     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
 87         vtkSmartPointer<vtkRenderWindowInteractor>::New();  88     rwi->SetRenderWindow(rw);  89     /********************************************************************************/
 90     //vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();  91     //axes->SetScale(10);  92     //vtkSmartPointer<vtkOrientationMarkerWidget> widget =  93     // vtkSmartPointer<vtkOrientationMarkerWidget>::New();  94     //widget->SetOutlineColor(1, 1, 1);  95     //widget->SetViewport(0, 0, 0.2, 0.2);  96     //widget->SetOrientationMarker(axes);  97     //widget->SetInteractor(rwi);  98     //widget->SetEnabled(1);  99     //widget->InteractiveOn();
100  
101     ren->ResetCamera(); 102     rw->Render(); 103     rwi->Start(); 104  
105     return 0; 106 }
#vtkVolumeRayCastMapper:
vtkVolumeRayCastMapper定義了一個光線投影體繪制Mapper,其主要接受如下兩個輸入。
SetInputData(vtkImageData*):該函數用於設置輸入圖像數據。
SetVolumeRayCastFunction(vtkVolumeRayCastFunction*):該函數用於設置光線透射函數類型。
vtkVolumeRayCastCompositeFunction是vtkVolumeRayCastFunction的子類,定義了光線經過體數據后的顏色計算方式。
需要注意的是,這個類備受很多科研人員職責,在VTK7.0.0之后會被移除。
這里我采用vtkFixedPointVolumeRayCastMapper以避免如下錯誤:
#vtkVolumeProperty:
該類定義了體繪制屬性,設置標量不透明度傳輸函數、梯度不透明度函數、顏色傳輸函數、陰影。
vtkVolumeProperty用於設置體繪制的屬性,決定體繪制的渲染效果,其中:
  • SetScalarOpacity(vtkPiecewiseFunction* function):該類用於設置灰度不透明度函數。
  • SetColor(vtkColorTransferFunction *function):該類用於設置顏色傳輸函數。
#vtkVolume:
vtkVolume與幾何渲染中的vtkActor作用一致,需要設置如下兩個輸入:
  • void SetMapper(vtkAbstractVolumeMapper* mapper):該函數用於設置Mapper對象。
  • void SetProperty(vtkVolumeProperty* property):該函數用於設置屬性對象。
#定義vtkRenderer、vtkRenderWindow、vtkRenderWindowInteractor對象,建立可視化管線。
體繪制渲染結果如下:

4.圖形渲染管線與體繪制渲染管線對比

通過上面代碼可以看出,體繪制渲染管線與幾何渲染管線的組成是比較一致的,都需要vtkRenderWindow、vtkRenderer、vtkActor/vtkVolume、vtkMapper等對象。
它們不同之處在於:
  • 幾何渲染中,通常使用vtkActor來渲染幾何圖像數據,使用vtkImageActor來渲染圖像數據;而在體繪制中,則使用vtkVolume渲染數據。
  • 在幾何渲染中,通常采用vtkPolyDataMapper實現輸入數據向圖元數據的轉換;在體繪制中,則采用vtkVolumeRayCastMapper,要切記的是,這個類是與體繪制的算法相關的,不同的體繪制算法會有不同的Mapper類。
更一般的,幾何圖像渲染管線與體繪制的渲染管線對比圖如下:
虛線部分表示兩者不同之處,從上圖我們能夠看出來,兩種渲染方式不同點主要在Mapper和Actor對象上。

5.no override found for 'vtkRayCastImageDisplayHelper'修訂

體繪制過程中,出現如下錯誤:
這也是一個初始化的問題,解決辦法如下:
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM