1.曲率计算
曲率时曲面弯曲程度的一种度量,是几何体的一种重要的局部特征。如下图所示:
要计算曲面上给定点M的曲率,考虑经过M的法线的一个平面与曲面相交,得到一条二维曲面,称之为曲面在M点的一条法截线。经过M点法向量的曲面可以任意旋转,即可得到任意多条法截面,如上图所示。每一条法截线都会对应一个曲率,取具有最大曲率和最小曲率的两条法截线为主法截线,例如上图中的C1,C2;其对应的曲率分别记为k1,k2;称为主曲率;高斯曲率等于主曲率的乘积即k1*k2;平均曲率等于主曲率k1,k2的平均值,即(k1+k2)/2;当然,这只是曲率的直观几何解释,并没有给出具体的计算公式。这个公式高中就接触过:
vtk中vtkCurvatures类实现了四种计算网格模型点曲率的计算方法。该类接受一个vtkPolyData数据,经计算得到的曲率数据作为网格模型的点的属性数据存入返回的vtkPolyData中。
下例实现了一个网格模型的曲率计算,并通过颜色映射表来显示模型的表面曲率:
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
#include <vtkSmartPointer.h>
#include <vtkPolyDataReader.h>
#include <vtkCurvatures.h>
#include <vtkLookupTable.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkScalarBarActor.h>
#include <vtkPointData.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<vtkCurvatures> curvaturesFilter =
vtkSmartPointer<vtkCurvatures>::New();
curvaturesFilter->SetInputConnection(reader->GetOutputPort());
//curvaturesFilter->SetCurvatureTypeToMinimum(); //最小曲率
curvaturesFilter->SetCurvatureTypeToMaximum(); //最大曲率
//curvaturesFilter->SetCurvatureTypeToGaussian();//高斯曲率
//curvaturesFilter->SetCurvatureTypeToMean(); //平均曲率
curvaturesFilter->Update();
double scalarRange[2];
curvaturesFilter->GetOutput()->GetScalarRange(scalarRange);
//建立查找表 做颜色映射
vtkSmartPointer<vtkLookupTable> lut =
vtkSmartPointer<vtkLookupTable>::New();
lut->SetHueRange(0.0, 0.6);
lut->SetAlphaRange(1.0, 1.0);
lut->SetValueRange(1.0, 1.0);
lut->SetSaturationRange(1.0, 1.0);
lut->SetNumberOfTableValues(256);
lut->SetRange(scalarRange);
lut->Build();
///
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(curvaturesFilter->GetOutput());
mapper->SetLookupTable(lut);
mapper->SetScalarRange(scalarRange);
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkScalarBarActor> scalarBar =
vtkSmartPointer<vtkScalarBarActor>::New();
scalarBar->SetLookupTable(mapper->GetLookupTable());
scalarBar->SetTitle(curvaturesFilter->GetOutput()->GetPointData()->GetScalars()->GetName());
scalarBar->SetNumberOfLabels(5); //设置5个标签
vtkSmartPointer<vtkRenderer> render =
vtkSmartPointer<vtkRenderer>::New();
render->AddActor(actor);
render->AddActor2D(scalarBar);
render->SetBackground(0, 0, 0);
vtkSmartPointer<vtkRenderWindow> rw =
vtkSmartPointer<vtkRenderWindow>::New();
rw->AddRenderer(render);
rw->SetSize(640, 480);
rw->SetWindowName("Calculating PolyData Curvature");
vtkSmartPointer<vtkRenderWindowInteractor> rwi =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
rwi->SetRenderWindow(rw);
rwi->Initialize();
rwi->Start();
return 0;
}
首先读入一个vtkPolyData人脸模型数据,作为vtkCurvatures的输入,并调用SetCurvatureTypeToMaximum()函数计算最大曲率,此外我们还可以定义最小曲率,高斯曲率,平均曲率。当然,四种曲率允许同时计算。
在内部计算完曲率数据后,将其作为输出的vtkPolyData点的属性数据。保存属性数据时,四种曲率数据分别对应属性名字为Minimum_Curvature/Maximum_Curvature/Gauss_Curvature/Mean_Curvature,因此可以通过属性名字获取相应的曲率数据。例如要获得高斯曲率数据,可调用:
vtkDoubleArray *gauss = static_cast<vtkDoubleArray*>(
curvaturesFilter->GetOutput()->GetpointData()->GetArray("Gauss_Curvature"));
为了能够在模型上显示曲率属性数据,采用颜色映射来显示。定义了一个256色的VTKLookupTable对象,并设置了曲率数据的范围。
然后将改颜色映射表添加到vtkPolyDataMapper中。
最后,我用到了一个新的VTKScalarBarActor类,该类支持一个颜色映射表转换为一个Actor对象,将颜色表以图形的形式显示,并支持设置图形相应的名字和翔实数据Label个数。最后显示即可。