PCL 迭代器(CloudIterator)源码解析及使用
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
还不能使用,通过源码看到两者在实现上有略微的不同。