VTK 圖形基本操作進階_多分辨率策略(模型抽取的三種方法)


1.多分辨率處理策略

模型抽取(Decimation)和細化(Subdivision)是兩個相反的操作,是三角形網格模型多分辨處理中的兩個重要操作。使用這兩個操作可以在保持模型拓撲結構的同時,得到不同分辨率的網格模型。模型抽取的作用是減少模型中的點數據和單元數據,便於模型的后續處理與交互渲染,這類似於圖像數據的降采樣。而網格細化則是利用一定的細化規則,在給定的初始網格中插入新的點,從而不斷細化出新的網格單元,在極限細化情況下,該網格能夠收斂一個光華的曲面。

2.網格抽取(Decimation)

2.1 vtkDecimatePro

VTK中主要有三種網格抽取類:vtkDecimatePro、vtkQuadricDecimation、vtkQuadricClustering。
vtkDecimatePro是最常用的,該處理方法的原理參考文獻[1],是用一種邊塌陷的方法來刪除點和單元,處理速度比較快,而且可以方便的控制網格抽取的幅度,得到不同級別的模型數據。
該類的使用方法,如下:
1 vtkSmartPoint<vtkDecimatePro> decimate = vtkSmartPointer<vtkDecimatePro>::New(); 2 decimate->SetInput(input); 3 decimate->SetTargetReduction(0.6); 4 decimate->update();
vtkDecimatePro接收一個單元為三角網格的vtkPolyData數據,其中函數SetTargetReduction()用於設置變量TargetReduction的大小,將網格面片抽取的比例控制在0~1.這里設置為0.6,說明有60%的三角面片單元將被移除。使用這個函數可以得到不同程度的簡化網格模型,不過,為確保函數效果,一般需要滿足下面四個條件:
  • vtkDecimatePro需要支持模型拓撲的改變,即將PreserveTopology變量的值設置為FALSE。
  • 支持網格分裂,即Splitting變量的值設置為TRUE。
  • 支持修改模型的邊界,即將變量BoundaryVetexDeletion的值設置為TRUE。
  • 設置最大誤差變量MaximumError的值為VTK_DOUBLE_MAX。
在滿足這四個條件情況下,可以得到不同簡化程度的模型。如果上面四個條件不滿足,最終得到的模型簡化率並非所期望的簡化率。

2.2 vtkQuadricDecimation

該類也可以實現三角形網格簡化,並能較好地逼近原模型。該簡化算法思想可以參考文獻[2]。該類雖然也提供了SetTargetReduction()函數用於設置模型簡化程度,但是最終簡化率並非嚴格等於程序中設置的簡化率。可以通過GetActualReduction()函數來獲取最終模型簡化率。

2.3 vtkQuadricClustering

該類是三種實現模型抽取算法中最快的一種,能夠處理大數據模型。其算法思想可以參考文獻[3]。通過StartAppend()、Append()、EndAppend()函數可以將整個模型分為多個網格片處理,從而避免一次性處理整個模型,減少內存開支,提高處理效率。

3.vtkDecimatePro用於模型抽取實驗

作為結果觀測實驗,這里僅僅使用vtkDecimatePro類實現模型抽取。
示例代碼如下:
 1 #include <vtkAutoInit.h>
 2 VTK_MODULE_INIT(vtkRenderingOpenGL);  3 VTK_MODULE_INIT(vtkRenderingFreeType);  4 VTK_MODULE_INIT(vtkInteractionStyle);  5  
 6 #include <vtkSmartPointer.h>
 7 #include <vtkPolyDataReader.h>
 8 #include <vtkDecimatePro.h>
 9 #include <vtkPolyDataMapper.h>
