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