Advertisement

VTK与ITK在VS(2008,2012)下的安装

阅读量:

必须选用32位版本,并且应先安装VTK软件库,在高级选项卡中指定名为Module_ITKVtkGlue的部分必须被勾选(以便确保两个库的有效连接)。只有这样做才能与前文所述的VTK实现相连接

采用QT5版本:qt-opensource-windows-x86-msvc2012_64_opengl-5.2.1;配置为:qt-vs-addin-1.2.2 opensource VS 选型:VS 64位版本

请记住,在处理相关问题时,请统一进行释放操作。同样地,在进行调试时,请保持一致的操作。(为确保程序正常运行,请确保所有与QT和VTK连接的库都已进行 release 处理)建议先执行 release 操作后再进行 debug。您可以选择性地重新编译相关代码。将指定目录下的源代码分别复制到新建的 release 和 debug 目录中。如果不需要保留这些配置,则可以直接从源代码中删除或不执行相应的步骤。通过编辑相应的Makefile或使用cmake命令来设置安装路径。无需重新编译整个项目的Makefile或cmake配置即可完成安装设置。

第一章VTK与ITK的安装与测试

1.1获取安装资源

(1)CMake安装资源

作为一个跨平台的自动化构建工具,CMake主要用于编译VTK和ITK,并从该网站上的资源页面下载一个专门针对Windows系统的安装版本

(2)VTK安装资源

VTK可通过官方网站http://www.vtk.org/VTK/resources/software.html获取包括vtk-5.6.1-win32.exe(适用于Windows系统的安装程序)以及vtkdata-5.6.1.zip和vtk-5.6.1.zip在内的相关软件资源包。

(3)ITK安装资源

ITK可从其官方网站http://www.itk.org/ITK/resources/software.html获取两个软件包:一个是名为"InsightToolkit-3.20.0"的ZIP文件包(ID: InsightApplications-3.20.0),另一个是名为"InsightApplications-3.20.0"的ZIP文件包(ID: InsightToolkit-3.20.0)。这些软件包包含所需的所有资源。

注:这些安装操作均基于Windows XP操作系统,并依赖于Visual Studio开发环境。对于其他操作系统而言,在执行这些步骤时可能会遇到问题。此外,请注意以下事项:如果希望将所有软件一次性安装到同一个硬盘分区,则可能需要至少30GB的空间。由于安装过程耗时较长,请建议大家在开始操作前合理规划好存储空间。

1.2安装步骤

在安装和配置的过程中,路径设置的重要性不容忽视.为了使用户的安装过程能够顺利进行,本人按照与Visual Studio 2008相同的路径结构对主要相关软件进行了整合和排列,如图1-1所示.并参考该图1-1中的结构进行操作.

1.2.1 VTK的安装

系统win7 64位,已装vs2012,所有软件安装及打开都用管理员身份。

下面详细介绍QT和VTK结合开发的环境配置步骤

1. 下载软件版本及地址

① qt的安装文件qt-opensource-windows-x86-msvc2012_opengl-5.3.2.exe

获取该资源包

② qt的vs2012插件qt-vs-addin-1.2.3-opensource.exe

http://qt-project.org/downloads

③ cmake-2.8.12.2-win32-x86.rar

