ITK的空间对象类层次结构为查询、操作和互连物理空间中的对象提供了一致的API。
通过对对象的表示进行抽象,以支持用图像以外的数据结构表示对象,支持广泛的医学图像分析研究;

下面介绍一些关键的例子:

  • Model-to-image registration.
    对象的数学实例可以注册到映像,以在映像中定位该对象的实例。使用空间对象,互信息,交叉相关,和图像边界度量可以应用而不需要修改来执行空间对象到图像的配准。
  • Model-to-model registration
    迭代最近点、地标和表面距离最小化方法可以与任何ITK变换一起使用,用于刚性和非刚性配准图像、基于FEM和傅立叶描述的对象作为空间对象的表示
  • Atlas formation
    图像或空间对象的集合可以被整合来表示期望的对象特征及其共同的变化模式。标签可以与图集的对象相关联。
  • Storing segmentation results from one or multiple scans
    分割的结果最好存储在物理/世界坐标中,这样它们就可以组合起来,并与其他分辨率下拍摄的其他图像的分割进行比较。分割结果从手绘轮廓,像素标签,或模型到图像的配准一致处理。
  • 捕获对象之间的功能和逻辑关系。
    空间对象可以有父对象和子对象。可以对对象进行查询(例如确定某个点是否在对象内部),以集成来自子对象的响应。应用于父级的转换也可以传播到子级。例如,当肝脏模型移动时,它的血管也跟着移动。
  • 从图像或者到图像的转换
    基本功能提供渲染任何空间对象(或空间对象的集合)成一幅图像。
  • IO
    空间对象对磁盘的读写独立于空间对象类的层次结构。提供了元对象IO(通过itk::MetaImageIO)方法,其他方法也很容易定义。
  • Tubes, blobs, images, surfaces.
    是提供的许多空间对象数据容器和类型中的几个。可以添加新类型,通常只需要在派生类中定义一个或两个成员函数。

在本文的剩余部分,我们将用几个例子来演示ITK中的许多空间对象,以及如何使用ITK::SceneSpatialObject将它们组织成层次结构。进一步的例子说明如何使用空间对象转换来控制和计算对象在空间中的位置。

结构:

空间对象可以组合成树状的层次结构。

  • 根据设计,一个SpatialObject只能有一个父对象。
  • 此外,每个转换都存储在每个对象中,因此不能将层次结构描述为有向无环图(DAG),而是有效地描述为树。
  • 用户负责维护树结构,无须检查树有没有循环

这个例子描述了itk::SpatialObject如何形成层次结构。第一个示例还展示了如何创建和操作空间对象:

#include "itkSpatialObject.h"
//首先,我们创建两个空间对象,并分别为它们命名First Object和Second Object。
typedef itk::SpatialObject<3> SpatialObjectType;

SpatialObjectType::Pointer object1 = SpatialObjectType ::New();
object1->GetProperty()->SetName("First Object");

SpatialObjectType::Pointer object2 = SpatialObjectType ::New(); 
object2->GetProperty()->SetName("Second Object");

//然后使用AddSpatialObject()方法将第二个对象添加到第一个对象。结果,object2成为object1的子对象。
object1->AddSpatialObject(object2);

//我们可以使用HasParent()方法查询对象是否有父对象。
    //如果有,GetParent()方法返回一个指向父对象的常量指针。
//在我们的例子中,如果我们询问object2的父对象的名称,我们应该得到:First Object。
if(object2->HasParent())
 {
  std::cout << "Name of the parent of the object2: "; 
  std::cout << object2->GetParent()->GetProperty()->GetName() << std::endl; 
  }

//要访问对象的子对象列表,GetChildren()方法返回一个指向(STL)子对象列表的指针。
SpatialObjectType::ChildrenListType * childrenList = object1->GetChildren(); 
std::cout << "object1 has " << childrenList->size() << " child" << std::endl;

SpatialObjectType::ChildrenListType::const_iterator it = childrenList->begin(); 
while(it != childrenList->end()) 
{ 
std::cout << "Name of the child of the object 1: "; 
std::cout << (*it)->GetProperty()->GetName() << 
std::endl; 
it++; 
}

//不要忘记删除子列表,因为GetChildren()函数创建了一个内部列表。
delete childrenList;
//还可以使用RemoveSpatialObject()方法删除对象
object1->RemoveSpatialObject(object2);
//可以使用GetNumberOfChildren()方法查询一个对象的子对象数量。
std::cout << "Number of children for object1: "; 
std::cout << object1->GetNumberOfChildren() << std::endl;

//clear()方法擦除关于对象和数据的所有信息。此方法通常由派生类重载。
object1->Clear();

第一个示例的输出如下所示:

Name of the parent of the object2: First Object 
object1 has 1 child 
Name of the child of the object 1: Second Object 
Number of children for object1: 0