VTK 圖形基本操作進階_網格平滑(點雲的曲面重建技術)


1.網格平滑

現代掃描技術的發展使得獲取點雲數據不再困難,通過曲線重建技術可以獲取表面網格來表示各種復雜的實體。但是點雲數據中往往存在噪聲,這樣得到的重建網格通常都需要進行平滑處理。
拉普拉斯平滑是一種常用的網格平滑算法。該方法的原理比較簡單,如下圖所示:
將每個點用其鄰域點的中心來代替。通過不斷地迭代,可以得到較為光滑的網格。
VTK中,VTKSmoothPolyDataFilter類實現了網格的拉普拉斯平滑算法,使用方法如下:
 1 #include <vtkAutoInit.h>
 2 VTK_MODULE_INIT(vtkRenderingOpenGL);  3 VTK_MODULE_INIT(vtkInteractionStyle);  4 VTK_MODULE_INIT(vtkRenderingFreeType);  5  
 6 #include <vtkSmartPointer.h>
 7 #include <vtkPolyDataReader.h>
 8 #include <vtkSmoothPolyDataFilter.h>
 9 #include <vtkPolyDataMapper.h>
10 #include <vtkActor.h>
11 #include <vtkRenderer.h>
12 #include <vtkRenderWindow.h>
13 #include <vtkRenderWindowInteractor.h>
14 int main() 15 { 16     vtkSmartPointer<vtkPolyDataReader> reader =
17         vtkSmartPointer<vtkPolyDataReader>::New(); 18     reader->SetFileName("fran_cut.vtk"); 19     reader->Update(); 20  
21     vtkSmartPointer<vtkSmoothPolyDataFilter> smoothFilter =
22         vtkSmartPointer<vtkSmoothPolyDataFilter>::New(); 23     smoothFilter->SetInputConnection(reader->GetOutputPort()); 24     smoothFilter->SetNumberOfIterations(100); 25     smoothFilter->Update(); 26     /
27     vtkSmartPointer<vtkPolyDataMapper> inputMapper =
28         vtkSmartPointer<vtkPolyDataMapper>::New(); 29     inputMapper->SetInputConnection(reader->GetOutputPort()); 30     vtkSmartPointer<vtkActor> inputActor =
31         vtkSmartPointer<vtkActor>::New(); 32     inputActor->SetMapper(inputMapper); 33  
34     vtkSmartPointer<vtkPolyDataMapper> smoothedMapper =
35         vtkSmartPointer<vtkPolyDataMapper>::New(); 36     smoothedMapper->SetInputConnection(smoothFilter->GetOutputPort()); 37     vtkSmartPointer<vtkActor> smoothedActor =
38         vtkSmartPointer<vtkActor>::New(); 39     smoothedActor->SetMapper(smoothedMapper); 40     /
41     double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; 42     double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 }; 43  
44     vtkSmartPointer<vtkRenderer> leftRenderer =
45         vtkSmartPointer<vtkRenderer>::New(); 46     leftRenderer->SetViewport(leftViewport); 47     leftRenderer->AddActor(inputActor); 48     leftRenderer->SetBackground(1, 0, 0); 49     leftRenderer->ResetCamera(); 50  
51     vtkSmartPointer<vtkRenderer> rightRenderer =
52         vtkSmartPointer<vtkRenderer>::New(); 53     rightRenderer->SetViewport(rightViewport); 54     rightRenderer->AddActor(smoothedActor); 55     rightRenderer->SetBackground(0, 0, 0); 56     rightRenderer->ResetCamera(); 57     /
58     vtkSmartPointer<vtkRenderWindow> rw =
59         vtkSmartPointer<vtkRenderWindow>::New(); 60     rw->AddRenderer(leftRenderer); 61     rw->AddRenderer(rightRenderer); 62     rw->SetSize(640, 320); 63     rw->SetWindowName("PolyData Grid Smooth By LapLasian"); 64  
65     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
66         vtkSmartPointer<vtkRenderWindowInteractor>::New(); 67     rwi->SetRenderWindow(rw); 68     rwi->Initialize(); 69     rwi->Start(); 70     return 0; 71 }
vtkSmoothPolyDataFilter::SetNumberOfIterations()控制平滑次數,次數越多平滑的越厲害。200次的平滑效果如下圖所示:
左圖為原始模型,右圖為平滑后模型。從圖中可以看出,經過200次Laplace平滑后,模型變得相當的光滑,但是在平滑的同事也損失了一些細節信息。
其實在該類中還有多個變量來控制平滑過程,利用這些變量在一定程度上可以控制細節的損失。
BoundarySmoothing:控制是否對邊界點平滑。這里需要理解邊界點的概念,在一個網格模型中,一條邊只被一個單元包含那么這條邊就是邊界邊,而邊界邊上的點則為邊界點。如果一個模型中含有邊界邊,則說明該模型不是封閉的,正如圖中的一樣。
FeatureEdgeSmoothing:控制是否對特征邊上的點進行平滑。如果一條邊被兩個鄰近的多邊形共用,若兩個多邊形法向量的夾角(特征角)大於定義的閾值,則說明該邊為一條特征邊。因此,FeatureEdgeSmoothing設置開始時,需要調用SetFeatureAngle()函數設置特征角的閾值。具體如圖所示:
特征角越大,說明改邊越尖銳。特征邊/角往往表達模型的細節,平滑過程中最好不要進行處理,以保護細節不受損傷。
雖然通過特征邊平滑設置可以降低一部分細節損失,但並不能完全避免,且隨着laplace平滑的不斷迭代,模型會逐漸向網格的中心收縮。所以,vtkWindowSincPolyDataFilter是一種更好的選擇,該算法采用窗口Sinc函數實現網格平滑,能夠最小程度地避免收縮,vtkWindowSincPolyDataFilter的用法和VTKSmoothPolyDataFilter用法完全一致。
1 vtkSmartPointer<vtkWindowedSincPolyDataFilter> wndSincSmoothFilter =
2         vtkSmartPointer<vtkWindowedSincPolyDataFilter>::New(); 3     wndSincSmoothFilter->SetInputConnection(reader->GetOutputPort()); 4     wndSincSmoothFilter->SetNumberOfIterations(10); 5     wndSincSmoothFilter->Update();
算法的輸出結果如下所示:


免責聲明!

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



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