[()

④ VTK-6.1.0.zip

该资源路径被包含有该版本文件

⑤ VTKData-6.1.0.zip

该资源的下载链接为http://www.vtk.org/files/release/6.1/VTKData-6.1.0.zip

2. 安装qt

分别执行上面的①②后,添加系统路径。

变量名:PATH

变量值:D:\Qt\Qt5.3.2\5.3\msvc2012_opengl\bin

(qt安装在D:\Qt\Qt5.3.2目录,qt插件安装在D:\Qt目录)

启动Visual Studio 2012并进入选项设置界面→选择" Qt "→进入" Qtoptions "→选择" Qt versions "→点击" Add "按钮

至此你就可以在VS2012中创建qt项目了。

下面开始配置VTK。

3. 把④⑤解压到D:\VTK6下,④改名为VTKSource,⑤改名为VTKData

解压③后安装cmake,我的安装路径是在D:\VTK6\CMake2.8

(1) 打开cmake-gui.exe

分别在源代码文件夹和编译目录中设置相应的项目路径,并将目标编译位置设置为指定位置。随后配置项目后,请选择Visual Studio 2015(即Visual Studio 11)版本作为开发环境。但因为是64位操作系统,并且有教程建议不要选择‘Visual Studio 2015 Win64’版本(实际操作中未尝试过此配置),因此请谨慎选择相应选项进行测试

等待配置完成后,会有错误发生,需要做如下修改:

build_shared_libs勾选

点击addentry,添加qt的安装路径

vtk_group_qt勾选

再次点击configure,完成后再做如下修改

将VTK qt版本号设置为5,并确保QT_QMAKE_EXECUTABLE环境变量配置为你项目的qmake.exe路径;重新配置Build Settings;无错误提示后点击Generate键;生成完整的项目文件夹。

Qt5Gui_glu32_LIBRAYRY 错误解决

单击cmake界面上方右侧的AddEntry按钮以设置CMAKE_PREFIX_PATH选项,并在其中将TYPE属性设为PATH类型。

在C:\ProgramFiles\Microsoft SDKs\Windows\v6.0A\Lib\x64这个目录下,并连接上述两个路径变量,并用分号将它们分开设置

(每次CMAKE都要重复一次)

或者(推荐,WindowsKits比MicrosoftSDKs框架更新,更好支持QT):

复制代码
    C:/Qt/Qt5.2.1/5.2.1/msvc2012_64_opengl/lib/cmake/Qt5Gui/Qt5GuiConfigExtras.cmake  
    set(CMAKE_LIBRARY_PATH "C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64")

注意 要安装Microsoft SDKS或者Windows Kits

Windows Kits对应C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x64(建议)

需要注意的是:vtk_data_store 用于告知cmake 确定 vtk 所需的数据存储位置,我们提供的数据位于该处。

请确认路径设置:D:\VTK...

build_examples: 主要是询问是否需要编译VTK中的例子,在学习这个教程的情况下表明你可能刚接触VTK软件包,请开启该功能。
build_shared_libs: 如果选择关闭(off),系统仅生成lib静态库文件,默认情况下足够用于本地开发。
而选择开启(on)则会生成额外的DLL动态链接库文件,并支持基于动态链接库的编程方式。
建议根据项目需求选择适合的选项。

请根据需求设置参数:对于希望进行并行计算的用户,请将此参数设为启用状态;而对于仅用于学习VTK的用户,则应将其保持为关闭状态。

所有的项目不再有问题,并且会变成灰色。这时就可以按OK键操作了。随后仅仅几秒钟后, cmake程序就会自动退出, 并生成好了适用于VC6环境的make文件。

在你的编译文件夹中(D:\VTK6\VTKBin2),请定位到VTK.sln文件,并以管理员身份启动以便顺利进行两次编译操作。

A.release版本编译

可以选择生成相应的解决方案。完成生成后可能会遇到SAFESEH错误,在链接的命令行界面中输入/safeseh:no,并找到对应的项目进行处理。之后再进行一次完整的生成过程。

B.debug版本编译

和release编译步骤相同。

完成后将位于release目录中的QVTKWidgetPlugin.lib和QVTKWidgetPlugin.dll移动到D:\Qt\Qt5.3.2\5.3\msvc2012_opengl\plugins\designer文件夹内;随后打开QTCreator即可查看QTVTK选项。

然后把D:\VTK\prefix\bin下添加到系统环境变量的Path

(3)上述步骤仅负责将下载下来的VTK源码转换为适用于Windows平台的setup文件,并将其定义为"install"过程;但在CMAPTE过程中需先完成安装工程(即INSTALL子进程)方可生成相应的安装文件。(且在此阶段CMAPTE不会处理INSTALL子进程);于VS2015 IDE中的解决方案中定位到该 INSTALL 子进程后点击"BUILD ONLY PROJECT"进行操作即可完成后续的"build"过程;完成后即可完成安装操作(如图所示)。

这样就会在C:\ProgramFiles(x86)\VTK下生成如下文件:

表示vtk安装成功。

(4)添加系统路径

PATH=C:\ProgramFiles(x86)\VTK\bin

QTDIR=D:\Qt\Qt5.3.2\5.3\msvc2012_opengl

以上就完成了所以的配置,下面举例如何建立自己的项目

1. 打开vs2012,创建新项目,选择QtApplication

VTK官网上的QT_VTK example:

http://www.vtk.org/Wiki/VTK/Examples/Cxx/Qt/QImageToImageSource

添加包含目录及所有的库文件。最终结果如下。

注意:

以后新建QT与VTK程序时候,

Qt5Gui_glu32_LIBRAYRY 错误解决

,单击CMake界面右上角的"Add Entry" 按钮,并在其中选择"Options"选项卡下的"CMAKE_PREFIX_PATH" 选项进行配置。(TYPE 选项设置为PATH)

在C:\ProgramFiles\Microsoft SDKs\Windows\v6.0A\Lib\x64与前文QT路径之间插入一个分号作为分隔符

推荐方法:(不必再以后新建VTK,QT程序时候,每次都加CMAKE_PREFIX_PATH)

例如,在 QT 的安装目录中找到 Qt5GuiConfigExtras.cmake 文件作为预处理指令放置于该文件的起始部分。

set(CMAKE_LIBRARY_PATH"C:\ Program Files\ Microsoft SDKs\ Windows\ v6.0A\ Lib\ x64")

在Visual Studio 2010环境中打开通过CMake构建生成的工程文件,请注意包含以下三个项目:ALL_BUILD、bilateral_filter和ZERO_CHECK。

程序运行时异常终止了,想进入调试模式查看问题具体出在什么地方。

但编译的时候出现错误提示:

程序无法启动,并且找不到指定的项目文件夹(例如:e:\projects_pcl\pcl_filters\bilateral_filter\build\x64\Debug\ALL_BUILD)

**
**


解决办法:

在VS2010中删除ALL_BUILD和ZERO_CHECK这两个项目文件就足够了只剩下一个工程文件

移除工程文件的方法:鼠标右击对应的工程文件,单击“移除”。

2. 重新编译进调试模式,可以了。

问题解决。

**
**

**
**

2.3 创建一个简单的VTK程序

在第2.2节中进行了详尽的介绍以指导如何编译与安装VTK软件包。随后的问题在于如何验证其正确性以及如何调用先前编译好的VTK函数库。

为了构建项目,请创建一个名为CMakeLists.txt的源代码管理文件。在之前的章节中已经介绍了CMake的基本知识,并且成功配置过VTK开发环境。让我们接下来深入探讨一下CMake的相关知识吧。

2.3.1 什么是CMake?

对于那些使用VTK进行开发的人来说,掌握这一项关键的技术工具是CMake。这一项关键的技术工具是CMake的产生与发展也与VTK紧密结合在一起。以下是维基百科中的一段文字:大约在20年前(1995年),由Stichting Computer Graphics Lab (S-CGL) 发布了一段核心代码。随后在社区中逐渐发展完善,并于2005年正式推出了完整版本。如今已成为了被广泛采用的关键技术之一,并在多个领域得到了实践应用。

CMake是出于为美国国家医学图书馆资助的VisibleHuman Project项目中使用的Insight Segmentation and Registration Toolkit (ITK)软件实现跨平台构建目标而开发出来的;它借鉴了开发者Ken Martin所研发的pcmaker这一工具的设计理念;然而pcmake最初是为了支持 Visualization Toolkit(VTK),一个开源三维图形与可视化系统的出现而产生的;如今VTK也采纳了这一工具作为其构建框架的基础。

从上述对CMake的介绍可以看出,CMake实际上是一个跨平台的应用程序构建工具,它可以根据不同的操作系统自动生成与该系统相关的应用程序配置文件,例如在Windows系统上采用VisualStudio则会生成.dsw或.sln等项目文件。通过使用CMake,我们可以有效地管理大型项目,VTK便是采用了这一技术作为其项目管理工具之一。此外,CMake还简化了应用程序构建流程,只需在项目的每一个目录中编写一个CMakeLists.txt文件即可生成所需的编译文件。值得注意的是,CMake支持原地构建和分步构建两种模式:原地构建意味着编译得到的二进制文件与源代码文件位于同一个目录;而分步构建则意味着编译链接完成后生成的二进制文件与源代码分别存放在不同的目录中,这种模式我们之前在讲解VTK的编译过程时也有所涉及。

具有独特的编程语言和语法结构,
采用CMake进行工程管理的过程,
即编写名为CMakeLists.txt的脚本文件的过程。
在一般情况下,
每个目录都应该包含一个同名的配置文件,
该配置文件的名字必须是:
... CMakeLists.txt ...
这种做法具有显著的效果。
需要注意的是,
如果误将名称设为cmakelists.txt,
在Windows系统中通常不会有问题;
但是一旦切换到其他操作系统,
如Ubuntu时,
就会遇到找不到... CMakeLists.txt...的情况。
为了确保兼容性和稳定性,
建议无论在哪个平台上都使用
... CMakeLists.txt ...
这个标准名称,
并严格遵守其大小写的正确性。

2.3.2 写一个简单的CMakeLists.txt脚本文件

为了验证VTK是否成功安装,请创建一个基本的VTK工程来进行测试。书本中提到的所有示例均为CMake所配置管理。同样地,请首先创建一个CMakeLists.txt文件(为了便于本教程后续示例工程文件的管理和组织,在本书VTK安装目录中已创建了一个名为Examples的文件夹)。该Examples文件夹内存储了书中所述的所有程序示例,并遵循以下命名规则:每个程序示例命名为XXX_ProjectName格式(其中XXX表示示例所在的章节编号),ProjectName为工程名称(例如:2.3.2_TestVTKInstall)。完整的完整路径为:D:\Toolkits\VTK\Examples\2.3.2_TestVTKInstall。(请暂且不要急着询问原因,请按照说明步骤逐一尝试操作即可)后续的内容将逐步代码化解释说明其原理与实现细节(即‘知其然’),随后会逐步展开详细说明其中的道理与机制(即‘知其所以然’)。

在此时此地,在该目录下创建一个新的名为CMakeLists.txt 的记事本文件。其中输入内容如下:

复制代码
    cmake_minimum_required(VERSION 2.8)
     
    PROJECT(Cylinder)
     
    find_package(VTK REQUIRED)
    include(${VTK_USE_FILE})
     
    add_executable(Cylinder MACOSX_BUNDLE Cylinder)
     
    if(VTK_LIBRARIES)
      target_link_libraries(Cylinder ${VTK_LIBRARIES})
    else()
      target_link_libraries(Cylinder vtkHybrid vtkWidgets)
    endif()

接着在helloword目录下新建一个cpp文件,名字Cylinder.cpp,输入内容:

复制代码
 #include "vtkCylinderSource.h"

    
 #include "vtkPolyDataMapper.h"
    
 #include "vtkActor.h"
    
 #include "vtkRenderer.h"
    
 #include "vtkRenderWindow.h"
    
 #include "vtkRenderWindowInteractor.h"
    
 #include "vtkProperty.h"
    
 #include "vtkCamera.h"
    
 #include "vtkSmartPointer.h"
    
  
    
 int main()
    
 {
    
   // This creates a polygonal cylinder model with eight circumferential facets
    
   // (i.e, in practice an octagonal prism).
    
   vtkSmartPointer<vtkCylinderSource> cylinder =
    
     vtkSmartPointer<vtkCylinderSource>::New();
    
   cylinder->SetResolution(8);
    
  
    
   // The mapper is responsible for pushing the geometry into the graphics library.
    
   // It may also do color mapping, if scalars or other attributes are defined.
    
   vtkSmartPointer<vtkPolyDataMapper> cylinderMapper =
    
     vtkSmartPointer<vtkPolyDataMapper>::New();
    
   cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
    
  
    
   // The actor is a grouping mechanism: besides the geometry (mapper), it
    
   // also has a property, transformation matrix, and/or texture map.
    
   // Here we set its color and rotate it around the X and Y axes.
    
   vtkSmartPointer<vtkActor> cylinderActor =
    
     vtkSmartPointer<vtkActor>::New();
    
   cylinderActor->SetMapper(cylinderMapper);
    
   cylinderActor->GetProperty()->SetColor(1.0000, 0.3882, 0.2784);
    
   cylinderActor->RotateX(30.0);
    
   cylinderActor->RotateY(-45.0);
    
  
    
   // The renderer generates the image
    
   // which is then displayed on the render window.
    
   // It can be thought of as a scene to which the actor is added
    
   vtkSmartPointer<vtkRenderer> renderer =
    
     vtkSmartPointer<vtkRenderer>::New();
    
   renderer->AddActor(cylinderActor);
    
   renderer->SetBackground(0.1, 0.2, 0.4);
    
   // Zoom in a little by accessing the camera and invoking its "Zoom" method.
    
   renderer->ResetCamera();
    
   renderer->GetActiveCamera()->Zoom(1.5);
    
  
    
   // The render window is the actual GUI window
    
   // that appears on the computer screen
    
   vtkSmartPointer<vtkRenderWindow> renderWindow =
    
     vtkSmartPointer<vtkRenderWindow>::New();
    
   renderWindow->SetSize(200, 200);
    
   renderWindow->AddRenderer(renderer);
    
  
    
   // The render window interactor captures mouse events
    
   // and will perform appropriate camera or actor manipulation
    
   // depending on the nature of the events.
    
   vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
    
     vtkSmartPointer<vtkRenderWindowInteractor>::New();
    
   renderWindowInteractor->SetRenderWindow(renderWindow);
    
  
    
   // This starts the event loop and as a side effect causes an initial render.
    
   renderWindowInteractor->Start();
    
  
    
   return 0;
    
 }

在D盘中的Toolkits目录下有VTK工具箱,在VTK Examples子目录中的2.3.2_TestVTKInstall目录中存有两个文件分别是CMakeLists.txt以及TestVTK安装.cpp这两个文件。启动CMake程序后在窗口中定位到源代码存放的位置并输入D盘中的Toolkits子目录下的VTK Examples中的TestVTK安装位置接着定位到编译二进制存放的位置并将其指向D盘中的Toolkits子目录下的VTK Examples中的TestVTK安装目录下的bin选项之后点击配置按钮就会出现如图所示的配置界面

您需要点击"Yes"按钮并随后设置编译环境为Visual Studio 2008 Win64系统版本,在CMake界面中启动配置流程。这个小型工程很快就能完成配置工作,在界面上会展示一些带有红色背景的选择项。如果不勾选"Advance"视图选项,默认情况下只会出现两个关键参数:CMAKE_INSTALL_PREFIXVTK_DIR 。其中CMAKE_INSTALL_PREFIX 指的是编译安装目录,默认指向您在CMakeLists.txt中所定义的项目名称位置(即D:/Toolkits/VTK/VTK-5.10-bin)。具体来说, 这个路径指的是VTKConfig.cmake文件所在完整的存储位置。对于CMAKE_INSTALL_PREFIX, 编程环境中默认设置为类似"C:\Program Files\XXX"(其中XXX是由您在项目定义中的project(XXX)命令确定的具体工程名称)。而对于VTK_DIR, 在正常情况下, CMake会在编译完成后自动定位到正确的路径位置;如果遇到无法识别或定位到指定版本的情况(尤其是当计算机已经预先编译了多个不同版本的VTK时),您可以使用"BrowseBuild..."按钮手动选择对应的编译目录位置, 或者直接手动输入所需路径信息进行处理。

设置完毕后再次点击"Configure"。当不再显示红色项时继续操作。启动生成流程。完成后,请前往软件界面中的"Wheretobuild the binaries"参数设置页面。

图2.9 用CMake构建TestVTKInstall工程所生成的文件

在我们已经非常熟悉的TestVTKInstall.sln项目中,在没有意外的情况下,默认情况下启动编译过程,并通过键盘快捷键F7来执行此操作。

图2.10 ExecutableFor Debug Session对话框

对于不熟悉Visual Studio 2008的新手而言,误以为这是一种错误现象,实际上只是由于项目的启动工程未生成可执行文件所致。右键点击SolutionExplorer中的TestVTKInstall工程,在弹出菜单中选择将其设为启动项目。再次按下F5键运行后(如图2.11所示),左侧为VTK展示窗口、右侧为终端控制台窗口。通过CMake构建的项目,默认情况下会包含控制台窗口以方便调试信息输出显示。

当程序运行到这里时, 如果程序运行的结果与图2.11中的结果相似, 则表明您的计算机已成功安装了VTK。

图2.11示例2.3.2_TestVTKInstall运行界面

2.3.3 CMake的几个常用命令

为便于描述,我们把2.3.2节里的CMakeLists.txt的内容再列出来,并标上行号:

复制代码
    cmake_minimum_required(VERSION 2.8)
     
    PROJECT(Cylinder)
     
    find_package(VTK REQUIRED)
    include(${VTK_USE_FILE})
     
    add_executable(Cylinder MACOSX_BUNDLE Cylinder)
     
    if(VTK_LIBRARIES)
      target_link_libraries(Cylinder ${VTK_LIBRARIES})
    else()
      target_link_libraries(Cylinder vtkHybrid vtkWidgets)
    endif()

该CMake命令为cmake_minimum_required(VERSIONmajor[.minor[.patch[.tweak]]][FATAL_ERROR])。功能说明:用于指定构建工程所需的最低CMake版本要求。参数VERSION必须的关键字且必须大写(参数VERSION为必须的关键字且必须大写)。第二个参数指定所需CMake版本号(第二个参数指定所需CMake版本号)。第三个参数可选且为内置关键字"FATAL_ERROR"(第三个参数可选且为内置关键字"FATAL_ERROR")。若所使用的CMake版本未达到最低要求,则会弹出图2-12所示错误提示信息并终止构建过程(若所使用的CMake版本未达到最低要求,则会弹出图2-12所示错误提示信息并终止构建过程)。

图2.12CMake构建工程时的错误提示信息

第2行,project 命令。完整语法格式为:

project(projectname[CXX][C] [Java])

通过指定该命令来确定工程名称,并可以选择该命令来设置工程所支持的语言;其中支持语言的参数是可选配置项,默认情况下支持C/C++语言。此外,在这种配置模式下,默认会定义两个CMake变量:_BINARY_DIR以及**_SOURCE_DIR**;在这个例子中即分别为TestVTKInstall_BINARY_DIR以及TestVTKInstall_SOURCE_DIR。然而,在CMake系统中已经预先定义了两个相关变量:PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR;它们与前面提到的两个变量具有相同的取值范围;为了便于统一管理和引用,在后续配置中可以直接使用PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR分别表示工程的编译路径与源码路径(例如在这个例子中即为D:\Toolkits\VTK\Examples\2.3.2_TestVTKInstall\bin”与“D:\Toolkits\VTK\Examples\2.3.2_TestVTKInstall”)。这样一来即使后续对工程名称进行修改也不会影响到这两个预定义变量的作用范围

在项目命令中,默认情况下第一个参数包含了另一个关键变量 PROJECT_NAME 。在第5和6行的位置上,我们调用了该变量的具体值 {PROJECT_NAME}。请注意,在CMake语言中,默认会使用‘${变量名}’的形式来引用当前环境中的特定环境变量。

第3行find_package命令,完整语法格式为:

find_package(

[version]

[EXACT]

[QUIET]

[[REQUIRED|COMPONENTS][components...]]

[NO_POLICY_SCOPE])

find_package命令用于搜索并加载外部工程配置,并包含的关键字字段为**< package>_FOUND**,该字段用于指示所搜索工程的存在状态。参数[REQUIRED]表明所搜索的外部工程对于当前工程是必要的;如果没有找到所需外部工程,则会导致整个构建过程终止。例如,在VTK附带的例子目录下的CMakeLists.txt文件中包含以下CMake脚本语句:

(摘自VTK-5.10\Examples\Tutorial\Step1\Cxx\CMakeListx.txt):

find_package(VTKREQUIRED)

if(NOTVTK_USE_RENDERING)

message(FATAL_ERROR"Example${PROJECT_NAME} requires VTK_USE_RENDERING.")

endif(NOTVTK_USE_RENDERING)

实际上这四行脚本的功能跟第3行实现的功能是相同的。具体说明find_package命令其他参数的意义,请参见CMake帮助文件(CMake安装目录下的doc文件夹中有相关文档)。

第4行include命令,完整的语法为:

include(<file|module>

[OPTIONAL]

[RESULT_VARIABLE]

[NO_POLICY_SCOPE])

指定了包含一个文件或模块的情况。如果所指定的是一个模块,则应在预设路径中的CMAKE_MODULE_PATH中进行搜索和导入操作;举例而言,在本例中所指定的是VTK这一特定软件库,则应在预设路径中的CMAKE_MODULE_PATH中进行相应的导入操作;其中变量名CMAKE_MODULE_PATH被定义为指向预设路径中的CMask安装目录;安装配置完成后(通常位于...),可以在...目录下的share\cmake-2.8\Modules子目录中查找找到FindVTK.cmake这一特定配置文件;通过查阅该配置文件即可获取有关VTK_USE_FILE变量的相关说明信息。

在VTK编译目录(D:/Toolkits/VTK/VTK-5.10-bin/)中位于VTKConfig.cmake文件中可以看到变量VTK_USE_FILE被设置为:

#Thelocation of the UseVTK.cmake file.

SET(VTK_USE_FILE"D:/Toolkits/VTK/VTK-5.10-bin/UseVTK.cmake")

换言之,include (${VTK_USE_FILE})命令就是包含UseVTK.cmake文件。

第5行add_executable 命令,完整语法为:

add_executable(

[WIN32]

[MACOSX_BUNDLE]

[EXCLUDE_FROM_ALL]

source1source2... sourceN)

该工程将生成一个命名为的可执行程序(在此示例中使用${PROJECT_NAME}变量来确定程序名称),其相关源代码包括source1、source2等…(若项目包含多个模块或函数,则这些模块或函数通常以空格分隔存储);如果项目中有多个独立的功能模块或函数,则建议首先定义一个集合变量用于组织这些模块或函数名称,并通过取集合元素的方式获取完整列表(例如,在某个项目中存在main.cpp、utils.cpp和data加工.cpp三个核心功能模块,则可以编写如下代码)

set(projectname_srcsource1.cpp source2.cpp source3.cpp)

add_executable(projectname${projectname_src})

与下行是等价的:

add_executable(projectnamesource1.cpp source2.cpp source3.cpp)

第6行 target_link_libraries命令,完整语法为:

target_link_libraries(

[item1[item2[...]]]

[[debug|optimized|general]]...)

指定生成可执行文件时需连接哪些文件?参数名称应与第5行指定的一致。举例而言,在本例中我们采用${PROJECT_NAME}来获取所需名称,并且在编写这些连接函数时不需携带“.lib”的后缀。

通常这个时候, 你可能会问: 为什么必须要链接vtkRendering.lib这个文件呢?

在TestVTKInstall.cpp文件中调用了一个包含vtkRenderWindow和 vtkSmartPointer这两个关键类的对象实例。为了获取这些对象的相关信息, 我们需要确定这两个类对应的头文件路径, 分别为:D:\Toolkits\VTK\VTK-5.10\Rendering 和 D:\Toolkits\VTK\VTK-5.10\Common。基于观察发现, VTK项目采用统一命名规范, 所有类名均以" vtk"开头, 这提示我们其生成的功能库也应遵循类似的命名习惯。进一步分析显示, 与 vtkRenderWindow 和 vtkSmartPointer相关的头文件 vtkRenderWindow.h 和 vtkSmartPointer.h 分别位于上述两个目录下, 同时在编译目录中可以直接找到对应的lib文件: vtkRendering.lib 和 vtkCommon.lib。因此, 我们有理由推测这两者的接口定义即存在于相应的lib文件之中。经过慎重考虑后, 最终决定将依赖于这两个函数库: vtkRendering 和 vtkCommon

配置 VTK 库组件时,请指定以下组件:包括 vtkCommon、vtkFiltering、vtkImaging、vtkGraphics、vtkGenericFiltering 和 vtkIO

以下为常用的VTK渲染器类型:包括 vtkRendering; vtkVolumeRendering; vtkHybrid; vtkWidgets; vtkInfovis;vt geovis;vtfViews;vtt Charts.

在之前的讨论中已经阐述过,在UG中使用set命令的作用是定义某个特定变量。获取变量值的方式是通过使用类似于{VTK_LIBRARIES}这样的引用形式。那是否意味着我可以直接在target_link_libraries的最后一行输入${VTK_LIBRARIES}而不必逐一列出所有的函数库名称呢?答案当然是肯定的。

在此阶段之后,则已掌握CMake所涉及的主要六个命令——cmake_minimum_required、project、find_package、include、add_executable以及target_link_libraries等的作用与功能,在一个包含六条指令的CMakeLists.txt文件中(其中第一条通常与软件版本兼容性相关而无需特别说明),其余五条指令均为必要条款。

2.3.4 一个简单的VTK工程

复制代码
  #include"vtkRenderWindow.h"

    
  #include"vtkSmartPointer.h"
    
  int main()
    
 {
    
    vtkSmartPointer<vtkRenderWindow> renWin =vtkSmartPointer<vtkRenderWindow>::New();
    
    renWin->Render();
    
    std::cin.get();
    
     return 0;
    
  }

在代码中需要包含必要的头文件

在代码中需要包含必要的头文件

在第5行,通过智能指针实现了对vtkRenderWindow类型的实例化创建。其类型是vtkRenderWindow实例,并且这属于VTK类对象的基类功能。然而需要注意的是,在VTK中所有类都采用了保护成员变量的设计原则,在这种情况下直接使用普通的赋值方式并不可行:

具体来说,在下面所示的功能实现代码中无法直接创建或使用标准的 vtkRenderWindow 对象:

vtkClassExampleinstance;//vtkClassExample这个类显然并不存在,只是用于演示目的

要不然会提示如下的错误:

error C2248: vtkClassExample::vtkClassExample: cannot access a protected member element within the scope of vtkClassExample

所以,要构造VTK的对象可以用第5行的方法,或者用以下的方法:

vtkRenderWindow*renWin= vtkRenderWindow::New();

至于为什么,后面的内容会让你再“知其所以然”。

第6行,调用vtkRenderWindow里的方法显示并渲染VTK窗口。

第8行内容并无特别之处,并仅为让程序暂停以便接收用户的输入请求。目的是为了让你了解VTK窗口的大致形态,你可以选择将这一行注释掉来观察它是否迅速消失。

这个程序相当简单;它仅仅是一个VTK窗口,并没有任何其他组件。然而实际上这是一个基于VTK的应用程序;至少使用了两个相关的VTK类,并调用了几个核心功能模块。在后面的章节里;你还会经常与这个窗口打交道。

2.4 本章小结

在这一章开始时, 我们对安装VTK进行了充分的准备. 明确编译安装VTK前应先安装哪些软件的需求. 随后, 我们详细演示了如何进行编译VTK的过程. 整个过程相当简单. 最后, 安装完VTK后, 使用一个相对简单的程序来测试其是否正确运行. 这个程序是一个基于VTK展示窗口界面的小程序, 通过它我们不仅学到了编写CMakeLists.txt脚本的方法, 还熟练掌握了六个 essential CMake命令: cmake_minimum_required, project, find_package, include, add_executable 和 target_link_libraries.

1.2.2 ITK的安装

(1)创建ITK安装目录

首先下载并解压缩InsightToolkit-3.20.0.zip文件到位于E:\Program Files\ITK下的指定目录中,并将其重命名为InsightToolkit;接着,在上述目录中新建一个名为ITK_bin的文件夹,并将其用于存储编译好的二进制程序;其整体架构如图1-6所示:

图1-6 ITK目录结构

(2)CMake配置

首先打开CMake,并对其进行配置。如图1-8所示。ITK的配置与VTK类似:仅需将BUILD_SHARED_LIBS设为ON(可选);同样地,请注意以下几点:Builder Examples和Builder Tests也是可选项;丰富的事例有助于更好地理解ITK的功能;最后请指定CMAKE_INSTALL_PREFIX为E:\Program Files\ITK即可

图1-7 ITK配置安装

然后开始配置系统(由于配置选项较多),不同用户可以根据自身需求进行调整(以适应不同的使用场景)。以上的基本设置已经足够满足一般用户的开发与学习需求(无需手动调整)。如果未出现红色显示,则点击"Generate"键生成内容。

Advanced下面的 Module_ITKVtkGlue必须选择,才能和VTK连接

(3)生成解决方案

在E盘的Program Files目录下的ITK程序包中的ITK.sln配置文件类似于VTK的工作流程配置工具,请按照以下步骤操作:首先单击“生成”选项卡中的“Generate Solutions”按钮;若无错误提示,请访问位于ITK_bin目录下的VCExpress安装向导项目的vcbuild/VCExpress/vcproj/INSTALL.vcproj配置文件;然后在VCExpress项目的解法器窗口中定位到对应安装路径;选择该安装项后右键点击“属性”选项卡,在“Build Only”和“Deploy Only”前勾选复选框以限制构建和部署范围。

如果编译过程中有错误,应该删除ITK里面的文件,重新安装。

(4)ITK的配置

·打开工具->选项->项目和解决方案->VC++目录

包含文件:在后面分别添加(如图1-8所示):

图1-8 ITK包含文件的设置

E:\Program Files\ITK\include\InsightToolkit

E:\ProgramFiles\ITK\include\InsightToolkit\IO

E:\ProgramFiles\ITK\include\InsightToolkit\Numerics\FEM

E:\ProgramFiles\ITK\include\InsightToolkit\Numerics\NeuralNetworks

E:\Program Files\ITK\include\InsightToolkit\Numerics\Statistics

E:\ProgramFiles\ITK\include\InsightToolkit\SpatialObject

E:\ProgramFiles\ITK\include\InsightToolkit\Utilities

E:\ProgramFiles\ITK\include\InsightToolkit\Utilities\vxl\core

E:\ProgramFiles\ITK\include\InsightToolkit\Utilities\vxl\core\vnl

E:\ProgramFiles\ITK\include\InsightToolkit\Utilities\vxl\core\vnl\algo

E:\ProgramFiles\ITK\include\InsightToolkit\Utilities\vxl\vcl

E:\ProgramFiles\ITK\include\InsightToolkit\Algorithms

E:\ProgramFiles\ITK\include\InsightToolkit\BasicFilters

E:\ProgramFiles\ITK\include\InsightToolkit\Common

E:\ProgramFiles\ITK\include\InsightToolkit\gdcm\src

E:\ProgramFiles\ITK\include\InsightToolkit\Numerics

· 库文件:在后面添加E:\ProgramFiles\ITK\lib\InsightToolkit

环境变量配置:计算机->属性编辑器->高级选项->环境变量设置->新增:E:\Program Files\ITK\itk_bin;

为了将 E:\Program Files\ITK\bin 或者 E:\Program Files\ITK\itk_bin\bin\Debug 中的 .NET DLL 文件复制至 C:\WINDOWS\system32 中。

建议按照您具体的安装目录找到相应的文件,并按照图1-1所示进行配置

ITK编程步骤示例

使用 ITK, CMake 进行编程, 基本过程如下:

在项目配置阶段,请按照以下指令设置好相关目录:创建D:\I_VTK\test\src 和 D:\I_VTK\test\bin两个目录;其中src字段用于存储源代码;而bin字段则用于生成可执行文件。

如下 Hello ITK 示例.

1. 建立 D:/I_VTK/test/src/HelloITK, D:/I_VTK/test/bin/HelloITK

在 HelloITK 目录内创建新文件 named HelloWorld.cxx 并撰写其源代码实现。同时,在同一目录内新增 CMakeLists.txt 文件以配置 CMake 工具链设置。

3. HelloWorld.cxx:

复制代码
    #include "itkImage.h"

    
    #include <iostream>
    
    int main()
    
    {
    
       //声明图像类型,  像素类型为 unsigned short,  图像维数为 3维
    
       typedef itk::Image< unsigned short, 3 > ImageType;
    
  
    
       //新建一幅图像, 并将其赋值给图像类的智能指针, 智能指针不需要 delete
    
       //自动释放, ITK 中每一个类基本都提供智能指针, 且使用New() 实例化. 除少数极小的对象不使用智能指针
    
       ImageType::Pointer image = ImageType::New();
    
  
    
       std::cout << "ITK Hello World !" << std::endl;
    
       return 0;
    
     }
复制代码
     CMAKE_MINIMUM_REQUIRED(VERSION 2.4)               //CMake 最小版本
     PROJECT(HelloWorld)                                                 //工程名
     FIND_PACKAGE(ITK)                                                   //寻找 ITK
     IF(ITK_FOUND)
            INCLUDE(${ITK_USE_FILE})    //找到则使用, 否则需要手动指定 D:/I_VTK/ITK/ITK-3.14.0-bin
     ELSE(ITK_FOUND)
          MESSAGE(FATAL_ERROR
                          "ITK not found. Please set ITK_DIR.") //没有找到,弹出对话框提示
     ENDIF(ITK_FOUND)
     
     ADD_EXECUTABLEHelloWorld HelloWorld.cxx )         //生成可执行文件名, 及需要编译的源文件
     
     //该工程所需要的 ITK 子系统, 该句会生成工程所需的 ITk lib库文件
     TARGET_LINK_LIBRARIES(HelloWorld  ITKCommon)

