##1 include文件和类定义

在 ITK 中类最大限度地定义在两个文件中:一个是.h 后缀的头文件;另一个是执行文件,非模板类时为.cxx 后缀,模板类为.txx 后缀。
除了类的头文件外,下面介绍一些其他重要的头文件。
itkMacro.h:在目录 Code/Common 中定义了标准的系统 macros(例如 Set/Get、常数和其他参数)。
itkNumericTraits.h:在目录 Code/Common 中定义了已知类型的数字化参数,例如它的最大值和最小值。
itkWin32Header.h:在目录 Code/Common 中用来定义控制编译过程的操作系统参数。

##面向对象

与标准的 C++类使用构造和析构函数所不同的是,ITK 中类的实例化是用静态类 New()方式创建的。一般地,New( )方式通过Common/itkMacro.h 中的 macro itkNewMacro( )方式来声明和实现。

内存管理:计数:引用计数通过一个 Register( )/Delete( )成员函数界面来实现。一个 ITK 对象的所有实例都是由引用它们的的对象使用一个 Register( )方式来调用的。Register( )方式增加实例的引用计 数。当 实 例引用消 失时 ,调用一 个 Delete( )方 式来减 少 实例的引 用计 数——这 和UnRegister( )方式是相同的。当引用计数为零时,实例将消失。

智能指针:智能指针的作用与常规指针一样(例如支持操作符->和*),但当引用一个实例时执行 Register( )而当不再引用实例时用UnRegister( )。与 ITK 中大部分实例不同,智能指针可以指向程序块,当智能指针生成的范围关闭时会自动删除。因此,在 ITK 中就应该尽量少用 Register( )和 Delete( )。

MyRegistrationFunction()`
{ <----- Start of scope`
// here an interpolator is created and associated to the
// SmartPointer "interp".
InterpolatorType::Pointer interp = InterpolatorType::New();
} <------ End of scope

在这个例子中,有一个引用计数为 1 的引用计数对象(使用 new( )方式)。赋值给对象指针的 interp 并未改变引用计数。在程序最后,interp 被释放,当前对象 interpolator 的引用计数减少,当减少到零时,对象 interpolator 也被释放。

错误处理

try
{
//...try executing some code here...
}
catch ( itk::ExceptionObject exp )
{
//...if an exception is thrown catch it here
}

数据表达
ITK 中有两种基本的数据表示类型:图像和网格。这个功能是在类 Image 和 Mesh 中实现的,这两个类都是itk::DataObject 的子类。
itk::Image 表示一个 n 维、规则的样品数据。采样方向平行于任一个坐标轴,采样起点、像素间隔和每个方向上的样品数量(如图像维数)是特定的。
ITK 中关于图像的一个重要概念是区域 regions,它是一个矩形的、连续的图像块。区域用来指定图像中处理的部分,例如多线程或保留在内存中的部分。

  1. LargestPossibleRegion——全部图像。
  2. BufferedRegion——保留在内存中的图像部分。
  3. RequestedRegion——对图像操作时滤波器或其他类需要的部分。

网格类表示一个 n 维无结构的格子。网格类的拓扑布局是由一套单元(cells)来表示的,单元(cells)是由一个类型和连通性列表来定义的;这个连通性列表依次涉及到点(points)。网格的几何结构是通过 n 维的点(points)组合相关的单元插补函数来定义的。
网格以三个模板参数的形式来定义:1)和点、单元和单元边界相关联的一个像素类型;2)点的维数(依次限制了单元的最大维);3)一个网格特征模板参数,指定了用来储存点、单元、边界的容器和迭代器的类型。通过谨慎使用网格特征,可以在允许表达复杂性、存储器和速度之间的一个平衡的条件下,创建更适合于编辑或者更适合于只读操作的网格。

