1. 程式人生 > 實用技巧 >VTK 圖形處理之顏色對映

VTK 圖形處理之顏色對映

顏色對映

  顏色對映的操作物件是資料集中的標量屬性。它是一種常用的 標量演算法。它會根據資料集中各個部分不同的標量值,對各個部分上不同的顏色。與此相關的另一種上色方法是控制演員的顏色屬性,但這樣整個圖形只有單一的顏色,這顯然沒有顏色對映方法靈活。
  建立多邊形資料集程式執行 結果顯示的彩色立方體就用到了顏色對映。由於對 立方體的6個頂點設定了不同的標量值(點id),所以這6個點的顏色不同。至於立方體其他部分的顏色,也是通過標量值對映來的,不過這些標量值並不是手動設定,而是根據鄰近的頂點的標量值,運用某種內插演算法計算出來的。

顏色對映過程

  假設有一個共256種顏色的查詢表,且顏色的索引號範圍為0~255,那麼顏色對映就是將資料集的標量值對映到這些索引號的過程。在渲染時,與索引號對應的顏色將作為資料中相應部分的顏色顯示出來。對映的方法如下圖所示。


  

  上圖中,scalar表示資料集中的標量值,index表示對映後的索引號。smin和smax表示的是標量值的對映範圍(注意不是資料集中標量值的取值範圍)。若一個標量值小於smin,則其對映的索引號為0;若一個標量值大於smax,其對映的索引號為255;若一個標量值在這個範圍之間,則對映過程就是一個求一元一次函式值的過程,其對應的曲線是一條直線,不過需要對函式值取整。實際上,在範圍外的標量值也可以被看作smin和smax,然後對其求函式值。
  在VTK中,顏色對映的過程是由對映器mapper完成的。可以通過呼叫對映器的方法SetScalarRange()來設定標量值的範圍[smin, smax]。對映過程只是為每個標量值確定了一個索引號,最終該標量值對映為何種顏色,還需要看顏色查詢表中顏色的分配情況。如果不手動建立一個查詢表,則對映器會使用一個預設的對映表。

示例演示

CMakeLists.txt檔案程式碼如下:

1 CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
2 PROJECT(LookupTableExample)
3 FIND_PACKAGE(VTK REQUIRED)
4 INCLUDE(${VTK_USE_FILE})
5 ADD_EXECUTABLE(LookupTableExample lookuptable.cpp)
6 TARGET_LINK_LIBRARIES(LookupTableExample ${VTK_LIBRARIES})

C++程式碼:

 1 #include "vtkActor.h
" 2 #include "vtkCellArray.h" 3 #include "vtkFloatArray.h" 4 #include "vtkPointData.h" 5 #include "vtkPoints.h" 6 #include "vtkPolyData.h" 7 #include "vtkPolyDataMapper.h" 8 #include "vtkRenderWindow.h" 9 #include "vtkRenderWindowInteractor.h" 10 #include "vtkRenderer.h" 11 #include <vtkLookupTable.h> 12 #include "vtkSmartPointer.h" 13 14 int main() 15 { 16 int i; 17 //定義立方體的頂點座標 18 static float x[8][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, 19 { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 1, 1 } }; 20 //定義單元,每4個頂點建立一個四邊形單元,共計6個單元 21 static vtkIdType pts[6][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 0, 1, 5, 4 }, 22 { 1, 2, 6, 5 }, { 2, 3, 7, 6 }, { 3, 0, 4, 7 } }; 23 //建立物件 24 vtkSmartPointer<vtkPolyData> cube = vtkSmartPointer<vtkPolyData>::New(); 25 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); 26 vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New(); 27 //儲存頂點 28 for (i = 0; i < 8; i++) 29 points->InsertPoint(i, x[i]); 30 //設定單元 31 for (i = 0; i < 6; i++) 32 polys->InsertNextCell(4, pts[i]); 33 34 //儲存標量值 35 vtkSmartPointer<vtkFloatArray> scalars = vtkSmartPointer<vtkFloatArray>::New(); 36 //設定每個頂點的標量值 37 for (i = 0; i < 8; i++) 38 scalars->InsertTuple1(i, i*4); 39 //建立多邊形資料 40 cube->SetPoints(points); 41 //設定單元型別為多邊形 42 cube->SetPolys(polys); 43 //設定每個頂點的標量值 44 cube->GetPointData()->SetScalars(scalars); 45 //定義顏色對映表 46 vtkSmartPointer<vtkLookupTable> pColorTable = vtkSmartPointer<vtkLookupTable>::New(); 47 //設定顏色表中的顏色 48 pColorTable->SetNumberOfColors(256); 49 pColorTable->SetHueRange(0.67, 0.0); //色調範圍從紅色到藍色 50 pColorTable->Build(); 51 //資料對映 52 vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); 53 cubeMapper->SetInputData(cube); 54 cubeMapper->SetScalarRange(0, 7); 55 cubeMapper->SetLookupTable(pColorTable); 56 vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New(); 57 cubeActor->SetMapper(cubeMapper); 58 59 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); 60 vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New(); 61 renWin->AddRenderer(renderer); 62 vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New(); 63 iren->SetRenderWindow(renWin); 64 renderer->AddActor(cubeActor); 65 renderer->SetBackground(1, 1, 1); 66 renWin->SetSize(500, 500); 67 renWin->Render(); 68 iren->Start(); 69 return 0; 70 }

執行結果:

分析


有時候,標量資料就是顏色值,並不需要通過查詢表進行對映。對此,對映器提供了以下一些方法來進行控制。
● SetColorModeToDefault()該方法執行預設的對映器行為,即把unsigned char型別的標量屬性資料當作顏色值,不執行隱式。對於其他型別的標量資料,將通過查詢表對映。
● SetColorModeToMapScalars()無論變數資料是何種型別,該方法都通過查詢表對標量資料進行對映。如果標量資料的每個元組有多個分量,則對第0個分量進行對映。 


注意事項:
1. 如果沒有標量資料,則對映器將不能使用查詢表控制物件的顏色。這時可以使用演員物件來控制顏色。
2. 如果想阻止顏色對映,可呼叫對映器的ScalarVisibilityOff()方法。


呼叫ScalarVisibilityOn()方法後,可以控制對映器的顏色對映行為:
● SetScalarModeToDefault()執行預設的對映行為:如果有點標量屬性資料,則用其進行對映,如果沒有點標量屬性資料但有單元標量屬性資料,則用單元標量屬性資料進行對映,否則不對映。
● SetScalarModeToUsePointData()總是使用點標量屬性資料進行對映的。如果沒有嗲按標量屬性資料,就不進行對映。
● SetScalarModeToUseCellData()總是使用單元標量屬性資料進行對映的。如果沒有單元標量屬性資料,就不進行對映。
● SetScalarModeToUsePointFieldData()不使用點或單元標量屬性資料,而是使用點屬性資料中的一般屬性資料來進行對映的。該方法應該與ColorByArrayComponent()結合使用,以用來指定用於顏色對映的資料。
● SetScalarModeToUseCellFieldData()不使用點或單元標量屬性資料,而是使用單元屬性資料中的一般屬性資料來進行對映的。該方法應該與ColorByArrayComponent()結合使用,以用來指定用於顏色對映的資料