注,CMakelists.txt中是不能出现上述注释的。

5. 使用 CMake进行配置.

Where is the source code:点击Browse,选择 D:/I_VTK/test/src/HelloITK

Where to build the binaries:点击Browse,选择 D:/I_VTK/test/bin/HelloITK

Configure,如果没有找到ITK路径,则需要手动指定:D:/I_VTK/ITK/ITK-3.14.0-bin

或指定为D:/I_VTK/ITK/ITK-3.14.0,该路径寻找ITK头文件。

配置成功后,点击 OK.

6. 打开D:/I_VTK/test/bin/HelloITK, 使用 VS 2005编译: HelloWorld.sln

至此成功.

需要注意的是:

配置CMakelist.txt, 主要涉及TARGET_LINK_LIBRARIES命令(HelloWorld ITKCommon)

在工程应用中涉及的ITK 子系统是什么?此处需要配置那个子系统的参数路径。

示例程序提供了大量ITK的使用,可以参考.

无需使用CMake来进行开发流程。这就会导致必须手动添加工程所依赖的lib,xxx.h。

1)按照通常的方法建立一个 C++Console工程,编写代码.

tool→option→Projects and Solutions→VC++ Directories中设置IncludeFiles,并在此处

在项目中添加所需的ITK头文件数量繁多,并且复杂的程序可能会需要用到所有的路径如D:/I_VTK/ITK/ITK-3.14.0/Code

