PCL 封装了迭代器,内部使用的是 std::vector
的迭代器,源码在 cloud_iterator.h
和 impl/cloud_iterator.hpp
两个文件中。
源码中有 CloudIterator
和 ConstCloudIterator
两种迭代器,下面以为例 ConstCloudIterator
。
namespace pcl { template <typename PointT> class ConstCloudIterator { public: ConstCloudIterator (const PointCloud<PointT>& cloud); ConstCloudIterator (const PointCloud<PointT>& cloud, const std::vector<int>& indices); ConstCloudIterator (const PointCloud<PointT>& cloud, const PointIndices& indices); ConstCloudIterator (const PointCloud<PointT>& cloud, const Correspondences& corrs, bool source); ~ConstCloudIterator (); void operator ++ (); void operator ++ (int); const PointT& operator* () const; const PointT* operator-> () const; unsigned getCurrentPointIndex () const; unsigned getCurrentIndex () const; size_t size () const; void reset (); bool isValid () const; operator bool () const { return isValid (); } private: class Iterator { public: virtual ~Iterator () {} virtual void operator ++ () = 0; virtual void operator ++ (int) = 0; virtual const PointT& operator* () const = 0; virtual const PointT* operator-> () const = 0; virtual unsigned getCurrentPointIndex () const = 0; virtual unsigned getCurrentIndex () const = 0; virtual size_t size () const = 0; virtual void reset () = 0; virtual bool isValid () const = 0; }; class DefaultConstIterator; class ConstIteratorIdx; Iterator* iterator_; }; }
上述代码中,ConstCloudIterator
包含 4 个构造函数,以及一些成员函数,在 private 下,定义了一个抽象类 Iterator
和三个成员变量。
成员变量 DefaultConstIterator
和 ConstIteratorIdx
继承了 ConstCloudIterator
内部的抽象类 Iterator
,目的是为了实现 ConstCloudIterator
不同的构造函数,并且 ConstCloudIterator
内部的成员函数都是依靠成员变量 iterator_
调用的 DefaultConstIterator
和 ConstIteratorIdx
内部成员函数的实现。
// 只输入点云信息 ConstCloudIterator (const PointCloud<PointT>& cloud); // 输入点云和索引信息 ConstCloudIterator (const PointCloud<PointT>& cloud, const std::vector<int>& indices); // 输入点云和索引信息 ConstCloudIterator (const PointCloud<PointT>& cloud, const PointIndices& indices); // 输入点云和对应关系信息 ConstCloudIterator (const PointCloud<PointT>& cloud, const Correspondences& corrs, bool source);
ConstCloudIterator
重载了以下操作符,可以看出,这个迭代器仅支持向前操作,为单向迭代器。CloudIterator
和 ConstCloudIterator
的区别为 operator*
和 operator->
的返回值是否为 const
类型。
void operator ++ (); void operator ++ (int); const PointT& operator* () const; const PointT* operator-> () const; operator bool () const { return isValid (); }
// 获取当前点的索引 unsigned getCurrentPointIndex () const; // 获取当前迭代器的索引 unsigned getCurrentIndex () const; // 包含多少个点 size_t size () const; // 将迭代器置位 begin void reset (); // 判断迭代器是否等于 end bool isValid () const;
以上函数的具体含义见示例。
构造一个ConstCloudIterator
,并尝试使用它输出信息。
#include <pcl/cloud_iterator.h> #include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <iostream> #include <vector> int main() { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 输入点云 for (int i = 0; i < 5; ++i) { pcl::PointXYZ point; point.x = i; point.y = i; point.z = i; cloud->push_back(point); } std::vector<int> index{0, 1, 3, 4}; pcl::ConstCloudIterator<pcl::PointXYZ> iter(*cloud, index); std::cout << "一共包含点的个数:" << iter.size() << std::endl; for (; iter.isValid(); ++iter) { std::cout << "第 " << iter.getCurrentIndex() << " 个元素" << std::endl; std::cout << "第 " << iter.getCurrentPointIndex() << " 个元素" << std::endl; std::cout << "x = " << (*iter).x << " " << "y = " << iter->y << " " << "z = " << iter->z << std::endl; std::cout << std::endl; } return 0; }
输出:
一共包含点的个数:4 第 0 个元素 第 0 个元素 x = 0 y = 0 z = 0 第 1 个元素 第 1 个元素 x = 1 y = 1 z = 1 第 2 个元素 第 3 个元素 x = 3 y = 3 z = 3 第 3 个元素 第 4 个元素 x = 4 y = 4 z = 4
ConstCloudIterator
可以如上使用,但 CloudIterator
还不能使用,通过源码看到两者在实现上有略微的不同。