急诊处方限1至3天用量:VTK 编程简介

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 20:27:37
0 如何利用文档
VTK 是由 Will Schroeder 等创立的 Kitware Inc. 的开放源码产品。Kitware 提供关于VTK 的技术支持和各种服务产品,包括教科书和用户指南:The Visualization Toolkit An Object-Oriented Approach To 3D Graphics, 3rd edition 和 The Visualization Toolkit User's Guide 。两本书的内容各有侧重,教科书主要介绍可视化的各种算法以及 VTK 中的数据结构,而用户指南强调软件的使用方法。可以根据使用过程中遇到的不同问题参考两本书中的相应章节。编程中对具体的类、函数等的使用可以参考电子版的手册。编程中遇到的问题,可以在 VTK 的 maillist 上提出,一般都会有解答。
1 编译 VTK 库
1.1 准备源代码
http://www.vtk.org/ 下载源代码。源代码按成熟度依次分为官方发行版、每日打包版和 CVS 开发版,其中官方发行版最稳定,CVS 开发版最新。一般应用使用官方发行版即可。
1.2 用 CMake 产生具体平台下的工程文件
VTK 是用 C++ 语言开发的平台无关的图形库。为了使相互关联的 VTK 库代码能在不同平台(如 Windows 和 Unix)和不同编译器(如 Visual Studio 6.0 和 Borland)下方便使用,Kitware 开发了 CMake 这一转换工具。比如使用 CMake,可以为 Windows 平台下的 Visual Studio 6.0 产生相应的工程文件(.dsp 或 .dsw 文件),此后就可以在 Visual Studio的集成开发环境(IDE)下进行编译连接了。
CMake 提供一个用户界面,用户可以定制某些变量,其中比较重要的是 BUILD_SHARED_LIBS,根据它的选择可以生成 VTK 的静态库或者动态链接库。如果编译成静态库,那么在开发应用程序时要将相应库代码加入可执行程序;如果是动态库,则可执行程序与动态链接库是分离的。用动态库的好处是可以减小主程序的体积,缺点是可执行程序不能独立运行。不过在有些情况下,因为某些专利算法在商业用途里只能授权使用,所以 VTK 提供的部分代码只能以动态链接库的方式使用,所以应该熟悉编译动态链接库的方法。其他较常见的重要变量有 VTK_USE_PATENTED 、VTK_USE_HYBRID 等,编译时使它们打开开关,就可以编译出相应的库以便日后使用了。

图 1
1.3 编译库
以下以 Windows 平台下的 Visual Studio 6.0 编译环境为例来说明使用方法,不再声明。
打开用 CMake 产生的 .dsw 文件,选择工程类型进行编译。工程类型主要分两类:Release 和 Debug ,开发过程中一般用 Debug ,到发行时再用 Release ,所以在此用Debug即可。编译整个工程产生全部库,这个过程所需时间很长。编译完成后,会在 CMake 里面指定的目标目录内(如 vtkbin )产生编译出的库文件(缺省在 vtkbin/bin/Debug 目录内)。
2 在 Visual Studio 6.0开发环境下使用 VTK 库
VTK 库编译好了以后,就可以在 Visual Studio 开发环境下使用 VTK 库了。使用 VTK库首先要设置头文件和库文件的路径,以便使用 VTK 库的程序在编译和链接的时候可以搜索到。头文件的位置即源代码的各个子目录,里面包含了大量的 .h 文件。将其路径加入到 Visual Studio 6.0 的 Tools -> Options -> Directories 内,如图 2。注意除了源码的各个子目录外,还要加上一个 vtkConfigure.h 文件的路径,它在 CMake 产生的目标目录内。库文件的设置与此类似,也在 Directories 页面进行,其路径是前述编译产生库文件的目录(如 vtkbin/bin/Debug )。这样设置好路径以后,使用 VTK 库的程序就可以正确地编译和链接了。对于使用动态链接库的程序来说,此时还不能运行编译出来的可执行程序( .exe),还需要一步,即把 VTK 的动态链接库文件所在路径加入操作系统的环境变量 PATH ,或直接将这些库文件拷贝到系统目录。

图 2
3 VTK 库编程特点
VTK 库是用面向对象的 C++ 语言写成的,由于主要开发者有着十数年涉及可视化系统的经验,所以 VTK 拥有非常合理的模型和结构。
VTK 的编程风格在教科书的附录 A,包括命名规范、术语定义、各类对象的用途说明等。值得注意的,比如它的对象工厂(Object Factory)概念。在 VTK 里,是用::New() 的方式来初始化对象的,而不是用 C++ 中的 new 来新建对象,对象工厂不仅可以做到代码与设备无关,而且通过引用计数(reference counting),可以使程序清晰简明,不容易发生内存泄漏或崩溃的问题。
VTK 中实现了数百个类及其方法,它们之间简化的继承和关联关系可以从教科书附录 A.3 的图中看到。熟悉不同的类的用途和它们之间的关系,对编程十分有利。
对开发者来说,如何扩充这个类库是重要的,教科书的附录 A.4 介绍了这个问题,而用户指南的开发者指南部分有一章来讲具体的做法。
4通过例子学习 VTK 概念及编程
要用 VTK 库进行可视化编程首先要对可视化要有一定的概念和基础。除了普通的可视化教科书以外,VTK 提供的教科书本身就非常好。VTK 源程序包的 Example 目录包括了一系列例子,它们都有详尽的注释。一步步学习这些例子,可以很容易理解 VTK 涉及的可视化概念和 VTK 编程的一般特点。
学习这些例子首先要成功编译运行它们。这个步骤跟编译库类似,也需要先用 CMake 工具生成 Visual Studio 的工程文件,然后编译;而要保证程序能正确运行,还得保证 VTK 库文件在环境变量的 PATH 内。
初学者应该从 Tutorial 目录内的 Step x 例子入手,它们从最简单的 VTK 程序开始,一步步地增加概念,演示了各种可视化概念。注意例子里的注释,以第一个程序(Step1 的 Cone 程序)为例,看一下源程序:

源程序:Example/Tutorial/Step1/Cxx/Cone.cxx
//
// This example creates a polygonal model of a cone, and then renders it to
// the screen. It will rotate the cone 360 degrees and then exit. The basic
// setup of source -> mapper -> actor -> renderer -> renderwindow is
// typical of most VTK programs.
//

// First include the required header files for the VTK classes we are using.
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkCamera.h"
#include "vtkActor.h"
int main( int argc, char *argv[] )
{
 //
 // Next we create an instance of vtkConeSource and set some of its
 // properties. The instance of vtkConeSource "cone" is part of a
 // visualization pipeline (it is a source process object); it produces data
 // (output type is vtkPolyData) which other filters may process.
 //
 vtkConeSource *cone = vtkConeSource::New();
 cone->SetHeight( 3.0 );
 cone->SetRadius( 1.0 );
 cone->SetResolution( 10 );
 //
 // In this example we terminate the pipeline with a mapper process object.
 // (Intermediate filters such as vtkShrinkPolyData could be inserted in
 // between the source and the mapper.)  We create an instance of
 // vtkPolyDataMapper to map the polygonal data into graphics primitives. We
 // connect the output of the cone souece to the input of this mapper.
 //
 vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
 coneMapper->SetInput( cone->GetOutput() );

程序段 1
这个简单的例子是一个控制台下的程序,创建一个棱锥,在屏幕上绘制,旋转360度后退出。程序虽简单,但已经包括了数据源、映射器、演员、绘制器、绘制窗口等概念,这些概念在 VTK 编程中几乎都是必然涉及的。通过这个例子,就可以对教科书里讲到的各种可视化概念(如相机、演员),编程模型(如管道)等有直观的了解了。
这里仅举这个最简单的例子,事实上,VTK 自带的例子循序渐进,从简单的概念,到各种复杂的概念、算法和数据结构、GUI 编程、直到具体的应用等,都做了很好的例证。结合教科书和例子,可以较快地理解 VTK 的各个方面。
比如说,如果要用 VTK 在 Win32 环境下编程,应该学习 Example/GUI/Win32 下的例程,如果要用 MFC 框架,那么可以参考其中的 vtkMFC 例程。体会 VTK 库和 Win32 的关系、和 MFC 框架的关系,以便在这些平台上开发自己的程序。这需要对 VTK和操作系统、编程环境本身有比较深入的了解,而这种了解对自行开发程序是十分必要的。
5 用 VTK 进行 CT 片三维重构
VTK 作为一种通用的可视化类库,在科学和工程界有着广泛的应用。其中一种重要而常见的应用就是在医学领域,比如著名的“可视化人”项目,就有 VTK 的应用。实际上,VTK 在医学方面的应用是是 VTK 比较强调的,在它提供的例程应用中,就有专门的医学目录。学习它们,并应用于我们的项目中,是一条合适的途径。
比如,如果要做一个 3D 的医学影像系统,其中重要的一个环节就是三维重构,这也是在全膝置换手术中需要的。所以,用 VTK 进行 CT 片的三维重构,就是一个合适的应用的例子。
利用 VTK 做 CT 片的三维重构,从算法和数据结构来看,就是一个读取数据问题和一个图形显示问题。
对于我们手里的 CT 片,因为它们符合 DICOM 3.0 标准,所以对它们的读取还是相对容易的。VTK 已经实现了这类数据的读取,vtkImageSource类的很多子类都可以完成这种工作,如vtkImageReader 类或者 vtkVolumeReader 等。这样我们编程的时候只要指定必须的参数,就可以实现对单张 CT 片乃至 CT 片序列的读取了。根据 VTK 的数据管道,原始数据读取入了以后,就可以使用各种各种过滤器进行数据转换,在这个例子里,即进行表面抽取、影射,然后就可以绘制了。因为是三维重建,所以还应该加入交互器,以便可以在绘制窗口里进行交互。
关于重建算法,对于 CT 片这种三维规则数据场,可以采取成熟、基本的算法来进行三维重建,比如 MarchingCubes 算法。
我们使用 Visual Studio 6.0 开发平台来完成上述的工作,使对 CT 片的读取、重建及显示、交互等功能融合到 MFC 的框架中,以便提供一个方便的用户接口。具体的程序另件给出,各部分的功能可以参考注释。

[参考文献]
1.The Visualization Toolkit An Object-Oriented Approach To 3D Graphics, 3rd edition
2.The Visualization Toolkit User's Guide
3.VTK 源码:http://www.vtk.org/get-software.php
4.VTK 电子文档:http://www.vtk.org/get-software.php
5.VTK 邮件列表:http://public.kitware.com/mailman/listinfo/vtkusers
6.http://digitalne.nju.edu.cn/new/course/vtk/index.htm