在项目中添加所需的ITK头文件数量繁多,并且复杂的程序可能会需要用到所有的路径如D:/I_VTK/ITK/ITK-3.14.0/Code

目录下所有子目录,以及子目录的子目录

不使用 CMake自动生成配置文件,在完成 ITK 的编译之后进行安装并构建 INSTALL 工程。这样包含头文件和库文件将被正确地放置。

单独的目录,结构比较清晰。

配置所需的库:在Visual Studio中依次点击Project→Properties→Linker→Input,并在附加依赖项中指定所需库。

配置所需的Lib文件时,请注意包含所有所依赖的Windows头文件. 通过查看一个前面方法生成的工程实例,我们可以直观地了解相关功能.

依赖的 lib非常的多,非常麻烦,所以最好使用 Cmake进行自动配置.

1.2.3 InsightApplication的安装

为了更好地掌握VTK与ITK的基础知识,在这里我们将深入一节专门介绍InsightApplication的安装过程。很多人可能有这样的误解:只有在完成InsightApplication的安装之后才能实现对VTK与ITK的有效结合;然而实际上一旦完成上述步骤即可开展混合编程工作。因此介绍这一部分内容的目的在于帮助大家通过使用生成的例子来更加便捷地进行学习和实践操作。

(1)创建安装目录

