VTK修行之相见恨晚

1.VTK是什么?

VTK(Visualization Toolkit)是 Kitware 公司发布的开源免费软件系统,受到国内外高等院校与科研机构的欢迎,广泛地应用于计算机图形学、图像处理与三维可视化等领域。VTK 独立于系统的图形界面接口(GUI),可方便的嵌入到其他的相关软件中。同时开发人员可以基于 VTK 独立的基础类库开发自己的库函数,拓展 VTK 的应用范围。
VTK 采用面向对象思想,基于 OpenGL 开发出目标函数库。它将将一些常用的算法封装为类的形式,用户在开发过程中可以直接调用其函数库进行开发,而不必纠结函数内部具体的实现过程。

2.VTK 的基本组成

VTK 包含图形图像处理与可视化领域内的上百种算法,支持跨平台,可在 Java、C/C++、Tcl/Tk 与 Python 等高级编程语言环境下使用。

VTK 由两大部分构成,其核心层(Compiled Core,C++类库)是基于 C/C++语言编写的,上层部分是依据特定规则编写的支持脚本语言(如 Java、Tcl/Tk 与 Python)的解释层(Interpreted Interface),如图 1 所示。
在这里插入图片描述

图1 VTK层次结构

在 VTK 编译层中,VTK 其它的类或相关程序可调用集成了图像处理相关数据结构与算法的 C++对象。解释层部分是脚本语言与编译后的 VTK 动态链接库进行绑定而生成的相应解释型语言的接口。这种结构既保持解释性语言代码的特性,又可用C/C++语言编写相关的算法来进行拓展应用,很大程度上提高了开发效率。

3.VTK 的框架结构

VTK 的框架结构如图2所示,类似于 MFC 中的 CObject 基类,vtkObject 是VTK 的基类,为可视化流程提供了基本的方法。vtkSource 是分别是 vtkObject、vtkFilter的派生类与父类,为整个可视化流程(如数据读取等)定义具体的行为与接口,经过vtkFilter 处理后的数据,可转化为直接用特定算法模块进行处理的形式。vtkObject的另一派生类是 vtkMapper,它将 vtkFilter 处理后的数据映射为几何数据形式,为原始数据与图像数据之间提供接口。任何可视化的数据都需要绑定 vtkActor 演示对象,在 vtkRender 类的渲染下,最终显示在屏幕的窗口中。
在这里插入图片描述

图2 VTK架构结构

4.VTK 的数据结构

VTK 作为一个封装良好的可视化工具包,有其独特的数据结构和数据类型。对于初始的测量数据,VTK 使用数据流(DataFlow)的方式将其变换成图形数据,这种方法的对象包括流程对象与数据对象,具体将在下节介绍。而对于已具有几何结构、拓扑结构及相关属性(如误差、测量值等)的数据被称作数据集(DataSet)。在 VTK 的数据集中,与拓扑结构、几何结构及相关属性相对应的是点(Point)、单元格(Cell)、属性(Property)对象。 数据集由多边形数据结构(Polygonal Data)、不规则网格(Unstructured Grid)及规则网格(Structured Grid)组成。在进行三维图形的重构中,对于有规律的点可以用相应的规则网格或多边形数据结构来表示,而用不规则网格表示其他没有规律的散乱点数据。此外,VTK 还为常见图形提供快速绘制的接口,叫做图形源对象 Source。对于立方体、球面、圆柱(锥)等图形都有 Source 对象,Source 对象封装了数据结构中的几何结构和拓扑结构,将图形对象的特点作为属性接口面向开发人员。
在这里插入图片描述

图3 数据集的分类及构成

5.VTK 的可视化流程

VTK 的可视化流程将需要处理的数据视作流动介质在管道中流动,因此可视化的不同阶段的数据将会有不同的处理方式,图形模型与可视化模型的结合构成了 VTK的可视化管线。 可视化模型主要用来对拟合后的数据进行处理,生成可被VTK绘制的几何形体,它包括处理对象(vtkProcessObject)与数据对象(vtkDataObject)。
在这里插入图片描述

图4 VTK可视化流程

Source 对象的数据既可以是已知读入的,也可是程序运算得到。过滤器(Filter)将经过 Source 对象处理后数据对象(Data Object)进行处理来生成新的数据对象。新生成的数据对象进入映射器(Mapper),将三维数据映射成几何图像,然后绑定到演示对象(Actor),此时用户可以设置演示对象的属性(如文本、颜色等)。渲染器(Renderer)在设置灯光(Light)与相机(Camera)等属性后,将演示对象添加到绘制器窗口(RenderWindow)对三维体进行绘制与显示。交互器(RenderWindowInteractor)可为演示对象提供人机交互(如缩放、旋转、文本显示等)。

