1.概述
Itk::PointSet
类使用一个内部容器来管理itk::Points
的存储。一般来说,通过使用点容器的直接访问方法来管理点将更加有效。
2.过程
下面的例子阐述了如何与点容器交互和如何使用点迭代器。
这个类型是由点集PointSet
类的特性来定义的。下面这行程序便捷地从点集特性得到PointsContatainer
类型并在全局命名空间对它进行声明。typedef PointSetType::PointsContainer PointsContainer;
PointsContainer
的实际类型是由所使用的点集PointSet
的方式来决定的。动态的点集使用itk::MapContainer
,而静态的点集使用itk::VectorContainer
。向量和映射容器是STL类std::map
和std::vector
的基本封装类。点集默认使用静态方式,因此点容器的默认类型是向量容器。映射和向量容器都是在它们包含的元素的类型基础上进行模板化的,这里是在PointType
上模板化的。容器是引用计数对象,使用New( )
创建后被分配给一个itk::SmartPointer
。下面一行创建了一个与PointSet
类型兼容的点容器PointsContainer::Pointer points = PointsContainer::New();
现在可以使用点集的特性PointType
来定义点。
typedef PointSetType::PointType PointType;
PointType p0;
PointType p1;
p0[0] = -1.0; p0[1] = 0.0; p0[2] = 0.0; // Point 0 = {-1,0,0 }
p1[0] = 1.0; p1[1] = 0.0; p1[2] = 0.0; // Point 1 = { 1,0,0 }
使用方法InsertElement( )
将创建的点插入到PointsContainer
中,这种方法需要给每个点提供一个标识符。
unsigned int pointId = 0;
points->InsertElement( pointId++ , p0 );
points->InsertElement( pointId++ , p1 );
最后,使用SetPoint( )
方法来将PointsContainer
分配给点集PointSet
。这将会覆盖点集PointSet
的原有PointsContainer
。pointSet->SetPoints( points );
顺序访问点的最有效的方法是使用PointsContainer
提供的迭代器。Iterator
类型属于PointsContainer
类的特性。它的行为与STL 迭代器十分相似[这些迭代器实际上是STL迭代器的封装类]。点迭代器不是一个引用计数类,所以它可以直接从特性创建而不必使用智能指针。typedef PointsContainer::Iterator PointsIterator;
随后的迭代器使用就和STL迭代器一样了。使用Begin( )
方法从容器得到的指向第一个点的迭代器,并分配另一个迭代器。PointsIterator pointIterator = points->Begin();
迭代器中的++操作符可以被用来从一个点指向下一个点。迭代器指向的点的实际值可以使用Value( )
方法得到。通过比较当前迭代器和用End( )
方法返回的迭代器,就可以控制循环遍历PointsContainer
中所有点。下面的代码阐述了遍历点的典型循环:
PointsIterator end = points->End();
while( pointIterator != end )
{
PointType p = pointIterator.Value(); // access the point
std::cout << p << std::endl; // print the point
++pointIterator; // advance to next point
}
注意:与STL中一样,使用End( )
方法返回的迭代器不是一个有效的迭代器。这是一个表示越过末端的,在访问了容器的最后一个元素后再前进一步的迭代器值。
使用Size( )
方法可以查询储存在容器中的元素的数目。在点集PointSet
的情况下,下面两行代码等价的,它们都返回点集PointSet
中点的数目。
std::cout << pointSet->GetNumberOfPoints() << std::endl;
std::cout << pointSet->GetPoints()->Size() << std::endl;
3.代码
// Itk::PointSet 类使用一个内部容器来管理itk::Points的存储。一般来说,通过使用点容器的直接访问方法来管理点将更加有效。
#include "itkPointSet.h"
int main(int, char *[])
{
using PointSetType = itk::PointSet<unsigned short, 3>;
// 这个类型是由点集PointSet 类的特性来定义的。下面这行程序便捷地从点集特性得到PointsContatainer 类型并在全局命名空间对它进行声明。
using PointsContainer = PointSetType::PointsContainer;
//PointsContainer的实际类型是由所使用的点集PointSet的方式来决定的。
// 动态的点集使用itk::MapContainer,而静态的点集使用itk::VectorContainer。
// 向量和映射容器是STL类std::map 和std::vector的基本封装类。
// 点集默认使用静态方式,因此点容器的默认类型是向量容器。映射和向量容器都是在它们包含的元素的类型基础上进行模板化的,
// 这里是在PointType上模板化的。容器是引用计数对象,使用New( )创建后被分配给一个itk::SmartPointer。
// 下面一行创建了一个与PointSet类型兼容的点容器PointsContainer::Pointer points = PointsContainer::New();
PointsContainer::Pointer points = PointsContainer::New();
// 现在可以使用点集的特性PointType 来定义点。
using PointType = PointSetType::PointType;
PointType p0;
PointType p1;
p0[0] = -1.0;
p0[1] = 0.0;
p0[2] = 0.0; // Point 0 = {-1,0,0 }
p1[0] = 1.0;
p1[1] = 0.0;
p1[2] = 0.0; // Point 1 = { 1,0,0 }
// 使用方法InsertElement( )将创建的点插入到PointsContainer 中,这种方法需要给每个点提供一个标识符。
unsigned int pointId = 0;
points->InsertElement(pointId++, p0);
points->InsertElement(pointId++, p1);
PointSetType::Pointer pointSet = PointSetType::New();
// 最后,使用SetPoint( )方法来将PointsContainer 分配给点集PointSet。这将会覆盖点集PointSet的原有PointsContainer。
pointSet->SetPoints(points);
// 可以使用GetPoints()方法从PointSet获取pointcontainer对象。
// 该方法返回指向PointSet所拥有的实际容器的指针,然后将该指针赋给SmartPointer。
PointsContainer::Pointer points2 = pointSet->GetPoints();
// 顺序访问点的最有效的方法是使用PointsContainer 提供的迭代器。Iterator类型属于PointsContainer 类的特性。
// 它的行为与STL 迭代器十分相似[这些迭代器实际上是STL迭代器的封装类]。点迭代器不是一个引用计数类,所以它可以直接从特性创建而不必使用智能指针。
using PointsIterator = PointsContainer::Iterator;
// 随后的迭代器使用就和STL迭代器一样了。使用Begin( )方法从容器得到的指向第一个点的迭代器,并分配另一个迭代器。
PointsIterator pointIterator = points->Begin();
// 迭代器中的++操作符可以被用来从一个点指向下一个点。迭代器指向的点的实际值可以使用Value( )方法得到。
// 通过比较当前迭代器和用End( )方法返回的迭代器,就可以控制循环遍历PointsContainer 中所有点。下面的代码阐述了遍历点的典型循环:
PointsIterator end = points->End();
while (pointIterator != end)
{
PointType p = pointIterator.Value(); // access the point
std::cout << p << std::endl; // print the point
++pointIterator; // advance to next point
}
// 注意:与STL中一样,使用End( )方法返回的迭代器不是一个有效的迭代器。这是一个表示越过末端的,在访问了容器的最后一个元素后再前进一步的迭代器值。
// 使用Size( )方法可以查询储存在容器中的元素的数目。在点集PointSet 的情况下,下面两行代码等价的,它们都返回点集PointSet中点的数目。
std::cout << pointSet->GetNumberOfPoints() << std::endl;
std::cout << pointSet->GetPoints()->Size() << std::endl;
return EXIT_SUCCESS;
}