将该软件包InsightApplications-3.20.0.tar.gz复制至ITK主目录并命名为InApp,并在此基础上创建一个名为InApp_bin的新目录(如图1-9所示)。

图1-9 InsightApplication安装目录

(2)CMake的配置

随后,在Score code和build the binaries选项中分别输入E:\Program Files\ITK\InApp及E:\Program Files\ITK\InApp_bin,并单击Configure按钮完成配置设置。请注意,在cmake-install-prefix这个选项中需要将路径设为ITK主文件夹即E:\ProgramFiles\ITK;executable-output-path路径应设置为位于该目录下的itk_bin文件夹中的位置即E:\ProgramFiles\ITK,itk_bin;itk-dir则应指定到该目录下的itk_bin文件夹位置即E:\Program Files ITK itk_bin;LIBRARY-OUTPUT-PATH仍需设定在上述同样的位置即E:\Program Files ITK,itk_bin;将USE_VTK参数设为True后继续完成配置操作时系统会提示VTK_DIR位于红色显示的状态此时应将VTK库的安装路径指定为其对应的红颜色标注所指示的位置即此处应更改为输入到其对应的位置如图1-10所示即可顺利完成配置过程

(3)生成解决方案

启动位于E:\Program Files\ITK\InApp_bin目录中的InsightApplications.sln解决方案文件以生成相应的解决办法。无错误发生后,请访问位于该方案的位置上的INSTALL.vcproj项目文件,在其解压空间内找到安装位置并右键单击以选择仅生成安装包的操作步骤即可完成设置。

