3)根据属性数据的最大、最小值建立颜色索引
点击打开链接https://blog.csdn.net/webzhuce/article/details/78077561?locationNum=4&fps=1
颜色映射的操作对象是数据集中的标量属性。它是一种常用的 标量算法。它会根据数据集中各个部分不同的标量值,对各个部分上不同的颜色。与此相关的另一种上色方法是控制演员的颜色属性,但这样整个图形只有单一的颜色,这显然没有颜色映射方法灵活。
创建多边形数据集程序运行 结果显示的彩色立方体就用到了颜色映射。由于对 立方体的6个顶点设置了不同的标量值(点id),所以这6个点的颜色不同。至于立方体其他部分的颜色,也是通过标量值映射来的,不过这些标量值并不是手动设置,而是根据邻近的顶点的标量值,运用某种内插算法计算出来的。
假设有一个共256种颜色的查询表,且颜色的索引号范围为0~255,那么颜色映射就是将数据集的标量值映射到这些索引号的过程。在渲染时,与索引号对应的颜色将作为数据中相应部分的颜色显示出来。映射的方法如下图所示。
上图中,scalar表示数据集中的标量值,index表示映射后的索引号。smin和smax表示的是标量值的映射范围(注意不是数据集中标量值的取值范围)。若一个标量值小于smin,则其映射的索引号为0;若一个标量值大于smax,其映射的索引号为255;若一个标量值在这个范围之间,则映射过程就是一个求一元一次函数值的过程,其对应的曲线是一条直线,不过需要对函数值取整。实际上,在范围外的标量值也可以被看作smin和smax,然后对其求函数值。
在VTK中,颜色映射的过程是由映射器mapper完成的。可以通过调用映射器的方法SetScalarRange()来设置标量值的范围[smin, smax]。映射过程只是为每个标量值确定了一个索引号,最终该标量值映射为何种颜色,还需要看颜色查询表中颜色的分配情况。如果不手动创建一个查询表,则映射器会使用一个默认的映射表。
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(LookupTableExample)
FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})
ADD_EXECUTABLE(LookupTableExample lookuptable.cpp)
TARGET_LINK_LIBRARIES(LookupTableExample ${VTK_LIBRARIES})
#include "vtkActor.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include
#include "vtkSmartPointer.h"
int main()
{
int i;
//定义立方体的顶点坐标
static float x[8][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 },
{ 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 1, 1 } };
//定义单元,每4个顶点建立一个四边形单元,共计6个单元
static vtkIdType pts[6][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 0, 1, 5, 4 },
{ 1, 2, 6, 5 }, { 2, 3, 7, 6 }, { 3, 0, 4, 7 } };
//创建对象
vtkSmartPointer cube = vtkSmartPointer::New();
vtkSmartPointer points = vtkSmartPointer::New();
vtkSmartPointer polys = vtkSmartPointer::New();
//存储顶点
for (i = 0; i < 8; i++)
points->InsertPoint(i, x[i]);
//设定单元
for (i = 0; i < 6; i++)
polys->InsertNextCell(4, pts[i]);
//存储标量值
vtkSmartPointer scalars = vtkSmartPointer::New();
//设定每个顶点的标量值
for (i = 0; i < 8; i++)
scalars->InsertTuple1(i, i*4);
//创建多边形数据
cube->SetPoints(points);
//设定单元类型为多边形
cube->SetPolys(polys);
//设定每个顶点的标量值
cube->GetPointData()->SetScalars(scalars);
//定义颜色映射表
vtkSmartPointer pColorTable = vtkSmartPointer::New();
//设置颜色表中的颜色
pColorTable->SetNumberOfColors(256);
pColorTable->SetHueRange(0.67, 0.0); //色调范围从红色到蓝色
pColorTable->Build();
//数据映射
vtkSmartPointer cubeMapper = vtkSmartPointer::New();
cubeMapper->SetInputData(cube);
cubeMapper->SetScalarRange(0, 7);
cubeMapper->SetLookupTable(pColorTable);
vtkSmartPointer cubeActor = vtkSmartPointer::New();
cubeActor->SetMapper(cubeMapper);
vtkSmartPointer renderer = vtkSmartPointer::New();
vtkSmartPointer renWin = vtkSmartPointer::New();
renWin->AddRenderer(renderer);
vtkSmartPointer iren = vtkSmartPointer::New();
iren->SetRenderWindow(renWin);
renderer->AddActor(cubeActor);
renderer->SetBackground(1, 1, 1);
renWin->SetSize(500, 500);
renWin->Render();
iren->Start();
return 0;
}
有时候,标量数据就是颜色值,并不需要通过查询表进行映射。对此,映射器提供了以下一些方法来进行控制。
● SetColorModeToDefault()该方法执行默认的映射器行为,即把unsigned char类型的标量属性数据当作颜色值,不执行隐式。对于其他类型的标量数据,将通过查询表映射。
● SetColorModeToMapScalars()无论变量数据是何种类型,该方法都通过查询表对标量数据进行映射。如果标量数据的每个元组有多个分量,则对第0个分量进行映射。
注意事项:
1. 如果没有标量数据,则映射器将不能使用查询表控制对象的颜色。这时可以使用演员对象来控制颜色。
2. 如果想阻止颜色映射,可调用映射器的ScalarVisibilityOff()方法。
调用ScalarVisibilityOn()方法后,可以控制映射器的颜色映射行为:
● SetScalarModeToDefault()执行默认的映射行为:如果有点标量属性数据,则用其进行映射,如果没有点标量属性数据但有单元标量属性数据,则用单元标量属性数据进行映射,否则不映射。
● SetScalarModeToUsePointData()总是使用点标量属性数据进行映射的。如果没有嗲按标量属性数据,就不进行映射。
● SetScalarModeToUseCellData()总是使用单元标量属性数据进行映射的。如果没有单元标量属性数据,就不进行映射。
● SetScalarModeToUsePointFieldData()不使用点或单元标量属性数据,而是使用点属性数据中的一般属性数据来进行映射的。该方法应该与ColorByArrayComponent()结合使用,以用来指定用于颜色映射的数据。
● SetScalarModeToUseCellFieldData()不使用点或单元标量属性数据,而是使用单元属性数据中的一般属性数据来进行映射的。该方法应该与ColorByArrayComponent()结合使用,以用来指定用于颜色映射的数据。
点击打开链接https://blog.csdn.net/shenziheng1/article/details/54846277
上一篇帖子提到一个事,就是用符号化操作显示单元的法向量。模型的法向量数据是向量数据,因此法向量不能像前面讲到的通过颜色映射来显示。但是可以通过符号化(Glyphing)技术将法向量图形化显示。Glyphing是一种基于图形的可视化技术,这些图像可以是简单的基本图形,如具有方向的椎体,也可以是更加复杂的图像。VTK中就是应用vtkGlyph3D类实现该功能的,并且可以支持Glyphing图形的缩放、着色、设置空间姿态等。使用该类时,需要接受两个输入:一个是需要显示的几何数据点集合;另一个是Glyph图形数据,为vtkPolyData数据。由于读入的模型数据比较大,点比较多,因此使用vtkMaskPoints类采样部分数据,该类保留输入数据中的点数据及其属性,并支持点数据的采样。为了减小计算量,随机采样了300个点做Glyphing显示。将其输出作为vtkGlyph3D的输入数据,而SetSourceData()设置了一个VTKArrowSource数据作为源数据,这样的效果是在输入数据的每一个点处会显示一个Glyph图形,这里我选用的就是箭头图形。vtkGlyph3D::SetVectorModeToUseNormal()指定要使用法向量数据来控制Glyph图形方向。vtkGlyph3D::SetScaleFactor()则控制Glyph图形的大小。
曲率时曲面弯曲程度的一种度量,是几何体的一种重要的局部特征。如下图所示:要计算曲面上给定点M的曲率,考虑经过M的法线的一个平面与曲面相交,得到一条二维曲面,称之为曲面在M点的一条法截线。经过M点法向量的曲面可以任意旋转,即可得到任意多条法截面,如上图所示。每一条法截线都会对应一个曲率,取具有最大曲率和最小曲率的两条法截线为主法截线,例如上图中的C1,C2;其对应的曲率分别记为k1,k2;称为主曲率;高斯曲率等于主曲率的乘积即k1*k2;平均曲率等于主曲率k1,k2的平均值,即(k1+k2)/2;当然,这只是曲率的直观几何解释,并没有给出具体的计算公式。这个公式高中就接触过:vtk中vtkCurvatures类实现了四种计算网格模型点曲率的计算方法。该类接受一个vtkPolyData数据,经计算得到的曲率数据作为网格模型的点的属性数据存入返回的vtkPolyData中。下例实现了一个网格模型的曲率计算,并通过颜色映射表来显示模型的表面曲率:
- "font-size:18px;">#include
- VTK_MODULE_INIT(vtkRenderingOpenGL);
- VTK_MODULE_INIT(vtkInteractionStyle);
- VTK_MODULE_INIT(vtkRenderingFreeType);
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- int main()
- {
- vtkSmartPointer
reader = - vtkSmartPointer
::New(); - reader->SetFileName("fran_cut.vtk");
- reader->Update();
- vtkSmartPointer
curvaturesFilter = - vtkSmartPointer
::New(); - curvaturesFilter->SetInputConnection(reader->GetOutputPort());
- //curvaturesFilter->SetCurvatureTypeToMinimum(); //最小曲率
- curvaturesFilter->SetCurvatureTypeToMaximum(); //最大曲率
- //curvaturesFilter->SetCurvatureTypeToGaussian();//高斯曲率
- //curvaturesFilter->SetCurvatureTypeToMean(); //平均曲率
- curvaturesFilter->Update();
- double scalarRange[2];
- curvaturesFilter->GetOutput()->GetScalarRange(scalarRange);
- //建立查找表 做颜色映射
- vtkSmartPointer
lut = - vtkSmartPointer
::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
mapper = - vtkSmartPointer
::New(); - mapper->SetInputData(curvaturesFilter->GetOutput());
- mapper->SetLookupTable(lut);
- mapper->SetScalarRange(scalarRange);
- vtkSmartPointer
actor = - vtkSmartPointer
::New(); - actor->SetMapper(mapper);
- vtkSmartPointer
scalarBar = - vtkSmartPointer
::New(); - scalarBar->SetLookupTable(mapper->GetLookupTable());
- scalarBar->SetTitle(curvaturesFilter->GetOutput()->GetPointData()->GetScalars()->GetName());
- scalarBar->SetNumberOfLabels(5); //设置5个标签
- vtkSmartPointer
render = - vtkSmartPointer
::New(); - render->AddActor(actor);
- render->AddActor2D(scalarBar);
- render->SetBackground(0, 0, 0);
- vtkSmartPointer
rw = - vtkSmartPointer
::New(); - rw->AddRenderer(render);
- rw->SetSize(640, 480);
- rw->SetWindowName("Calculating PolyData Curvature");
- vtkSmartPointer
rwi = - vtkSmartPointer
::New(); - rwi->SetRenderWindow(rw);
- rwi->Initialize();
- rwi->Start();
- return 0;
- }
首先读入一个vtkPolyData人脸模型数据,作为vtkCurvatures的输入,并调用SetCurvatureTypeToMaximum()函数计算最大曲率,此外我们还可以定义最小曲率,高斯曲率,平均曲率。当然,四种曲率允许同时计算。在内部计算完曲率数据后,将其作为输出的vtkPolyData点的属性数据。保存属性数据时,四种曲率数据分别对应属性名字为Minimum_Curvature/M aximum_Curvature/Gauss_Curvature/Mean_Curvature,因此可以通过属性名字获取相应的曲率数据。例如要获得高斯曲率数据,可调用:为了能够在模型上显示曲率属性数据,采用颜色映射来显示。定义了一个256色的VTKLookupTable对象,并设置了曲率数据的范围。
- "font-size:18px;">vtkDoubleArray *gauss = static_cast
( - curvaturesFilter->GetOutput()->GetpointData()->GetArray("Gauss_Curvature"));
然后将改颜色映射表添加到vtkPolyDataMapper中。最后,我用到了一个新的VTKScalarBarActor类,该类支持一个颜色映射表转换为一个Actor对象,将颜色表以图形的形式显示,并支持设置图形相应的名字和翔实数据Label个数。最后显示即可。
1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3. 张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.