ITK入门教程(12)点集之得到存储的点

1.概述

Itk::PointSet 类使用一个内部容器来管理itk::Points的存储。一般来说,通过使用点容器的直接访问方法来管理点将更加有效。

2.过程

下面的例子阐述了如何与点容器交互和如何使用点迭代器。

这个类型是由点集PointSet 类的特性来定义的。下面这行程序便捷地从点集特性得到PointsContatainer 类型并在全局命名空间对它进行声明。typedef PointSetType::PointsContainer PointsContainer;

PointsContainer的实际类型是由所使用的点集PointSet 的方式来决定的。动态的点集使用itk::MapContainer,而静态的点集使用itk::VectorContainer。向量和映射容器是STL类std::mapstd::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的原有PointsContainerpointSet->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;
}

4.结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值