(4)InsightApplication的配置

· 库文件:在后面添加F:\Program Files\ITK\include\ImageCalculator路径

· 包含文件:在后面添加E:\Program Files\ITK\lib

系统环境变量配置:计算机->属性->详细设置->环境变量->添加E:\Program Files\ITK\ App_bin;

将位于E:\Program Files\ITK\lib夹层中的全部DLL文件复制到C:\WINDOWS\system32路径中

实验环境安装结束

1.3测试安装结果

1.3.1 VTK安装测试用例

复制代码
 #include "vtkConeSource.h"

    
 #include "vtkPolyDataMapper.h"
    
 #include "vtkRenderWindow.h"
    
 #include "vtkActor.h"
    
 #include "vtkRenderer.h"
    
 int main()
    
 {
    
   // 创建一个圆锥,并设置其参数:高度、底面半径和分辨率。
    
   vtkConeSource *cone = vtkConeSource::New();
    
   cone->SetHeight( 3.0 );
    
   cone->SetRadius( 1.0 );
    
   cone->SetResolution( 10 );// 决定其棱角的多少
    
   // 创建一个多边形映射器,用于把多边形数据映射为可被计算机渲染的图元。
    
   vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
    
   coneMapper->SetInputConnection( cone->GetOutputPort() );
    
   // 创建一个演员,并关联一个映射器,从而确定了演员的形状。
    
   vtkActor *coneActor = vtkActor::New();
    
   coneActor->SetMapper( coneMapper );
    
  
    
   // 创建一个渲染器,添加要被渲染的演员,设置背景颜色。
    
   vtkRenderer *ren1= vtkRenderer::New();
    
   ren1->AddActor( coneActor );
    
   ren1->SetBackground( 0.1, 0.2, 0.4 );
    
   // 创建渲染窗口,供渲染器渲染用。
    
   vtkRenderWindow *renWin = vtkRenderWindow::New();
    
   renWin->AddRenderer( ren1 );
    
   renWin->SetSize( 300, 300 );
    
   // 渲染360次,这里主要是为了延时。
    
   int i;
    
   for (i = 0; i < 360; ++i)  renWin->Render();
    
   // 清除对象。
    
   cone->Delete();
    
   coneMapper->Delete();
    
   coneActor->Delete();
    
   ren1->Delete();
    
   renWin->Delete();
    
   return 0;
    
 }

我们发现,在生成解决方案的过程中,并非像我们预想中那样顺利。在解决过程中出现了七个错误信息,每个信息都指出无法解析的外部符号__declspec(dllimport)public: void __thiscall vtkRenderer::AddActor(class vtkProp *)等。类似的问题会频繁出现...原因在于编译器无法将VTK自带的.lib文件与我们在Visual Studio 2008开发的应用程序建立关联。

为了解决问题,请双击项目文件并进入属性设置界面。在该位置找到连接器设置选项卡下的输入部分,并添加必要依赖项列表框中依次插入vtkCommon.libvtkFiltering.lib、vtkGraphics.lib、vtkRendering.lib这三个库文件名以满足需求。系统会根据当前配置自动搜索这些文件路径并完成链接过程。单击重新生成解决方案按钮后即可启动程序运行流程(如图1-11所示)。

图1-11 VTK安装测试用例

注释:后续的实例中会经常遇到需要在程序中添加调用某个.lib文件的问题。无需赘述,在此提供具体的步骤说明。我们可以通过查看错误提示中的信息,在vtk的帮助文档中找到对应对象所属的类库,并根据这些信息正确地添加所需的.lib文件,并确保每次添加时将不同lib文件之间留有空格分隔开。当使用频率较高时,则无需每次都需要重新查找这些操作方法了。

1.3.2 ITK安装测试用例

复制代码
 #include "itkImage.h"

    
 #include <iostream>
    
 int main()
    
 {
    
 //定义一个图像类型
    
   typedef itk::Image< unsigned short, 3 > ImageType;
    
   ImageType::Pointer image = ImageType::New();
    
  
    
 //输出:ITK Hello World!
    
   std::cout << "ITK Hello World !" << std::endl;
    
   return 0;
    
 }

与VTK类似的用例也出现了问题。同样地,请按照上述方法进行操作。如果用户手中没有安装完整的VTK或ITK帮助文档的话,则可以选择一次性将所有可能需要用到的VTK或ITK运行时所需的.lib文件添加进来。我们可以一次性将所有可能需要用到的VTK或ITK运行时所需的.lib文件添加进来。其中,在Windows系统下,默认路径通常位于E:\Program Files(xp)\WTL 6.0\sdk(xp);而在Linux系统下,默认路径则位于/usr/lib/vtk/...;macOS系统则默认位于/VtkBuilder/...等位置。然后将这些.lib文件名复制到项目属性中的连接器输入下的附加依赖项部分就可以完成配置工作了。具体效果如图1-12所示:

图1-12 ITK安装测试用例

**
**

1.3.3 VTK与ITK混合编程测试用例

复制代码
 #include "itkImage.h"

    
 #include "itkImageFileReader.h"
    
 #include "itkImageToVTKImageFilter.h"
    
 #include "vtkImageViewer.h"
    
 #include "vtkRenderWindowInteractor.h"
    
 #include "vtkImageActor.h"
    
 #include "vtkRenderer.h"
    
 #include "vtkRenderWindow.h"
    
 #include <iostream>
    
 using namespace std;
    
 int main( int argc, char **argv) {
    
  
    
 typedef itk::Image<unsigned short,2> ImageType;
    
 typedef itk::ImageFileReader<ImageType> ReaderType;// 文件读取器
    
 typedef itk::ImageToVTKImageFilter<ImageType> ConnectorType;// VTK与ITK链接器
    
  
    
 ReaderType::Pointer reader= ReaderType::New();
    
 ConnectorType::Pointer connector= ConnectorType::New();
    
 reader->SetFileName("E:\ Program Files\ ITK\ InsightToolkit\ Wrapping\ WrapITK\ images\ ThresholdSegmentationLevelSetWhiteMatterTest.png");
    
 connector->SetInput(reader->GetOutput());
    
  
    
 vtkImageActor *actor = vtkImageActor::New();
    
 actor->SetInput(connector->GetOutput());
    
 vtkRenderer * ren = vtkRenderer::New();
    
 ren->AddActor(actor);
    
 vtkRenderWindow *renWin = vtkRenderWindow::New();
    
 renWin->AddRenderer(ren);
    
  
    
 vtkImageViewer* viewer= vtkImageViewer::New();
    
 // 绘制窗口交互器
    
 vtkRenderWindowInteractor* renderWindowInteractor=vtkRenderWindowInteractor::New();
    
 viewer->SetInput( connector->GetOutput() );
    
 viewer->SetupInteractor( renderWindowInteractor);
    
 viewer->SetColorWindow( 255);
    
 viewer->SetColorLevel( 128);
    
 viewer->Render();
    
 renderWindowInteractor->Initialize();
    
 renderWindowInteractor->Start();
    
  
    
 return 0;
    
 }

