• VTK 图形基本操作进阶_符号化操作与模型区率计算


    1.符号化Glyphing再谈

    上一篇帖子提到一个事,就是用符号化操作显示单元的法向量。
    模型的法向量数据是向量数据,因此法向量不能像前面讲到的通过颜色映射来显示。但是可以通过符号化(Glyphing)技术将法向量图形化显示。Glyphing是一种基于图形的可视化技术,这些图像可以是简单的基本图形,如具有方向的椎体,也可以是更加复杂的图像。VTK中就是应用vtkGlyph3D类实现该功能的,并且可以支持Glyphing图形的缩放、着色、设置空间姿态等。使用该类时,需要接受两个输入:一个是需要显示的几何数据点集合;另一个是Glyph图形数据,为vtkPolyData数据。
         
    由于读入的模型数据比较大,点比较多,因此使用vtkMaskPoints类采样部分数据,该类保留输入数据中的点数据及其属性,并支持点数据的采样。为了减小计算量,随机采样了300个点做Glyphing显示。将其输出作为vtkGlyph3D的输入数据,而SetSourceData()设置了一个VTKArrowSource数据作为源数据,这样的效果是在输入数据的每一个点处会显示一个Glyph图形,这里我选用的就是箭头图形。vtkGlyph3D::SetVectorModeToUseNormal()指定要使用法向量数据来控制Glyph图形方向。vtkGlyph3D::SetScaleFactor()则控制Glyph图形的大小。

    2.曲率计算

    曲率时曲面弯曲程度的一种度量,是几何体的一种重要的局部特征。如下图所示:
    要计算曲面上给定点M的曲率,考虑经过M的法线的一个平面与曲面相交,得到一条二维曲面,称之为曲面在M点的一条法截线。经过M点法向量的曲面可以任意旋转,即可得到任意多条法截面,如上图所示。每一条法截线都会对应一个曲率,取具有最大曲率和最小曲率的两条法截线为主法截线,例如上图中的C1,C2;其对应的曲率分别记为k1,k2;称为主曲率;高斯曲率等于主曲率的乘积即k1*k2;平均曲率等于主曲率k1,k2的平均值,即(k1+k2)/2;当然,这只是曲率的直观几何解释,并没有给出具体的计算公式。这个公式高中就接触过:
    vtk中vtkCurvatures类实现了四种计算网格模型点曲率的计算方法。该类接受一个vtkPolyData数据,经计算得到的曲率数据作为网格模型的点的属性数据存入返回的vtkPolyData中。
    下例实现了一个网格模型的曲率计算,并通过颜色映射表来显示模型的表面曲率:
     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 <vtkCurvatures.h>
     9 #include <vtkLookupTable.h>
    10 #include <vtkPolyDataMapper.h>
    11 #include <vtkActor.h>
    12 #include <vtkScalarBarActor.h>
    13 #include <vtkPointData.h>
    14 #include <vtkRenderer.h>
    15 #include <vtkRenderWindow.h>
    16 #include <vtkRenderWindowInteractor.h>
    17  
    18 int main()
    19 {
    20     vtkSmartPointer<vtkPolyDataReader> reader =
    21         vtkSmartPointer<vtkPolyDataReader>::New();
    22     reader->SetFileName("fran_cut.vtk");
    23     reader->Update();
    24     
    25     vtkSmartPointer<vtkCurvatures> curvaturesFilter =
    26         vtkSmartPointer<vtkCurvatures>::New();
    27     curvaturesFilter->SetInputConnection(reader->GetOutputPort());
    28     //curvaturesFilter->SetCurvatureTypeToMinimum(); //最小曲率
    29     curvaturesFilter->SetCurvatureTypeToMaximum();   //最大曲率
    30     //curvaturesFilter->SetCurvatureTypeToGaussian();//高斯曲率
    31     //curvaturesFilter->SetCurvatureTypeToMean();    //平均曲率
    32     curvaturesFilter->Update();
    33  
    34     double scalarRange[2];
    35     curvaturesFilter->GetOutput()->GetScalarRange(scalarRange);
    36     //建立查找表 做颜色映射
    37     vtkSmartPointer<vtkLookupTable> lut =
    38         vtkSmartPointer<vtkLookupTable>::New();
    39     lut->SetHueRange(0.0, 0.6);
    40     lut->SetAlphaRange(1.0, 1.0);
    41     lut->SetValueRange(1.0, 1.0);
    42     lut->SetSaturationRange(1.0, 1.0);
    43     lut->SetNumberOfTableValues(256);
    44     lut->SetRange(scalarRange);
    45     lut->Build();
    46     ///
    47     vtkSmartPointer<vtkPolyDataMapper> mapper =
    48         vtkSmartPointer<vtkPolyDataMapper>::New();
    49     mapper->SetInputData(curvaturesFilter->GetOutput());
    50     mapper->SetLookupTable(lut);
    51     mapper->SetScalarRange(scalarRange);
    52  
    53     vtkSmartPointer<vtkActor> actor =
    54         vtkSmartPointer<vtkActor>::New();
    55     actor->SetMapper(mapper);
    56  
    57     vtkSmartPointer<vtkScalarBarActor> scalarBar =
    58         vtkSmartPointer<vtkScalarBarActor>::New();
    59     scalarBar->SetLookupTable(mapper->GetLookupTable());
    60     scalarBar->SetTitle(curvaturesFilter->GetOutput()->GetPointData()->GetScalars()->GetName());
    61     scalarBar->SetNumberOfLabels(5); //设置5个标签
    62  
    63     vtkSmartPointer<vtkRenderer> render =
    64         vtkSmartPointer<vtkRenderer>::New();
    65     render->AddActor(actor);
    66     render->AddActor2D(scalarBar);
    67     render->SetBackground(0, 0, 0);
    68  
    69     vtkSmartPointer<vtkRenderWindow> rw =
    70         vtkSmartPointer<vtkRenderWindow>::New();
    71     rw->AddRenderer(render);
    72     rw->SetSize(640, 480);
    73     rw->SetWindowName("Calculating PolyData Curvature");
    74  
    75     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
    76         vtkSmartPointer<vtkRenderWindowInteractor>::New();
    77     rwi->SetRenderWindow(rw);
    78     rwi->Initialize();
    79     rwi->Start();
    80     return 0;
    81 }
    首先读入一个vtkPolyData人脸模型数据,作为vtkCurvatures的输入,并调用SetCurvatureTypeToMaximum()函数计算最大曲率,此外我们还可以定义最小曲率,高斯曲率,平均曲率。当然,四种曲率允许同时计算。
    在内部计算完曲率数据后,将其作为输出的vtkPolyData点的属性数据。保存属性数据时,四种曲率数据分别对应属性名字为Minimum_Curvature/M aximum_Curvature/Gauss_Curvature/Mean_Curvature,因此可以通过属性名字获取相应的曲率数据。例如要获得高斯曲率数据,可调用:
    1 vtkDoubleArray *gauss = static_cast<vtkDoubleArray*>(
    2 curvaturesFilter->GetOutput()->GetpointData()->GetArray("Gauss_Curvature"));
    为了能够在模型上显示曲率属性数据,采用颜色映射来显示。定义了一个256色的VTKLookupTable对象,并设置了曲率数据的范围。
    然后将改颜色映射表添加到vtkPolyDataMapper中。
    最后,我用到了一个新的VTKScalarBarActor类,该类支持一个颜色映射表转换为一个Actor对象,将颜色表以图形的形式显示,并支持设置图形相应的名字和翔实数据Label个数。最后显示即可。
  • 相关阅读:
    用localeCompare实现中文排序
    点击一个链接同时打开两个页面
    汉字和Unicode编码互转
    javascript中document学习
    javascript页面表格排序
    JavaScript 仿LightBox内容显示效果
    JavaScript面向对象的简单介绍
    JavaScript键盘上下键的操作(选择)
    关于clientWidth、offsetWidth、clientHeight、offsetHeigh
    动态(按需)加载js和css文件
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14241810.html
Copyright © 2020-2023  润新知