6.第一个VTK程序

至此,相信你已经对VTK有了一个大致的了解下,那么接下来就是实操部分。首先要做的事是安装VTK并配置环境,对此可以参考这个链接。然后就可以开始你自己的第一个VTK程序,不妨从以下这个例子开始,它将有助于你理解上述的理论知识。相关的说明已经在代码中注释。


#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>

int main()
{
    
    
	//数据源对象
	vtkSmartPointer<vtkCylinderSource> cylinder = 
		vtkSmartPointer<vtkCylinderSource>::New();
	cylinder->SetHeight( 3.0 );
	cylinder->SetRadius( 1.0 );
	cylinder->SetResolution( 200 );  //设置柱体横截面的边数
	// 映射器,接受cylinder的输出,将数据映射为几何元素
	vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = 
		vtkSmartPointer<vtkPolyDataMapper>::New();
	cylinderMapper->SetInputConnection( cylinder->GetOutputPort() ); 
	//需要渲染的可视化数据转换后加入渲染场景
	//vtkActor,派生自vtkProp类,渲染场景中数据的可视化表达是通过vtkProp的子类负责的
	//vtkProp子类负责确定渲染场景中对象的位置、大小和方向信息
	vtkSmartPointer<vtkActor> cylinderActor = 
		vtkSmartPointer<vtkActor>::New();
	cylinderActor->SetMapper( cylinderMapper );
	cylinderActor->GetProperty()->SetColor(0.0, 0.0, 1.0);
	//负责管理场景的渲染过程
	//组成场景的所有对象包括Prop,照相机(Camera)和光照(Light)都被集中在一个vtkRenderer对象中
	//一个vtkRenderWindow中可以有多个vtkRenderer对象,而这些vtkRenderer可以渲染在窗口中不同的矩形区域中
	vtkSmartPointer<vtkRenderer> renderer = 
		vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor( cylinderActor );      //添加vtkProp类型的对象到渲染场景中
	renderer->SetBackground( 1.0, 1.0, 1.0 ); //用于设置渲染场景的背景颜色

	// 将操作系统与VTK渲染引擎连接到一起。
	//不同平台下的vtkRenderWindow子类负责本地计算机系统中窗口创建和渲染过程管理
	vtkSmartPointer<vtkRenderWindow> renWin = 
		vtkSmartPointer<vtkRenderWindow>::New();
	renWin->AddRenderer( renderer );
	renWin->SetSize( 640, 480 ); //设置窗口的大小,以像素为单位
	renWin->Render();
	renWin->SetWindowName("RenderCylinder");
	//提供平台独立的响应鼠标、键盘和时钟事件的交互机制
	//通过VTK的Command/Observer设计模式将监听到的特定平台的鼠标
	//键盘和时钟事件交由vtkInteractorObserver或其子类
	vtkSmartPointer<vtkRenderWindowInteractor> iren = 
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	iren->SetRenderWindow(renWin); //设置渲染窗口,消息是通过渲染窗口捕获到的,所以必须要给交互器对象设置渲染窗口
	//交互器样式的一种,该样式下,用户是通过控制相机对物体作旋转、放大、缩小等操作
	vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = 
		vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
	iren->SetInteractorStyle(style); //定义交互器样式,默认的交互样式为vtkInteractorStyleSwitch

	iren->Initialize();
	iren->Start();

	return EXIT_SUCCESS;
}

运行后的结果如下:
其显示的一个多边形棱柱,其中可以通过cylinder->SetResolution( 200 )设置该柱体的边数,当我将这个值设置较大时,图中的轮廓已经看不清了。

在这里插入图片描述

图5 运行结果

在得到这个图像后,将鼠标左键放置在柱体上,长按并移动鼠标时能够旋转该柱体;长按并按住shift时,可以通过鼠标拖动图像;另外,可以按P键观察到图中的红框。

参考文献:
[1] https://blog.csdn.net/weixin_42291376/article/details/106810026
[2] https://blog.csdn.net/Littlehero_121/article/details/125842269

猜你喜欢

转载自blog.csdn.net/qq_44924694/article/details/130392383