在 PCL 中,PointT
是基本的点的表示形式,包括 PointXYZ
、PointXYZRGB
、Normal
等,而 PointCloud
则是存储点集的容器。
PointCloud
被定义在 point_cloud
文件中。
header:包含点云的信息,详见 PCLHeader 类型介绍。
points:保存点云的容器,类型为 std::vector
。
width:类型为uint32_t
,表示点云宽度(如果组织为图像结构),即一行点云的数量。
height:类型为uint32_t
,表示点云高度(如果组织为图像结构)。
若为有序点云,height 可以大于 1,即多行点云,每行固定点云的宽度;若为无序点云,height 等于 1,即一行点云,此时 width 的数量即为点云的数量。
is_dense:bool
类型,若点云中的数据都是有限的(不包含 inf/NaN 这样的值),则为 true,否则为 false。
sensor_origin_ :类型为Eigen::Vector4f
,指定传感器的采集位姿,用的少,一般不用管。
sensor_orientation_ :类型为Eigen::Quaternionf
,指定传感器的采集位姿(方向),用的少,一般不用管。
mapping_ ():类型为boost::shared_ptr
,这是由 ROS 整合推动的。用户不需要访问映射。
以上成员变量,黑体加粗的比较重要,要了解它们的含义。
PointCloud():
header(), points(), width(0), height(0), is_dense(true),
sensor_origin_(Eigen::Vector4f::Zero ()), sensor_orientation_(Eigen::Quaternionf::Identity ()),
mapping_()
{}
PointCloud (PointCloud<PointT> &pc) :
header (), points (), width (0), height (0), is_dense (true),
sensor_origin_ (Eigen::Vector4f::Zero ()), sensor_orientation_ (Eigen::Quaternionf::Identity ()),
mapping_ ()
{
*this = pc;
}
PointCloud (const PointCloud<PointT> &pc) :
header (), points (), width (0), height (0), is_dense (true),
sensor_origin_ (Eigen::Vector4f::Zero ()), sensor_orientation_ (Eigen::Quaternionf::Identity ()),
mapping_ ()
{
*this = pc;
}
// 根据索引创建对象(无序点云)
PointCloud (const PointCloud<PointT> &pc,
const std::vector<int> &indices) :
header (pc.header), points (indices.size ()), width (indices.size ()), height (1), is_dense (pc.is_dense),
sensor_origin_ (pc.sensor_origin_), sensor_orientation_ (pc.sensor_orientation_),
mapping_ ()
{
// Copy the obvious
assert (indices.size () <= pc.size ());
for (size_t i = 0; i < indices.size (); i++)
points[i] = pc.points[indices[i]];
}
// 指定大小创建对象
PointCloud (uint32_t width_, uint32_t height_, const PointT& value_ = PointT ())
: header ()
, points (width_ * height_, value_)
, width (width_)
, height (height_)
, is_dense (true)
, sensor_origin_ (Eigen::Vector4f::Zero ())
, sensor_orientation_ (Eigen::Quaternionf::Identity ())
, mapping_ ()
{}
points
实现的成员函数points
是 PointCloud
内部存放点集的 vector
容器,对点的操作都是基于对 vector
的操作,而 PointCloud
封装了 vector
的函数,可以直接对 PointCloud
调用操作vector
的函数,与操作 points
一样。
举个例子:
inline PointT&
operator () (size_t column, size_t row)
{
return (points[row * this->width + column]);
}
inline iterator
erase (iterator position)
{
iterator it = points.erase (position);
width = static_cast<uint32_t> (points.size ());
height = 1;
return (it);
}
inline size_t size () const { return (points.size ()); }
inline void reserve (size_t n) { points.reserve (n); }
inline bool empty () const { return points.empty (); }
...
对 PointCloud
的操作与对 points
的操作是一样的:
PointCloud<PointXYZ> pointcloud;
size_t size1 = pointcloud.size();
bool flag1 = pointcloud.empty();
// 等价操作
size_t size2 = pointcloud.points.size();
bool flag2 = pointcloud.points.empty();
以上两种操作是等价的,都可以达到目的。
PointCloud
的这些函数都是基于 points
实现的,如果对 vector
熟悉,那么 PointCloud
的这些函数就很容易了。
// 判断点云是否有序
inline bool
isOrganized () const
{
return (height > 1);
}
// 将对象转化为指针
inline Ptr
makeShared () const { return Ptr (new PointCloud<PointT> (*this)); }
PCL 中重载了 cout
,具体如下,该函数在类外实现,具体原因请参考 输出操作符 ( << ) 重载的类内、类外实现.
template <typename PointT> std::ostream&
operator << (std::ostream& s, const pcl::PointCloud<PointT> &p)
{
s << "points[]: " << p.points.size () << std::endl;
s << "width: " << p.width << std::endl;
s << "height: " << p.height << std::endl;
s << "is_dense: " << p.is_dense << std::endl;
s << "sensor origin (xyz): [" <<
p.sensor_origin_.x () << ", " <<
p.sensor_origin_.y () << ", " <<
p.sensor_origin_.z () << "] / orientation (xyzw): [" <<
p.sensor_orientation_.x () << ", " <<
p.sensor_orientation_.y () << ", " <<
p.sensor_orientation_.z () << ", " <<
p.sensor_orientation_.w () << "]" <<
std::endl;
return (s);
}