10 #include <vtkActor.h>
11 #include <vtkRenderer.h>
12 #include <vtkCamera.h>
13 #include <vtkRenderWindow.h>
14 #include <vtkRenderWindowInteractor.h>
15  
16 int main() 17 { 18     vtkSmartPointer<vtkPolyDataReader> reader =
19         vtkSmartPointer<vtkPolyDataReader>::New(); 20     reader->SetFileName("fran_cut.vtk"); 21     reader->Update(); 22  
23     vtkSmartPointer<vtkPolyData> original = reader->GetOutput(); 24     std::cout << "抽取前"<< "-----------------------" << std::endl; 25     std::cout << "模型點數為: " << original->GetNumberOfPoints() << std::endl; 26     std::cout << "模型面數為: " << original->GetNumberOfPolys() << std::endl; 27  
28     vtkSmartPointer<vtkDecimatePro> decimation =
29         vtkSmartPointer<vtkDecimatePro>::New(); 30     decimation->SetInputData(reader->GetOutput()); 31     decimation->SetTargetReduction(0.6); 32     decimation->Update(); 33  
34     vtkSmartPointer<vtkPolyData> decimated = decimation->GetOutput(); 35     std::cout << "抽取后"<< "-----------------------" << std::endl; 36     std::cout << "模型點數為:" << decimated->GetNumberOfPoints() << std::endl; 37     std::cout << "模型面數為:" << decimated->GetNumberOfPolys() << std::endl; 38     /
39     vtkSmartPointer<vtkPolyDataMapper> origMapper =
40         vtkSmartPointer<vtkPolyDataMapper>::New(); 41     origMapper->SetInputData(reader->GetOutput()); 42     vtkSmartPointer<vtkActor> origActor =
43         vtkSmartPointer<vtkActor>::New(); 44     origActor->SetMapper(origMapper); 45  
46     vtkSmartPointer<vtkPolyDataMapper> deciMapper =
47         vtkSmartPointer<vtkPolyDataMapper>::New(); 48     deciMapper->SetInputData(decimation->GetOutput()); 49     vtkSmartPointer<vtkActor> deciActor =
50         vtkSmartPointer<vtkActor>::New(); 51     deciActor->SetMapper(deciMapper); 52     /// 53     double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; 54     double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 }; 55  
56     vtkSmartPointer<vtkRenderer> leftRenderer =
57         vtkSmartPointer<vtkRenderer>::New(); 58     leftRenderer->SetViewport(leftViewport); 59     leftRenderer->AddActor(origActor); 60     leftRenderer->SetBackground(1.0, 0, 0); 61  
62     vtkSmartPointer<vtkRenderer> rightRenderer =
63         vtkSmartPointer<vtkRenderer>::New(); 64     rightRenderer->SetViewport(rightViewport); 65     rightRenderer->AddActor(deciActor); 66     rightRenderer->SetBackground(0, 0, 0); 67  
68     leftRenderer->GetActiveCamera()->SetPosition(0, -1, 0); 69     leftRenderer->GetActiveCamera()->SetFocalPoint(0, 0, 0); 70     leftRenderer->GetActiveCamera()->SetViewUp(0, 0, 1); 71     leftRenderer->GetActiveCamera()->Azimuth(30); 72     leftRenderer->GetActiveCamera()->Elevation(30); 73     leftRenderer->ResetCamera();//刷新照相機
74     rightRenderer->SetActiveCamera(leftRenderer->GetActiveCamera());//同步顯示
75     /// 76     vtkSmartPointer<vtkRenderWindow> rw =
77         vtkSmartPointer<vtkRenderWindow>::New(); 78     rw->AddRenderer(leftRenderer); 79     rw->AddRenderer(rightRenderer); 80     rw->SetSize(640, 320); 81     rw->SetWindowName("PolyData Decimation"); 82  
83     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
84         vtkSmartPointer<vtkRenderWindowInteractor>::New(); 85     rwi->SetRenderWindow(rw); 86     rwi->Start(); 87  
88     return 0; 89 }
輸出結果如下圖所示:
左圖為原始圖像,右圖為簡化后的效果,從圖總可以看出,簡化后的模型面片數量減少,模型變得非常粗糙。


免責聲明!

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



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