在程序中需配置路径参数,请按照以下步骤操作:首先打开项目属性配置对话框(Project Properties),然后依次选择"Configuration Properties > Compiler Configuration > Preprocessor";在该设置窗口中点击"Parameters"按钮并切换到"Include Paths"标签页;将该图片路径(E:\ProgramFiles\VTK\vtkdata\Data\fullhead15.png)添加到指定位置;并在附加依赖项部分添加相关的.lib文件即可。重复上述操作后再次编译程序;如果仍然出现找不到itkImageToVTKImageFilter.h头文件的问题(由于ITK算法库包含多个头文件),可以通过以下方式解决:同样地,在编译选项卡中进行设置(见图1-13)。

图1-13 添加包含文件

再次运行,如图1-14所示

图1-14 ITK、VTK混合编程测试

注:之前出现过的错误,在之后会经常遇到这种情况。这提醒我们应在此处采取措施以解决问题。

**
**

**
**

1.3.4 InsightApplication安装测试用例一

复制代码
 #include <iostream>

    
 #include "itkMesh.h"
    
 #include "itkLineCell.h"
    
 #include "itkTriangleCell.h"
    
 #include "vtkPolyDataReader.h"
    
 #include "vtkPolyData.h"
    
 #include "vtkPoints.h"
    
 #include "vtkCellArray.h"
    
  
    
 int main( int argc, char * argv [] )
    
 {
    
   vtkPolyDataReader * reader = vtkPolyDataReader::New();
    
   reader->SetFileName("E:/Program Files/VTK/vtkdata/Data/fran_cut.vtk");
    
   reader->Update();// 触发立即执行读取操作
    
  
    
   vtkPolyData * polyData = reader->GetOutput();
    
  
    
   const unsigned int PointDimension   = 3;
    
   const unsigned int MaxCellDimension = 2;
    
   typedef itk::DefaultStaticMeshTraits< 
    
                   vtkFloatingPointType, 
    
                   PointDimension,
    
                   MaxCellDimension, 
    
                   vtkFloatingPointType, 
    
                   vtkFloatingPointType  >       MeshTraits;
    
  
    
   typedef itk::Mesh<
    
                   vtkFloatingPointType, 
    
                   PointDimension, 
    
                   MeshTraits              >     MeshType;
    
  
    
   MeshType::Pointer  mesh = MeshType::New();
    
  
    
   const unsigned int numberOfPoints = polyData->GetNumberOfPoints();
    
   
    
   vtkPoints * vtkpoints = polyData->GetPoints();
    
  
    
   mesh->GetPoints()->Reserve( numberOfPoints );
    
   
    
   for(unsigned int p =0; p < numberOfPoints; p++)
    
     {
    
     vtkFloatingPointType * apoint = vtkpoints->GetPoint( p );
    
 mesh->SetPoint( p, MeshType::PointType( apoint ));
    
 }
    
  
    
   vtkCellArray * triangleStrips = polyData->GetStrips();
    
   vtkIdType  * cellPoints;
    
   vtkIdType    numberOfCellPoints;
    
   unsigned int numberOfTriangles = 0;
    
   triangleStrips->InitTraversal();
    
  
    
   while( triangleStrips->GetNextCell( numberOfCellPoints, cellPoints ) )
    
     {
    
     numberOfTriangles += numberOfCellPoints-2;
    
 }
    
  
    
   vtkCellArray * polygons = polyData->GetPolys();
    
   polygons->InitTraversal();
    
  
    
   while( polygons->GetNextCell( numberOfCellPoints, cellPoints ) )
    
     {
    
     if( numberOfCellPoints == 3 )
    
       {
    
       numberOfTriangles ++;
    
       }
    
 }
    
  
    
   mesh->GetCells()->Reserve( numberOfTriangles );
    
   typedef MeshType::CellType   CellType;
    
   typedef itk::TriangleCell< CellType > TriangleCellType;
    
   int cellId = 0;
    
  
    
   triangleStrips->InitTraversal();
    
  
    
   while( triangleStrips->GetNextCell( numberOfCellPoints, cellPoints ) )
    
     {
    
     unsigned int numberOfTrianglesInStrip = numberOfCellPoints - 2;
    
     unsigned long pointIds[3];
    
     pointIds[0] = cellPoints[0];
    
     pointIds[1] = cellPoints[1];
    
 pointIds[2] = cellPoints[2];
    
  
    
     for( unsigned int t=0; t < numberOfTrianglesInStrip; t++ )
    
       {
    
       MeshType::CellAutoPointer c;
    
       TriangleCellType * tcell = new TriangleCellType;
    
       tcell->SetPointIds( pointIds );
    
       c.TakeOwnership( tcell );
    
       mesh->SetCell( cellId, c );
    
       cellId++;
    
       pointIds[0] = pointIds[1];
    
       pointIds[1] = pointIds[2];
    
       pointIds[2] = cellPoints[t+3];
    
       }
    
  
    
 }
    
  
    
   polygons->InitTraversal();
    
   while( polygons->GetNextCell( numberOfCellPoints, cellPoints ) )
    
     {
    
     if( numberOfCellPoints !=3 )      {
    
       continue;
    
       }
    
  
    
     MeshType::CellAutoPointer c;
    
     TriangleCellType * t = new TriangleCellType;
    
     t->SetPointIds( (unsigned long*)cellPoints );
    
     c.TakeOwnership( t );
    
     mesh->SetCell( cellId, c );
    
     cellId++;
    
 }
    
  
    
   std::cout << "Mesh  " << std::endl;
    
   std::cout << "Number of Points =   " << mesh->GetNumberOfPoints() << std::endl;
    
   std::cout << "Number of Cells  =   " << mesh->GetNumberOfCells()  << std::endl;
    
 getchar();
    
   reader->Delete();
    
   return 0;
    
 }

作为InsightApplication内部提供的案例研究

图1-15 InsightApplication安装测试用例一

**
**

1.3.5 InsightApplication安装测试用例二

