VTK修炼之道49:图形基本操作进阶_网格平滑(点云的曲面重建技术)
生活随笔
收集整理的這篇文章主要介紹了
VTK修炼之道49:图形基本操作进阶_网格平滑(点云的曲面重建技术)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.網格平滑
現代掃描技術的發展使得獲取點云數據不再困難,通過曲線重建技術可以獲取表面網格來表示各種復雜的實體。但是點云數據中往往存在噪聲,這樣得到的重建網格通常都需要進行平滑處理。 拉普拉斯平滑是一種常用的網格平滑算法。該方法的原理比較簡單,如下圖所示:將每個點用其鄰域點的中心來代替。通過不斷地迭代,可以得到較為光滑的網格。 VTK中,VTKSmoothPolyDataFilter類實現了網格的拉普拉斯平滑算法,使用方法如下: #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkRenderingFreeType);#include <vtkSmartPointer.h> #include <vtkPolyDataReader.h> #include <vtkSmoothPolyDataFilter.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> int main() {vtkSmartPointer<vtkPolyDataReader> reader =vtkSmartPointer<vtkPolyDataReader>::New();reader->SetFileName("fran_cut.vtk");reader->Update();vtkSmartPointer<vtkSmoothPolyDataFilter> smoothFilter =vtkSmartPointer<vtkSmoothPolyDataFilter>::New();smoothFilter->SetInputConnection(reader->GetOutputPort());smoothFilter->SetNumberOfIterations(100);smoothFilter->Update();/vtkSmartPointer<vtkPolyDataMapper> inputMapper =vtkSmartPointer<vtkPolyDataMapper>::New();inputMapper->SetInputConnection(reader->GetOutputPort());vtkSmartPointer<vtkActor> inputActor =vtkSmartPointer<vtkActor>::New();inputActor->SetMapper(inputMapper);vtkSmartPointer<vtkPolyDataMapper> smoothedMapper =vtkSmartPointer<vtkPolyDataMapper>::New();smoothedMapper->SetInputConnection(smoothFilter->GetOutputPort());vtkSmartPointer<vtkActor> smoothedActor =vtkSmartPointer<vtkActor>::New();smoothedActor->SetMapper(smoothedMapper);/double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 };double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 };vtkSmartPointer<vtkRenderer> leftRenderer =vtkSmartPointer<vtkRenderer>::New();leftRenderer->SetViewport(leftViewport);leftRenderer->AddActor(inputActor);leftRenderer->SetBackground(1, 0, 0);leftRenderer->ResetCamera();vtkSmartPointer<vtkRenderer> rightRenderer =vtkSmartPointer<vtkRenderer>::New();rightRenderer->SetViewport(rightViewport);rightRenderer->AddActor(smoothedActor);rightRenderer->SetBackground(0, 0, 0);rightRenderer->ResetCamera();/vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(leftRenderer);rw->AddRenderer(rightRenderer);rw->SetSize(640, 320);rw->SetWindowName("PolyData Grid Smooth By LapLasian");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Initialize();rwi->Start();return 0; }
vtkSmoothPolyDataFilter::SetNumberOfIterations()控制平滑次數,次數越多平滑的越厲害。200次的平滑效果如下圖所示:
左圖為原始模型,右圖為平滑后模型。從圖中可以看出,經過200次Laplace平滑后,模型變得相當的光滑,但是在平滑的同事也損失了一些細節信息。 其實在該類中還有多個變量來控制平滑過程,利用這些變量在一定程度上可以控制細節的損失。 BoundarySmoothing:控制是否對邊界點平滑。這里需要理解邊界點的概念,在一個網格模型中,一條邊只被一個單元包含那么這條邊就是邊界邊,而邊界邊上的點則為邊界點。如果一個模型中含有邊界邊,則說明該模型不是封閉的,正如圖中的一樣。 FeatureEdgeSmoothing:控制是否對特征邊上的點進行平滑。如果一條邊被兩個鄰近的多邊形共用,若兩個多邊形法向量的夾角(特征角)大于定義的閾值,則說明該邊為一條特征邊。因此,FeatureEdgeSmoothing設置開始時,需要調用SetFeatureAngle()函數設置特征角的閾值。具體如圖所示:
特征角越大,說明改邊越尖銳。特征邊/角往往表達模型的細節,平滑過程中最好不要進行處理,以保護細節不受損傷。 雖然通過特征邊平滑設置可以降低一部分細節損失,但并不能完全避免,且隨著laplace平滑的不斷迭代,模型會逐漸向網格的中心收縮。所以,vtkWindowSincPolyDataFilter是一種更好的選擇,該算法采用窗口Sinc函數實現網格平滑,能夠最小程度地避免收縮,vtkWindowSincPolyDataFilter的用法和VTKSmoothPolyDataFilter用法完全一致。 vtkSmartPointer<vtkWindowedSincPolyDataFilter> wndSincSmoothFilter =vtkSmartPointer<vtkWindowedSincPolyDataFilter>::New();wndSincSmoothFilter->SetInputConnection(reader->GetOutputPort());wndSincSmoothFilter->SetNumberOfIterations(10);wndSincSmoothFilter->Update();
算法的輸出結果如下所示:
2.參看資料
1.《C++ primer》2.《The VTK User’s Guide – 11thEdition》
3. ?張曉東, 羅火靈. VTK圖形圖像開發進階[M]. 機械工業出版社, 2015.
總結
以上是生活随笔為你收集整理的VTK修炼之道49:图形基本操作进阶_网格平滑(点云的曲面重建技术)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VTK修炼之道48:图形基本操作进阶_符
- 下一篇: 要玩就玩大的 夏普展示1,000,000