一律选择32Bit,先装VTK,后装ITK(方便ITK和VTK连接,ITK选项卡中Advanced下面的Module_ITKVtkGlue 必须选择,才能和VTK连接)
QT5选择qt-opensource-windows-x86-msvc2012_64_opengl-5.2.1;qt-vs-addin-1.2.2-opensource VS2012选64BIT
注意:要release就都release,要debug就都debug。(QT和VTK连接的lib必须release,建议先release在debug),可以release和debug都编译一遍,把CMAKE_INSTALL_PREFIX所对应的文件夹下的文件保存分别新建release和debug文件夹下保存,如果不想保存,直接在ITK.sln(VTK.sln)文件中直接找到INSTALL对应的,仅重新生成INSTALL即可,不必重新编译ALL_BUILD
(1)CMake安装资源
CMake 是个跨平台的自动化建构软件,用于对于VTK、ITK的编译,可以在http://www.cmake.org/cmake/resources/software.html上下载用于Windows安装的cmake-2.8.3-win32-x86.exe版本。
(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、InsightApplications-3.20.0.zip资源。
注:上述的安装都是基于Windows XP系统,Visual Studio 2008开发平台,其它操作系统上的安装下述步骤可能会出现问题!此外,提醒大家如果要将上述所有软件全部安装在一个盘符下面,那么可能需要30G的空间。因为安装耗时长,所以请大家提前合理分配您的空间。
系统win7 64位,已装vs2012,所有软件安装及打开都用管理员身份。
下面详细介绍QT和VTK结合开发的环境配置步骤
1. 下载软件版本及地址
① qt的安装文件qt-opensource-windows-x86-msvc2012_opengl-5.3.2.exe
http://download.qt-project.org/archive/qt/5.3/5.3.2/
② qt的vs2012插件qt-vs-addin-1.2.3-opensource.exe
http://qt-project.org/downloads
③ cmake-2.8.12.2-win32-x86.rar
http://download.csdn.net/detail/dedje/8276415
④ VTK-6.1.0.zip
http://www.vtk.org/files/release/6.1/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目录)
打开VS2012,选择菜单->qt5->qtoptions->qt versions->add,在path中填入qmake.exe的上级目录,(我的qmake.exe在D:\Qt\Qt5.3.2\5.3\msvc2012_opengl\bin,所以填入的目录是D:\Qt\Qt5.3.2\5.3\msvc2012_opengl)。
至此你就可以在VS2012中创建qt项目了。
下面开始配置VTK。
3. 把④⑤解压到D:\VTK6下,④改名为VTKSource,⑤改名为VTKData
解压③后安装cmake,我的安装路径是在D:\VTK6\CMake2.8
(1) 打开cmake-gui.exe
在sourcecode和build里面分别填上刚才的源文件及要放在编译文件的路径。点击Configure,选择visualstudio 11,(虽然是64位系统,但是有教程建议不要选visual studio11 win64,我没有试过选了会怎么样)。
等待配置完成后,会有错误发生,需要做如下修改:
build_shared_libs勾选
点击addentry,添加qt的安装路径
vtk_group_qt勾选
再次点击configure,完成后再做如下修改
vtk_qt_version改成5,确认QT_QMAKE_EXECUTABLE为你的qmake.exe的地址,再次configure,没有错误后点击Generate,生成项目文件。
Qt5Gui_glu32_LIBRAYRY错误解决
,点击cmake界面坐上角的“AddEntry”按钮,添加CMAKE_PREFIX_PATH选项(TYPE选择PATH)
C:\ProgramFiles\Microsoft SDKs\Windows\v6.0A\Lib\x64和前文QT路径之间加;隔开
(每次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/VTKData-6.2.0/VTK-6.2.0/.ExternalData
cmake_install_prefix: 这个是指定一个目录把.h.lib .dll等精华放在这里,"VTK安装三步曲"里说是为将来装vtk做准备,
build_examples: 就是询问是否编译vtk 中的例子,你在看这个教程,说明肯定是初次用VTK,建议选上。
build_shared_libs: 如果设置为off,就只会生成lib文件,用于开发肯定是够了。如果设置为on,将会多生成 dll文件,如果用静态库编程,即off时,应用程序可以独立运行,尺寸也比较大,如果用动态库编程,即on时,应用程序必须找到动态库才能运行,但尺寸可以做得比较小。建议选On,
vtk_use_parallel: 对于想用vtk 做并行计算的朋友,要把这个选上,对于只想学学vtk的,保持默认 off
都没问题了所有项目会变成灰色。这时就可以按OK了,几秒钟后,cmake自动退出,为VC6准备的make文件已经生成好。
(2) 在你的编译文件路径下(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下,然后打开qtdesigner就可以看到qvtk选项了。
然后把D:\VTK\prefix\bin下添加到系统环境变量的Path
(3)上面的步骤只是将下载下来的VTK源码在windows的平台上生成了相当于setup文件,就是install工程,还需要在编译 install工程才能在cmake时候的变量CMAKE_INSTALL_PREFIX下生成安装文件,(在前面编译的时候INSTALL工程都是skip的,没有编译),在visualstudio 中的solution中找到INSTALL,点击BUILDONLY 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界面坐上角的“AddEntry”按钮,添加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")
在VS2010中打开由CMake生成的工程文件,包含ALL_BUILD、bilateral_filter和ZERO_CHECK三个项目。
程序运行时异常终止了,想进入调试模式查看问题具体出在什么地方。
但编译的时候出现错误提示:
无法启动程序 无法找到文件e:\projects_pcl\pcl_filters\bilateral_filter\build\x64\Debug\ALL_BUILD
1. 在VS2010中移除ALL_BUILD和ZERO_CHECK这两个工程文件,剩下bilateral_filter这一个工程文件就可以了。
移除工程文件的方法:鼠标右击对应的工程文件,单击“移除”。
2. 重新编译进调试模式,可以了。
问题解决。
2.3 创建一个简单的VTK程序
在2.2一节里,我们详细讲解了如何编译、安装VTK,那么如何测试VTK到底有没有正确地安装,或者说怎么使用我们在前面编译出来的VTK函数库呢?
首先我们需要写一个CMakeLists.txt文件。前面的内容我们已经接触了CMake,也用CMake来配置过VTK工程,下面我们先看看CMake的介绍。
对于每个使用VTK的开发人员来说,必须认识的一个工具就是CMake,CMake的产生与发展也与VTK息息相关。以下一段内容摘自维基百科,主要是关于CMake的历史:
“CMake是为了解决美国国家医学图书馆出资的VisibleHuman Project项目下的Insight Segmentation andRegistration Toolkit (ITK)软件的跨平台构建的需求而创造出来的,其设计受到了KenMartin开发的pcmaker的影响。pcmaker当初则是为了支援VisualizationToolkit (VTK)这个开源的三维图形和视觉系统才出现的,现在VTK也采用了CMake。”
从以上关于CMake的介绍可以知道,CMake其实就是一个跨平台的工程构建工具,可以根据不同的平台生成与平台相关的工程配置文件,比如Windows平台采用VisualStudio,则可以生成*.dsw/*.sln等项目文件。利用CMake可以管理大型的项目,VTK就是使用了CMake作为项目管理工具。同时CMake也简化了工程构建过程,只要给工程里的每个目录都写一个CMakeLists.txt,就可以生成出该工程的编译文件。CMake支持in-place构建(也就是生成的二进制文件跟源文件在同一个目录)和out-of-place构建(编译链接生成的二进制文件和源文件分别在不同的目录,前面我们讲VTK编译过程时就是采用这种构建方式)两种工程构建方式。
CMake有自己的语言和语法,用CMake对工程进行管理的过程,就是编写CMakeLists.txt脚本文件的过程,原则上要求工程里的每一个目录都包含一个同名的文件,而且这个文件的名字只能是:CMakeLists.txt。假如写成cmakelists.txt,由于Windows不区别文件名大小写,所以可以通过;但如果在别的平台,如Ubuntu,用CMake构建工程时就会提示找不到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 cylinder =
vtkSmartPointer::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 cylinderMapper =
vtkSmartPointer::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 cylinderActor =
vtkSmartPointer::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 renderer =
vtkSmartPointer::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 renderWindow =
vtkSmartPointer::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 renderWindowInteractor =
vtkSmartPointer::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\Examples\2.3.2_TestVTKInstall目录下有两个文件,分别为CMakeLists.txt和TestVTKInstall.cpp。打开CMake程序,在CMake的“Whereis the source code”一栏输入路径:D:\Toolkits\VTK\Examples\2.3.2_TestVTKInstall,在“Whereto build the binaries”一栏输入路径:D:\Toolkits\VTK\Examples\2.3.2_TestVTKInstall\bin,接着按“Configure”按钮,CMake会弹出图2.8的对话框。
选择“Yes”,然后再选择我们准备采用的编译环境“VisualStudio 2008Win64”,CMake开始配置工程。这个工程非常小,很快就配置完成,接着在CMake界面上会出现一些红色的选项,如果没有勾选“Advance”视图,默认显示出来的选项只有两项,分别是:CMAKE_INSTALL_PREFIX以及VTK_DIR,前一个选项我们已经知道是什么意思,VTK_DIR这个选项就是指向编译的VTK目录,即D:/Toolkits/VTK/VTK-5.10-bin,准确地说,这个路径就是VTKConfig.cmake文件所在的完整路径。对于CMAKE_INSTALL_PREFIX这个选项默认的值都是C:\ProgramFiles\XXX (XXX指的就是你在CMakeLists.txt里的project(XXX)命令里填写的工程名字)。对于VTK_DIR,一般情况下,在你编译完VTK以后,用CMake配置VTK的工程时,会自动找到这个路径,如果CMake找不到,或者找到的不是你想要的VTK版本(假如你的计算机已经编译多个版本的VTK时),可以通过“BrowseBuild…”按钮选择需要的VTK编译路径,或者直接输入该路径。
设置完选项的值以后,再次“Configure”,直到没有红色的选项出现,最后“Generate”。完成以后打开在“Wheretobuild the binaries”一栏指定的路径D:\Toolkits\VTK\Examples\2.3.2_TestVTKInstall\bin,生成的文件如图2.9所示。
图2.9 用CMake构建TestVTKInstall工程所生成的文件
打开我们熟悉的*.sln文件,即TestVTKInstall.sln,按键盘F7键开始编译工程,完成以后按F5运行,如果没有其他意外,会弹出图2.10的对话框。
图2.10 ExecutableFor Debug Session对话框
对于不熟悉VisualStudio 2008的初学者而言,会以为这是一种错误,其实只是项目默认的启动工程没有生成可执行文件而已。右击“SolutionExplorer”里的“TestVTKInstall”工程,然后选择“Set asStartUp project”,再次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()
第1行用到的CMake命令cmake_minimum_required,该命令完整的形式为:cmake_minimum_required(VERSIONmajor[.minor[.patch[.tweak]]][FATAL_ERROR])命令说明:用于指定构建工程时所需的CMake版本要求。参数VERSION,必须的关键字,且为大写,(注:CMake的命令名是不区分大小写的,为了统一描述,本书里所有的CMake命令都以小写书写,但是CMake命令的参数关键字,如VERSION,要求必须大写。)第二个参数为指定CMake的版本号,CMake最新的版本是2.8.10,2012年11月7日发布。第三个参数为可选参数,且为内置的关键字“FATAL_ERROR”。如果构建工程所用的CMake版本没有达到要求,配置过程就会弹出图2.12所示的错误提示信息,终止工程构建过程。
图2.12CMake构建工程时的错误提示信息
第2行,project命令。完整语法格式为:
project(projectname[CXX][C] [Java])
用该命令指定工程名称,可指定工程支持的语言,支持语言的参数为可选。默认支持C\C++。该命令还隐含两个CMake变量:
project命令的第一个参数还隐含了另外一个变量:PROJECT_NAME,我们在第5、6行分别引用了这个变量:${PROJECT_NAME}。注意:CMake使用“${变量}”的形式来获取该变量的值,也就是说,在这个例子里,${PROJECT_NAME}就相当于工程名:“TestVTKInstall”。
第3行find_package命令,完整语法格式为:
find_package(
[version]
[EXACT]
[QUIET]
[[REQUIRED|COMPONENTS][components...]]
[NO_POLICY_SCOPE])
find_package命令用于搜索并加载外部工程,隐含的变量为
(摘自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(
[OPTIONAL]
[RESULT_VARIABLE]
[NO_POLICY_SCOPE])
指定载入一个文件或者模块,如果指定的是模块,那么将在CMAKE_MODULE_PATH中搜索这个模块并载入,在本例中,指定的是VTK模块,则会在CMAKE_MODULE_PATH中搜索VTK模块并载入,变量CMAKE_MODULE_PATH指的是搜索CMake模块的目录,安装安CMake以后,在CMake的安装目录下(本机是安装在C:\Program Files (x86)\CMake 2.8\)可以找到CMake已经定义的模块,路径为:C:\Program Files(x86)\CMake2.8\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)
定义这个工程会生成一个文件名为
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]
指定生成可执行文件时需要链接哪些文件。参数
可能这个时候,你会问:为什么就知道要链接vtkRendering.lib这个文件呢?
TestVTKInstall.cpp文件里,我们使用到了vtkRenderWindow和vtkSmartPointer这个两个类,查找这两个类的头文件所在的路径,分别为:D:\Toolkits\VTK\VTK-5.10\Rendering和D:\Toolkits\VTK\VTK-5.10\Common。于是我们可以暂时做一个猜测:因为VTK里所有的类都是以“vtk”开头,那VTK生成的函数库应该也以“vtk”开头,而我们要用到的两个类vtkRenderWindow和vtkSmartPointer的头文件vtkRenderWindow.h和vtkSmartPointer.h又分别在文件夹Rendering和Common里,刚好在VTK编译的目录里我们能找到vtkRendering.lib和vtkCommon.lib这两个文件,于是是否可以断定我们要用到的两个类vtkRenderWindow和vtkSmartPointer的接口就是分别定义在vtkRendering.lib和vtkCommon.lib里的?最后我们做出艰难的决定:在CMakeLists.txt的target_link_libraries里,要链接的函数库就是vtkRendering和vtkCommon。随着对VTK的深入了解,你会发现这种猜测是对的!如果你好奇心比较强的话,在VTKConfig.cmake这个文件里(用记事本打开),可以找到以下语句:
SET( VTK_LIBRARIES "vtkCommon;vtkFiltering;vtkImaging;vtkGraphics;vtkGenericFiltering;vtkIO;
vtkRendering;vtkVolumeRendering;vtkHybrid;vtkWidgets;vtkInfovis;vtkGeovis;vtkViews;vtkCharts")
上面的内容我们已经讲过,set命令是用来定义某个变量的,而取变量的值我们可以用符号${},那是不是我只要在target_link_libraries的最后,不用一一列出所要链接的函数库,而直接引用变量值:${VTK_LIBRARIES}来代替列出的“vtkRenderingvtkCommon”呢?答案也是可行的。
到此为止,就应该能知道CMake常用的六个命令cmake_minimum_required、project、find_package、include、add_executable和target_link_libraries的“所以然”了,在这个CMakeLists.txt文件的六行代码里,除了第1行关于CMake版本要求的可以省略之外,其他的5行都是必须的。
2.3.4 一个简单的VTK工程
#include"vtkRenderWindow.h"
#include"vtkSmartPointer.h"
int main()
{
vtkSmartPointer renWin =vtkSmartPointer::New();
renWin->Render();
std::cin.get();
return 0;
}
第1、2行,包含头文件,因为要用到VTK里的vtkRenderWindow和vtkSmartPointer两个类,所以包含相应的头文件。VTK对类的命名都是以小写的vtk开头,每个类的关键字的首字母大写。
第5行,用智能指针定义了一个类型为vtkRenderWindow的对象,这是VTK的类实例化对象的基本方法。因为VTK里每个类的构造函数都定义为保护成员,因此你不能够用以下的语句来定义一个VTK对象:
vtkClassExampleinstance;//vtkClassExample这个类当然是不存在的,只是说明问题而已
要不然会提示如下的错误:
errorC2248:vtkClassExample:: vtkClassExample: cannot access protected memberdeclared inclass vtkClassExample
所以,要构造VTK的对象可以用第5行的方法,或者用以下的方法:
vtkRenderWindow*renWin= vtkRenderWindow::New();
至于为什么,后面的内容会让你再“知其所以然”。
第6行,调用vtkRenderWindow里的方法显示并渲染VTK窗口。
第8行,没有其他特别的意义,只不过是让程序暂停下来,等待接受用户的输入,目的是想让你看看VTK窗口到底是长什么样子,你可以把它注释掉,看看它会不会一闪而过。
这个程序非常简单,就一个VTK窗口,其他什么也没有。但它确实是一个VTK的工程,至少使用了两个VTK类,调用了一个VTK的方法。在后面的章节里,你还会经常与这个窗口打交道。
2.4 本章小结
这章一开始我们为安装VTK作了非常充分的准备工作,了解了在编译安装VTK之前需要先安装哪些软件。然后,我们一步一步地演示了如何编译VTK,这个过程还是非常简单的。最后,安装完VTK,我们通过一个非常简单的VTK小程序——显示一个VTK窗口,来测试VTK是否成功安装。通过这个小程序,我们学习了CMakeLists.txt脚本的写法,并掌握了6个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;然后在E:\ProgramFiles\ITK中创建ITK_bin文件夹,同样用于保存编译的二进制文件;其结构如图1-6所示:
图1-6 ITK目录结构
(2)CMake配置
首先打开CMake,对其进行设置,如图1-8所示。ITK设置同VTK设置类似,只将BUILD_SHARED_LIBS置ON(可选);BUILD_EXAMPLES置ON(可选);将BUILD_TEST置ON(可选),丰富的例子便于ITK的学习;同样;最后将CMAKE_INSTSLL_PREFFIX设置为E:\Program Files\ITK即可,其它可采用默认格式即可,如图1-7所示。
图1-7 ITK配置安装
然后Configure,因其设置项比较多,不同用户可以根据其需要而定,上面基本设置已可以满足一般用户的开发和学习。如果没有红色标示,点击Generate。
Advanced下面的 Module_ITKVtkGlue必须选择,才能和VTK连接
(3)生成解决方案
打开E:\ProgramFiles\ITK\ITK_bin里面的ITK.sln文件,雷同VTK的生成解决方案,点击:生成->生成解决方案。如果没有错误,打开ITK_bin里面的INSTALL.vcproj文件,在解决方案里面找到Install文件,选中点击右键->仅用于项目->仅生成INSTALL。
如果编译过程中有错误,应该删除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中的.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
2. 在 HelloITK 目录中,新建文件 HelloWorld.cxx,编写源代码. 新建文件 CMakeLists.txt, 用于 CMake 进行配置.
3. HelloWorld.cxx:
#include "itkImage.h"
#include
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
至此成功.
需要注意的是:
1. CMakelist.txt的编写,主要是TARGET_LINK_LIBRARIES(HelloWorld ITKCommon)
工程中用到ITK 的哪一个子系统,这里就需要添写那一个,D:/I_VTK/ITK/ITK-3.14.0/Examples
示例程序提供了大量ITK的使用,可以参考.
2.可以不使用 CMake进行开发.这样的话,就需要手动添加工程所依赖的 lib,xxx.h .
1)按照通常的方法建立一个 C++Console工程,编写代码.
2)tool->option->Projects and Solutions->VC++ Directories选择Includefiles,然后在下面
添加所有需要的 ITK头文件非常的多,复杂点的程序可能用到所有路径:D:/I_VTK/ITK/ITK-3.14.0/Code
目录下所有子目录,以及子目录的子目录
不使用 CMAKE自动配置,最好在编译 ITK后,编译INSTALL工程,这样include, lib会安装到
单独的目录,结构比较清晰。
3)添加所依赖的lib: Project-->Properties-->Linker-->Input,选择Additional Dependencies,
添加所需 lib文件,包括所依赖的Windows头文件. 可以查看一个使用前面的方法生成的工程,可以看到
依赖的 lib非常的多,非常麻烦,所以最好使用 Cmake进行自动配置.
1.2.3 InsightApplication的安装
为了更好的学习VTK、ITK,我们在这里进一小节将介绍InsightApplication的安装,很多人都认为只有将InsightApplication安装后才能将VTK、ITK结合起来使用,其实上述安装结束之后完全可以进行混合编程。之所以介绍InsightApplication的安装,目的是为了利用InsightApplication安装生成的例子便于大家更好的学习。
(1)创建安装目录
将InsightApplications-3.20.0.tar.gz解压在ITK主文件夹中为InApp,并在ITK主文件夹中新建文件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,然后单击Configuration进行选项配置。注意这里cmake-install-prefix这个选项的路径设为ITK主文件夹即E:\ProgramFiles\ITK;executable-output-path路径设置为E:\ProgramFiles\ITK\itk_bin\bin;itk-dir路径设置为E:\Program Files\ITK\itk_bin;LIBRARY-OUTPUT-PATH依然设置为E:\Program Files\ITK\itk_bin\bin;将USE_VTK设置为True,然后Configuration,发现VTK_DIR为红色,将其路径设置为E:\ProgramFiles\VTK\vtk_bin,然后再Configuration,没有问题单击Generate即可,详细参见图1-10所示:
(3)生成解决方案
打开E:\Program Files\ITK\InApp_bin文件中的InsightApplications.sln解决方案文件进行生成解决方案,没有问题后,再打开INSTALL.vcproj项目文件,在解决方案中找到Install右击选择仅生成Install即可。
(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文件之间要有空格隔开。
1.3.2 ITK安装测试用例
#include "itkImage.h"
#include
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用例类似的问题出现了,同样,我们需要再将.lib文件如上添加进去即可。如果大家手头没有vtk或者itk帮助文档,可以将所有的vtk或者itk运行时可能需要的.lib文件一次添加进去,ITK该文件在E:\ProgramFiles\ITK\lib\InsightToolkit中,VTK该文件在E:\Program Files\VTK2008\lib\vtk-5.6中,将其.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
using namespace std;
int main( int argc, char **argv) {
typedef itk::Image ImageType;
typedef itk::ImageFileReader ReaderType;// 文件读取器
typedef itk::ImageToVTKImageFilter 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;
}
程序中需要载入路径参数,打开项目->属性->配置属性->调试->命令参数,在此添加“E:\ProgramFiles\VTK\vtkdata\Data\fullhead15.png”,如果需要多个参数,请用空格隔开。并在附加依赖项中添加需要的.lib文件即可。再次运行,我们发现仍然有错误:“无法找到itkImageToVTKImageFilter.h文件”,因ITK算法库类比较多,我们无法将所有的类路径一次添加到包含文件中,所以可以在电脑中查找该头文件,发现其在E:\ProgramFiles\ITK\InsightToolkit\Wrapping\WrapITK\ExternalProjects\ItkVtkGlue\src中,为了在编译过程中使编译器能够查找到该头文件,我们可以将其同vtk、itk配置一样添加到工具->选项->项目和解决方案->VC++目录的包含文件中,如图1-13所示:
图1-13 添加包含文件
再次运行,如图1-14所示
图1-14 ITK、VTK混合编程测试
注:上述出现的错误,在后面会经常见到,所以大家应该在此注意其解决方法。
1.3.4 InsightApplication安装测试用例一
#include
#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自带的用例,主要功能是将一幅vtk的PolyData结构图转换为一个itk的Mesh(网格)结构,并统计最后该网格的单元数及点数。程序运行结果如图1-15所示:
图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
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
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 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-->vtkImage
Actor,这样通过ITK数据流的信息都可以由VTK数据流实现。优点是如果发现ITK的数据流过期,VTK数据流将重新执行。该程序同1.3.3类似,都实现了VTK同ITK的连接。运行结果如图1-16所示:
图1-16 InsightApplication安装测试用例二
注:本书后面所有程序用例,如出现上述问题,均应按照上述解决方案逐步调试,程序中用到ITK与VTK的.lib添加将不再累述,请认真阅读调试程序的过程。
(资料整理于网络)