PCL中点的类型
使用PointT类型的原因
最早,PCL的PointT是作为ROS中的一个库被开发出来的。大家一致认为点云(Point Cloud)是一个复杂的n维结构,能表示不同的类型的信息。然而,对于用户来说,为了使代码易于调试,便于优化等,应该知道什么样的信息需要被传递。
下面用对XYZ数据的简单操作来举例。对于支持SSE的处理器来说,最高效的方式就是将XYZ这三维数据以float的形式存储,再紧跟一个float用于填补存储空间:
struct PointXYZ
{
float x;
float y;
float z;
float padding;
};
虽然是举例,但是当在嵌入式平台下编译PCL时,填补存储空间的那个float就相当于浪费内存了。因此,在这种情况下,我们应该用简化的PointXYZ,它没有最后一个float。
此外,如果你的应用需要一种PointXYZRGBNormal类型(包含了XYZ 3D位置信息,RGB彩色信息和表面法线),定义它是很简单的。因为PCL中的所有算法都是模板的,因此除了需要定义你自己的结构,其他都不用改变。
PCL中可以直接使用的PointT类型
为了能涵盖所有可能出现的情况,在PCL中定义了大量的点类型。这里介绍的只是一小部分,如果你想看到完整的点类型列表,可以直接查看point_types.hpp。
- PointXYZ 成员:float X,Y,Z;
这是人们最常用的一个数据类型,因为它只表示了xyz3D信息。为了满足SSE的存储对齐,在三个float后面补上一个额外的float。为了方便表示,使用union来定义,这样你既可以用points[i].data[0],也可以用points[i].x来表示x坐标了。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
- PointXYZI 成员:float x,y,z,intensity;
这是一个简单的只有XYZ信息加上强度信息的类型。理想情况下,这四个部分可以直接构成一个结构体,并且满足对齐要求。但是因为主要的对点的操作会使得最后一个float变为0或1(用于变换),所以我们不能将强度作为结构体的一部分,这样可以防止它被错误修改。举个例子,对于两个点坐标的点积来说,这个操作会让这两个点的最后一个float变成0,否则点积就没有意义了。
因此,为了满足SSE对齐,我们给强度后面再加上三个额外的float以满足要求。虽然这样浪费了存储空间,但是有利于内存对齐。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
struct
{
float intensity;
};
float data_c[4];
};
- PointXYZRGBA 成员:float x,y,z;uint32_t rgba;
与PointXYZI类似,只有一点不同,就是将强度换成了RGBA信息,但是它也是用32bit的int型存储的。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
struct
{
uint32_t rgba;
};
float data_c[4];
};
- PointXYZRGB 成员:float x,y,z,rgb;
与PointXYZRGBA类似,只有一点不同,就是将RGBA换成了RGB并将其型存储为一个float。
rgb数据为什么作为一个float存储呢?这要从PCL还是ROS中的一部分说起,当时rgb数据就是以float的形式传送的。我们希望当遗留代码重写后这类数据可以丢弃(在PCL 2.x中很可能这样做)。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
struct
{
float rgb;
};
float data_c[4];
};
- PointXY:float x,y;
简单的二维x-y点结构
struct
{
float x;
float y;
};
- InterestPoint:float x,y,z,strength;
类似于PointXYZI,除了strength是对关键点强度的测量值。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
struct
{
float strenght;
};
float data_c[4];
};
- Normal:float normal[3],curvature;
这是另一个常用的数据结构,Normal结构体表示了一点处的法线方向,以及此处的曲率(通过这个曲面块各特征值的关系来得到–如果你想知道更多信息,可以参考NormalEstimation 类的API)。
因为操作表面法线向量在PCL中是十分常见的事情,我们用四个float来存储它的信息,来达到SSE对齐和高效运算的目的。用户可以使用points[i]data_n[0],points[i].normal[0]或者是points[i]normal_x来达到访问法线向量第一个坐标的目的。最后,curvature通用不能被写在第四个float上,而是重新用四个float的结构体来保存它的信息。
union
{
float data_n[4];
float normal[3];
struct
{
float normal_x;
float normal_y;
float normal_z;
};
};
union
{
struct
{
float curvature;
};
float data_c[4];
};
- PointNormal:float x,y,z;float normal[3],curvature;
PointNormal结构体包含了XYZ数据,表面法线方向及此处的曲率。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
float data_n[4];
float normal[3];
struct
{
float normal_x;
float normal_y;
float normal_z;
};
};
union
{
struct
{
float curvature;
};
float data_c[4];
};
- PointXYZRGBNormal:float x,y,z,rgb,normal[3],curvature;
PointNormal结构体包含了XYZ数据,RGB颜色信息,表面法线方向及此处的曲率。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
float data_n[4];
float normal[3];
struct
{
float normal_x;
float normal_y;
float normal_z;
};
};
union
{
struct
{
float rgb;
float curvature;
};
float data_c[4];
};
- PointXYZINormal:float x,y,z,intersity,normal[3],curvature;
PointNormal结构体包含了XYZ数据,强度值,表面法线方向及此处的曲率。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
float data_n[4];
float normal[3];
struct
{
float normal_x;
float normal_y;
float normal_z;
};
};
union
{
struct
{
float intensity;
float curvature;
};
float data_c[4];
};
- PointWithRange:float x,y,z,range;
类似于PointXYZI,除了range是==从视点到观测点的现实距离==。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
struct
{
float range;
};
float data_c[4];
};
- PointWithViewpoint:float x,y,x,vp_x,vp_y,vp_z;
类似于PointXYZI,除了包含一个视点信息(vp_x,vp_y,vp_z代表的3D点)。
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
struct
{
float vp_x;
float vp_y;
float vp_z;
};
float data_c[4];
};
- MomentInvariants:float j1,j2,j3;
一个三个float组成的点类型,包含了所在曲面的一些信息。查看MomentInvariantsEstimation以获得更多信息。
struct
{
float j1,j2,j3;
};
- PrincipalRadiiRSD:float r_min,r_max;
一个两个float组成的点类型,代表了这个曲面上的两个RSD半径,查看RSDEstimation 以获得更多信息。
struct
{
float r_min,r_max;
};
- Boundary:uint8_t boundary_point;
这个简单的点类型表明了一个点是否在一个表面的边界,查看BoundaryEstimation 以获得更多信息。
struct
{
uint8_t boundary_point;
};
- PrincipalCurvatures:float principal_curvature[3],pc1,pc2;
这个点类型代表了一个指定点上的主曲率。查看PrincipalCurvaturesEstimation 以获得更多信息。
struct
{
union
{
float principal_curvatrue[3];
struct
{
float principal_curvature_x;
float principal_curvature_y;
float principal_curvature_z;
};
};
float pc1;
float pc2;
};
- PFHSignature125:float pfh[125];
这个点类型代表了一个指定点上的PFH(点特征直方图)。查看PFHEstimation 以获得更多信息。
struct
{
float histogram[125];
};
- FPFHSignature33:float fpfh[33];
这个点类型代表了一个指定点上的FPFH(快速点特征直方图)。查看FPFHEstimation 以获得更多信息。
struct
{
float histogram[33];
};
- VFHSignature308 :float vfh[308];
这个点类型代表了一个指定点上的VFH(视点特征直方图)。查看VFHEstimation 以获得更多信息。
struct
{
float histogram[308];
};
- Narf36:float x,y,z,roll,pitch,yaw;float descriptor[36];
这个点类型代表了一个指定点上的NARF(归一化对齐半径特征)。查看NARFEstimation 以获得更多信息。
struct
{
float x,y,z,rool,pitch,yaw;
float descriptor[36];
};
```- BorderDescription:int x,y;BorderTraits traits;
这个点类型代表了一个指定点上的边界类型。查看BorderEstimation 以获得更多信息。
<div class="se-preview-section-delimiter"></div>
struct
{
int x,y;
BorderTraits traits;
};
- IntensityGradient:float gradient[3];
这个点类型代表了一个指定点上的强度梯度。查看IntensityGradientEstimation 以获得更多信息。
<div class="se-preview-section-delimiter"></div>
struct
{
union
{
float gradient[3];
struct
{
float gradient_x;
float gradient_y;
float gradient_z;
};
};
};
- Histogram:float histogram[N];
一般用于表示n维直方图。
<div class="se-preview-section-delimiter"></div>
template
struct Histogram
{
float histogram[N];
};
- PointWithScale:float x,y,z,scale;
类似PointXYZI,除了scale表示对这个点进行几何操作(最近邻计算的球半径,窗口大小等)的尺寸。
<div class="se-preview-section-delimiter"></div>
struct
{
union
{
float data[4];
struct
float x;
float y;
float z;
};
};
float scale;
};
- PointSurfel:float x,y,z,normal[3],rgba,radius,confidence,curvature;
这是一个复杂的点类型,它包含了XYZ数据,表面法向量,RGB信息,尺寸大小,可信度和表面曲率。
<div class="se-preview-section-delimiter"></div>
union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};
union
{
float data_n[4];
float normal[3];
struct
{
float normal_X;
float normal_y;
float normal_z;
};
};
union
{
struct
{
uint32_t rgb;
float radius;
float confidence;
float curvature;
};
float data_c[4];
};
“`