复制代码
 #include "itkCommand.h"

    
 #include "itkImage.h"
    
 #include "itkVTKImageExport.h"
    
 #include "itkVTKImageImport.h"
    
 #include "itkConfidenceConnectedImageFilter.h"
    
 #include "itkCastImageFilter.h"
    
 #include "itkRGBPixel.h"
    
 #include "itkImageFileReader.h"
    
 #include "itkImageFileWriter.h"
    
 #include "vtkImageImport.h"
    
 #include "vtkImageExport.h"
    
 #include "vtkImageActor.h"
    
 #include "vtkInteractorStyleImage.h"
    
 #include "vtkRenderer.h"
    
 #include "vtkRenderWindow.h"
    
 #include "vtkRenderWindowInteractor.h"
    
 #include "vtkActor.h"
    
 #include "vtkPolyData.h"
    
 #include "vtkPolyDataMapper.h"
    
 #include "vtkContourFilter.h"
    
 #include "vtkImageData.h"
    
 #include "vtkDataSet.h"
    
 #include "vtkProperty.h"
    
  
    
 template <typename ITK_Exporter, typename VTK_Importer>
    
 void ConnectPipelines(ITK_Exporter exporter, VTK_Importer* importer)
    
 {
    
   importer->SetUpdateInformationCallback(exporter->GetUpdateInformationCallback());
    
   importer->SetPipelineModifiedCallback(exporter->GetPipelineModifiedCallback());
    
   importer->SetWholeExtentCallback(exporter->GetWholeExtentCallback());
    
   importer->SetSpacingCallback(exporter->GetSpacingCallback());
    
   importer->SetOriginCallback(exporter->GetOriginCallback());
    
   importer->SetScalarTypeCallback(exporter->GetScalarTypeCallback());
    
   importer->SetNumberOfComponentsCallback(exporter->GetNumberOfComponentsCallback());
    
   importer->SetPropagateUpdateExtentCallback(exporter->GetPropagateUpdateExtentCallback());
    
   importer->SetUpdateDataCallback(exporter->GetUpdateDataCallback());
    
   importer->SetDataExtentCallback(exporter->GetDataExtentCallback());
    
   importer->SetBufferPointerCallback(exporter->GetBufferPointerCallback());
    
   importer->SetCallbackUserData(exporter->GetCallbackUserData());
    
 }
    
  
    
 template <typename VTK_Exporter, typename ITK_Importer>
    
 void ConnectPipelines(VTK_Exporter* exporter, ITK_Importer importer)
    
 {
    
   importer->SetUpdateInformationCallback(exporter->GetUpdateInformationCallback());
    
   importer->SetPipelineModifiedCallback(exporter->GetPipelineModifiedCallback());
    
   importer->SetWholeExtentCallback(exporter->GetWholeExtentCallback());
    
   importer->SetSpacingCallback(exporter->GetSpacingCallback());
    
   importer->SetOriginCallback(exporter->GetOriginCallback());
    
   importer->SetScalarTypeCallback(exporter->GetScalarTypeCallback());
    
   importer->SetNumberOfComponentsCallback(exporter->GetNumberOfComponentsCallback());
    
   importer->SetPropagateUpdateExtentCallback(exporter->GetPropagateUpdateExtentCallback());
    
   importer->SetUpdateDataCallback(exporter->GetUpdateDataCallback());
    
   importer->SetDataExtentCallback(exporter->GetDataExtentCallback());
    
   importer->SetBufferPointerCallback(exporter->GetBufferPointerCallback());
    
   importer->SetCallbackUserData(exporter->GetCallbackUserData());
    
 }
    
  
    
 int main()
    
 {  
    
     typedef unsigned char PixelType;
    
     const unsigned int Dimension = 2;
    
     typedef itk::Image< PixelType, Dimension > ImageType;
    
     
    
     typedef itk::ImageFileReader< ImageType > ReaderType;
    
  
    
     ReaderType::Pointer reader  = ReaderType::New();
    
     reader->SetFileName( "E:/Program Files/VTK/vtkdata/Data/fullhead15.png" );
    
     reader->Update();
    
  
    
     typedef itk::ConfidenceConnectedImageFilter<ImageType,ImageType> SegmentationFilterType;
    
  
    
     SegmentationFilterType::Pointer filter = SegmentationFilterType::New();
    
  
    
     filter->SetInput( reader->GetOutput() );
    
     filter->SetNumberOfIterations(2);
    
     filter->SetReplaceValue(255);
    
     filter->SetMultiplier(2.5);
    
  
    
     ImageType::IndexType index;
    
     index[0] = 100;
    
     index[1] = 100;
    
 filter->SetSeed( index );
    
  
    
     typedef itk::VTKImageExport< ImageType > ExportFilterType;
    
     ExportFilterType::Pointer itkExporter1 = ExportFilterType::New();
    
     ExportFilterType::Pointer itkExporter2 = ExportFilterType::New();
    
  
    
     itkExporter1->SetInput( reader->GetOutput() );
    
     itkExporter2->SetInput( filter->GetOutput() );
    
  
    
     vtkImageImport* vtkImporter1 = vtkImageImport::New();  
    
     ConnectPipelines(itkExporter1, vtkImporter1);
    
     
    
     vtkImageImport* vtkImporter2 = vtkImageImport::New();  
    
     ConnectPipelines(itkExporter2, vtkImporter2);
    
     
    
     vtkImageActor* actor = vtkImageActor::New();
    
     actor->SetInput(vtkImporter1->GetOutput());
    
     
    
     vtkInteractorStyleImage * interactorStyle = vtkInteractorStyleImage::New();
    
  
    
     vtkRenderer* renderer = vtkRenderer::New();
    
     vtkRenderWindow* renWin = vtkRenderWindow::New();
    
     vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
    
     
    
     renWin->SetSize(500, 500);
    
     renWin->AddRenderer(renderer);
    
     iren->SetRenderWindow(renWin);
    
     iren->SetInteractorStyle( interactorStyle );
    
     
    
     renderer->AddActor(actor);
    
     renderer->SetBackground(0.4392, 0.5020, 0.5647);
    
  
    
     vtkContourFilter * contour = vtkContourFilter::New();
    
     contour->SetInput( vtkImporter2->GetOutput() );
    
 contour->SetValue(0, 128);
    
  
    
     vtkPolyDataMapper * polyMapper = vtkPolyDataMapper::New();
    
     vtkActor          * polyActor  = vtkActor::New();
    
  
    
     polyActor->SetMapper( polyMapper );
    
     polyMapper->SetInput( contour->GetOutput() );
    
     polyMapper->ScalarVisibilityOff();
    
     
    
     vtkProperty * property = vtkProperty::New();
    
     property->SetRepresentationToSurface();
    
     property->SetAmbient(0.1);
    
     property->SetDiffuse(0.1);
    
     property->SetSpecular(0.5);
    
     property->SetColor(1.0,0.0,0.0);
    
     property->SetLineWidth(2.0);
    
  
    
     polyActor->SetProperty( property );
    
     renderer->AddActor( polyActor );
    
     renWin->Render();
    
     iren->Start();
    
  
    
     actor->Delete();
    
     interactorStyle->Delete(); 
    
     polyActor->Delete();
    
     vtkImporter1->Delete();
    
     vtkImporter2->Delete();
    
     contour->Delete();
    
     property->Delete();
    
     polyMapper->Delete();
    
     renWin->Delete();
    
     renderer->Delete();
    
 iren->Delete();
    
  
    
   return 0;
    
 }

这个示例展示了InsightApplication安装过程中自带的一个典型用例。其主要功能体现在整合ITK与VTK的数据处理流程:从itkImageFileReader读取数据开始(即调用该组件进行数据输入),随后通过itkVtkImageExport进行数据转换(采用此模块完成数据格式转换),最终通过vtkImageImport实现数据呈现(利用此接口完成可视化显示)。

Actor,在这种情况下可以通过VTK数据流实现其信息的所有方面。其优势在于当ITK的数据流失效时系统将自动重新执行相关功能。该程序与上文中的1.3.3版本类似,并实现了对ITK和VTK平台的无缝连接。运行结果如图1-16所示:

图1-16 InsightApplication安装测试用例二

注:本书后续的所有程序示例中,在遇到类似情况时,请按照指定的方法逐步排查故障。在使用ITK和VTK库时省略了相应的lib添加部分,请读者能够仔细阅读并理解整个调试流程。

(资料整理于网络)

复制代码
    <pre name="code" class="plain" data-index="14"><pre data-index="15"></pre>
    <pre data-index="16"></pre>
    <pre data-index="17"></pre>
    <pre data-index="18"></pre>
    <pre data-index="19"></pre>
    <pre data-index="20"></pre>
    <pre data-index="21"></pre>
    <pre data-index="22"></pre>
    <pre data-index="23"></pre>
    <pre data-index="24"></pre>
    <pre data-index="25"></pre>
    <pre data-index="26"></pre>
    <pre data-index="27"></pre>
    <pre data-index="28"></pre>
    <pre data-index="29"></pre>
    <pre data-index="30"></pre>
    <pre data-index="31"></pre>
    <pre data-index="32"></pre>
    <pre data-index="33"></pre>
    <pre data-index="34"></pre>
    <pre data-index="35"></pre>
    <pre data-index="36"></pre>
    <pre data-index="37"></pre>
    <pre data-index="38"></pre>
    <pre data-index="39"></pre>
    <pre data-index="40"></pre>
    <pre data-index="41"></pre>
    <pre data-index="42"></pre>
    <pre data-index="43"></pre>
    <pre data-index="44"></pre>
    </pre>
复制代码

全部评论 (0)

还没有任何评论哟~