数据处理管道
数据处理管道连接了数据对象(如图像和网格)和过程对象。管道支持一个自动更新机制。该机制在当且仅当它的输入或内在状态改变时才会唤起一个滤波器来运行。另外,数据管道还支持 streaming,可以自动将数据分成许多小部分,对这些小部分进行逐一处理,并重新集合处理后的数据产生最终结果。通常使用 SetInput( )GetOutput( )方式连接数据对象和过程对象,方法代码如下:

typedef itk::Image<float,2> FloatImage2DType;
itk::RandomImageSource<FloatImage2DType>::Pointer random;
random = itk::RandomImageSource<FloatImage2DType>::New();
random->SetMin(0.0);
random->SetMax(1.0);
itk::ShrinkImageFilter<FloatImage2DType,FloatImage2DType>::Pointer shrink;
shrink = itk::ShrinkImageFilter<FloatImage2DType,FloatImage2DType>::New();
shrink->SetInput(random->GetOutput());*****
shrink->SetShrinkFactors(2);
itk::ImageFileWriter::Pointer<FloatImage2DType> writer;
writer = itk::ImageFileWriter::Pointer<FloatImage2DType>::New();
writer->SetInput (shrink->GetOutput());*****
writer->SetFileName( ‘‘test.raw’’ );
writer->Update();

在这个例子中,源代码对象itk::RandomImageSourceitk::ShrinkImageFilter相连接,shrink 滤波器和 mapper itk::ImageFileWriter相连。当调用 Update( )方式时,数据处理管道就会按顺序使用这些滤波器,并将最终结果储存到文件中。

空间对象:ITK 空间对象提供了一个界面,用来储存对象的物理位置、几何性质以及对象之间的关系,储存是在独立于用来表示这些对象的形式的情况下进行的。也就是说,由一个空间对象保持的内在表达可能是一个对象内在的列表、对象的表面网格、对象的内在点或表面的一个连续的或参数的表达等等。
空间对象框架提供的功能支持对象分割、配准、表面/立体视图以及其他显示和分析功能。空间对象框架扩张了对计算机视图工具包很普遍的一个“scene graph”概念,因此也支持这些新函数功能。使用空间对象可以:

  1. 指定空间对象的父对象和子对象。在这种方式下,一个 liver 可以包含许多 vessels,而这些 vessels 可以用一个树型结构来组织。
  2. 查询一个物理点是否在一个对象或它的子对象中。
  3. 求出由一个对象或其子对象所指定的一个相关强度函数上某一物理点的值或派生值。
  4. 指定由一个父对象坐标系转换到一子对象坐标系的转换公式。
  5. 计算一个空间对象及其子对象的 bounding box。
  6. 查询对象最初计算的 resolution。例如,你可以查询一个用来生成 itk::BlobSpatialObject的一个特定实例的图像的 resolution (例如 voxel 空间)。

封装
封装处理的结果是产生一系列可供解释语言使用的共享库,依照每种语言不同的句法要求 甚 至 可 以 直 接 转 换 到 C++ 。 例 如 : 在 文 件 夹 Testing/Code/Algorithms 中 , 测 试itkCurvatureFlowTestTcl2.tcl 中有一段代码如下:

set cf [itkCurvatureFlowImageFilterF2F2_New]
$cf SetInput [$reader GetOutput]
$cf SetTimeStep 0.25
$cf SetNumberOfIterations 10C++中有同样的代码如下:
itk::ImageFileReader<ImageType>::Pointer reader =
itk::ImageFileReader<ImageType>::New();
reader->SetFileName("cthead1.png");
itk::CurvatureFlowImageFilter<ImageType,ImageType>::Pointer cf =
itk::CurvatureFlowImageFilter<ImageType,ImageType>::New();
cf->SetInput(reader->GetOutput());
cf->SetTimeStep(0.25);
cf->SetNumberOfIterations(10);

通译语言的优点就是不用像 C++语言那样需要一个很长的编译/链接周期。另外,它们通常都会附带一套生成有用功能的工具包。

10-03 16:49