ITK学习笔记:1.Data presentation-1.3Mesh网格(二):自定义mesh

网格的一般概念集成了许多不同的元素。原则上可以为每个这样的元素使用独立的类型。泛型编程中用于指定概念中涉及的许多不同类型的机制称为traits。它们基本上是与当前类交互的所有类型的列表。

网格通过三个参数模板化。到目前为止,我们只讨论了两个,即像素类型和维度。第三个参数是一个提供网格所需特征集的类。当省略第三个参数时,使用默认的类。这个默认类是itk::DefaultStaticMeshTraits。如果您想定制网格使用的类型,接下来的方法是修改默认特征,并将它们作为网格类实例化的第三个参数提供。有两种方法可以实现:

  1. 第一个是使用现有的DefaultStaticMeshTraits类。该类本身模板化了6个参数。定制这些参数可以提供足够的灵活性来定义一种非常特定的网格。
  2. 第二种方法是从头编写一个traits类,在这种情况下,最简单的方法是将DefaultStaticMeshTraits复制到另一个文件中并编辑它的内容。这里只演示了第一种方法。除非熟悉泛型编程,否则不建议使用这种方法

定制网格的第一步是包含网格的头文件及其静态特性:

#include "itkMesh.h"
#include "itkDefaultStaticMeshTraits.h"

然后通过选择六个模板参数中的每个参数的类型来实例化MeshTraits类。它们是有序的:

  1. PixelType。与点相关联的类型。
  2. PointDimension。嵌入网格的空间的维数。
  3. MaxTopologicalDimension。网格单元的最高维数。
  4. CoordRepType。用于表示空间坐标的类型。
  5. InterpolationWeightType。用于表示插值权重的类型。
  6. CellPixelType。与单元格关联的类型。

下面为每个元素定义类型和值。例如,下面的代码将使用3D空间中的点作为网格的节点。

  • 单元格的最大维数将是2,即表面(表层)。
  • 与点关联的数据类型被定义为一个四维向量。该类型可以表示四类分割方法的成员值。
  • 为单元选择的值是4×3矩阵,例如,成员值可以对空间坐标求导。
  • 最后选用double类型来表示网格点上的空间坐标和用于插值值的权重。
const unsigned int PointDimension = 3; //三维点
const unsigned int MaxTopologicalDimension = 2;//单元格的最大维数将是2,即表面(表层)。
typedef itk::Vector<double,4> PixelType;//与点关联的数据类型被定义为一个四维向量
typedef itk::Matrix<double,4,3> CellDataType;//单元选择的值是4×3矩阵
typedef double CoordinateType; 
typedef double InterpolationWeightType;

//设置特征类参数
typedef itk::DefaultStaticMeshTraits< PixelType, PointDimension, MaxTopologicalDimension, CoordinateType, InterpolationWeightType, CellDataType > MeshTraits;
//设置网格参数
typedef itk::Mesh< PixelType, PointDimension, MeshTraits > MeshType;

使用从网格中获取的特征来实例化itk::LineCell :

typedef MeshType::CellType CellType; 
typedef itk::LineCell< CellType > LineType;
//创建一个网格并在上面插入一些点。注意点的尺寸与网格的尺寸匹配。
//在这里,我们插入一个点序列,它看起来像log()函数的图形。
MeshType::Pointer mesh = MeshType::New();
typedef MeshType::PointType PointType;
PointType point;
const unsigned int numberOfPoints = 10; 

for(unsigned int id=0; 
id<numberOfPoints; id++) 
{
 point[0] = 1.565; // Initialize points here 
 point[1] = 3.647; // with arbitrary values
 point[2] = 4.129;
 mesh->SetPoint( id, point );
  }
//通过使用点标识符,将创建一组行单元格并与现有的点关联。
//在这个简单的例子中,可以从单元格标识符推导出点标识符,因为行单元格的排序方式相同。
//注意,在上面的代码中,分配给点组件的值是任意的。在更实际的示例中,这些值将从另一个源计算。


CellType::CellAutoPointer line; 
const unsigned int numberOfCells = numberOfPoints-1; 
for(unsigned int cellId=0; cellId<numberOfCells; cellId++) 
{ 
///CellAutoPointer通过使用TakeOwnership()方法获取接收的指针的所有权。
line.TakeOwnership( new LineType ); 
//尽管这看起来很冗长,但它是必要的,以便从代码中明确表明自动发送器承担内存释放的责任。
line->SetPointId( 0, cellId ); // first point 
line->SetPointId( 1, cellId+1 ); // second point 
mesh->SetCell( cellId, line ); // insert the cell 
}

//使用SetCellData()方法将与单元格关联的数据插入到网格中。它要求用户提供一个标识符和要插入的值。标识符应该匹配插入的一个单元格。
//在这个简单的示例中,单元格标识符的方形被用作单元格数据。注意在赋值中使用了对PixelType的静态转换。
for(unsigned int cellId=0; cellId<numberOfCells; cellId++) 
{
 CellDataType value;
  mesh->SetCellData( cellId, value );
   }

可以使用GetCellData()方法从网格中读取单元格数据。它要求用户提供要检索数据的单元格的标识符。用户还应该提供一个有效的指针,指向可以复制数据的位置。

for(unsigned int cellId=0; cellId<numberOfCells; cellId++) 
{
 CellDataType value;
 mesh->GetCellData( cellId, &value );
 std::cout << "Cell " << cellId << " = " << value << std::endl;
  }

SetCellData()或GetCellData()都不是访问单元格数据的有效方法。
//通过使用CellDataContainer内建的迭代器,可以实现对单元格数据的有效访问

typedef MeshType::CellDataContainer::ConstIterator CellDataIterator;
CellDataIterator cellDataIterator = mesh->GetCellData()->Begin();
CellDataIterator end = mesh->GetCellData()->End();
while( cellDataIterator != end ) 
{
 CellDataType cellValue = cellDataIterator.Value();
  std::cout << cellValue << std::endl; 
  ++cellDataIterator; 
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值