VTK 圖形基本操作進階_表面重建技術(三維點雲曲面重建)


1.點雲重建

雖然Delaunay三角剖分算法可以實現網格曲面重建,但是其應用主要在二維剖分,在三維空間網格生成中遇到了問題。因為在三維點雲曲面重建中,Delaunay條件不在滿足,不僅基於最大最小角判斷的對角線交換准則不在成立,而且基於外接圓判據的Delaunay三角化也不能保證網格質量。
VTKSurfaceReconstructionFilter則實現了一種隱式曲面重建方法,即將曲面看做一個符號距離函數的等值面,曲面內外的距離值得符號相反,而零等值面即為所求的曲面。該方法需要對點雲數據進行網格划分,然后估算每個點的切平面和方向,並以每個點與最近的切平面距離來近似表面距離。這樣即可得到一個符號距離的體數據。這樣,我們就可以利用VTKContourFilter來提取零等值面即可得到相應的網格。
利用人臉點雲數據進行人臉網格曲面重建實例如下:
 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 <vtkPolyData.h>
 9 #include <vtkSurfaceReconstructionFilter.h>
 10 #include <vtkContourFilter.h>
 11 #include <vtkVertexGlyphFilter.h>
 12 #include <vtkPolyDataMapper.h>
 13 #include <vtkActor.h>
 14 #include <vtkRenderer.h>
 15 #include <vtkCamera.h>
 16 #include <vtkRenderWindow.h>
 17 #include <vtkRenderWindowInteractor.h>
 18 #include <vtkProperty.h>
 19  
 20 int main()  21 {  22     vtkSmartPointer<vtkPolyDataReader> reader =
 23         vtkSmartPointer<vtkPolyDataReader>::New();  24     reader->SetFileName("fran_cut.vtk");  25     reader->Update();  26  
 27     vtkSmartPointer<vtkPolyData> points =
 28         vtkSmartPointer<vtkPolyData>::New();  29     points->SetPoints(reader->GetOutput()->GetPoints()); //獲得網格模型中的幾何數據:點集
 30  
 31     vtkSmartPointer<vtkSurfaceReconstructionFilter> surf =
 32         vtkSmartPointer<vtkSurfaceReconstructionFilter>::New();  33     surf->SetInputData(points);  34     surf->SetNeighborhoodSize(20);  35     surf->SetSampleSpacing(0.005);  36     surf->Update();  37  
 38     vtkSmartPointer<vtkContourFilter> contour =
 39         vtkSmartPointer<vtkContourFilter>::New();  40     contour->SetInputConnection(surf->GetOutputPort());  41     contour->SetValue(0, 0.0);  42     contour->Update();  43     //  44     vtkSmartPointer <vtkVertexGlyphFilter> vertexGlyphFilter =
 45         vtkSmartPointer<vtkVertexGlyphFilter>::New();  46     vertexGlyphFilter->AddInputData(points);  47     vertexGlyphFilter->Update();  48     vtkSmartPointer<vtkPolyDataMapper> pointMapper =
 49         vtkSmartPointer<vtkPolyDataMapper>::New();  50     pointMapper->SetInputData(vertexGlyphFilter->GetOutput());  51     pointMapper->ScalarVisibilityOff();  52  
 53     vtkSmartPointer<vtkActor> pointActor =
 54         vtkSmartPointer<vtkActor>::New();  55     pointActor->SetMapper(pointMapper);  56     pointActor->GetProperty()->SetColor(1, 0, 0);  57     pointActor->GetProperty()->SetPointSize(4);  58  
 59     vtkSmartPointer<vtkPolyDataMapper> contourMapper =
 60         vtkSmartPointer<vtkPolyDataMapper>::New();  61     contourMapper->SetInputData(contour->GetOutput());  62     vtkSmartPointer<vtkActor> contourActor =
 63         vtkSmartPointer<vtkActor>::New();  64     contourActor->SetMapper(contourMapper);  65     ///  66     double pointView[4] = { 0, 0, 0.5, 1 };  67     double contourView[4] = { 0.5, 0, 1, 1 };  68  
 69     vtkSmartPointer<vtkRenderer> pointRender =
 70         vtkSmartPointer<vtkRenderer>::New();  71     pointRender->AddActor(pointActor);  72     pointRender->SetViewport(pointView);  73     pointRender->SetBackground(1, 1, 1);  74  
 75     vtkSmartPointer<vtkRenderer> contourRender =
 76         vtkSmartPointer<vtkRenderer>::New();  77     contourRender->AddActor(contourActor);  78     contourRender->SetViewport(contourView);  79     contourRender->SetBackground(0, 1, 0);  80  
 81     pointRender->GetActiveCamera()->SetPosition(0, -1, 0);  82     pointRender->GetActiveCamera()->SetFocalPoint(0, 0, 0);  83     pointRender->GetActiveCamera()->SetViewUp(0,0,1);  84     pointRender->GetActiveCamera()->Azimuth(30);  85     pointRender->GetActiveCamera()->Elevation(30);  86     pointRender->ResetCamera();  87     contourRender->SetActiveCamera(pointRender->GetActiveCamera());  88  
 89     vtkSmartPointer<vtkRenderWindow> rw =
 90         vtkSmartPointer<vtkRenderWindow>::New();  91     rw->AddRenderer(pointRender);  92     rw->AddRenderer(contourRender);  93     rw->SetSize(640, 320);  94     rw->SetWindowName("3D Surface Reconstruction ");  95     rw->Render();  96  
 97     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
 98         vtkSmartPointer<vtkRenderWindowInteractor>::New();  99     rwi->SetRenderWindow(rw); 100     rwi->Initialize(); 101     rwi->Start(); 102  
103     return 0; 104 }

使用VTKSurfaceReconstructionFilter時,主要涉及兩個參數,分別使用函數SetNeighborhoodSize()和SetSampleSpacing()進行設置。

SetNeighborhoodSize:設置鄰域點的個數;而這些鄰域點則用來估計每個點的局部切平面。鄰域點的個數默認為20,能夠處理大多數重建問題。個數設置越多,計算消耗時間越長。當點雲分布嚴重不均勻情況下,可以考慮增加該值。
SetSampleSpacing:用於設置划分網格的網格間距,間距與小,網格越密集,一般采用默認值0.05.
該例的輸出結果如下圖所示:


免責聲明!

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



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