1. 示例代码
以下代码参照PCL官方文档:https://pcl.readthedocs.io/projects/tutorials/en/master/concatenate_fields.html
- concatenate_fields.cpp
#include <iostream>
#include <pcl/common/io.h> // for concatenateFields
#include <pcl/point_types.h>
//这里的约束条件是,两个数据集中的点数必须相等。
int main()
{
pcl::PointCloud<pcl::PointXYZ> cloud_a;
pcl::PointCloud<pcl::Normal> cloud_b;
pcl::PointCloud<pcl::PointNormal> cloud_c;
// Fill in the cloud data
cloud_a.width = cloud_b.width = 5;
cloud_a.height = cloud_b.height = 1;
cloud_a.resize(cloud_a.width * cloud_a.height);
cloud_b.resize(cloud_b.width * cloud_b.height);
for (std::size_t i = 0; i < cloud_a.size(); ++i)
{
cloud_a[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_a[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_a[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
for (std::size_t i = 0; i < cloud_b.size(); ++i)
{
cloud_b[i].normal[0] = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_b[i].normal[1] = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_b[i].normal[2] = 1024 * rand() / (RAND_MAX + 1.0f);
}
std::cerr << "Cloud A: " << std::endl;
for (std::size_t i = 0; i < cloud_a.size(); ++i)
std::cerr << " " << cloud_a[i].x << " " << cloud_a[i].y << " " << cloud_a[i].z << std::endl;
std::cerr << "Cloud B: " << std::endl;
for (std::size_t i = 0; i < cloud_b.size(); ++i)
std::cerr << " " << cloud_b[i].normal[0] << " " << cloud_b[i].normal[1] << " " << cloud_b[i].normal[2] << std::endl;
//create cloud_c by concatenating the fields of cloud_a and cloud_b together.
pcl::concatenateFields(cloud_a, cloud_b, cloud_c);
std::cerr << "Cloud C: " << std::endl;
for (std::size_t i = 0; i < cloud_c.size(); ++i)
std::cerr << " " <<
cloud_c[i].x << " " << cloud_c[i].y << " " << cloud_c[i].z << " " <<
cloud_c[i].normal[0] << " " << cloud_c[i].normal[1] << " " << cloud_c[i].normal[2] << std::endl;
system("Pause");
return (0);
}
2. 上面出现的PointT类型
2.1 PointXYZ
- PointXYZ只包含三维xyz坐标信息,附加一个浮点数是为了满足存储对齐,所以一共有4个浮点数。
struct EIGEN_ALIGN16 PointXYZ : public _PointXYZ
{
inline PointXYZ (const _PointXYZ &p)
{
x = p.x; y = p.y; z = p.z; data[3] = 1.0f;
}
inline PointXYZ ()
{
x = y = z = 0.0f;
data[3] = 1.0f;
}
inline PointXYZ (float _x, float _y, float _z)
{
x = _x; y = _y; z = _z;
data[3] = 1.0f;
}
friend std::ostream& operator << (std::ostream& os, const PointXYZ& p);
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
2.2 Normal
- Normal结构体表示给定点所在样本曲面的法线方向,以及对应曲率的测量值。
- 第四个元素用来占位,这样可以兼容SSE和高效计算。
- 曲率不能和xyz一样被存储在同一个数组中,它需要独立的变量以避免被普通的数据操作覆盖。
struct Normal : public _Normal
{
inline Normal (const _Normal &p)
{
normal_x = p.normal_x; normal_y = p.normal_y; normal_z = p.normal_z;
data_n[3] = 0.0f;
curvature = p.curvature;
}
inline Normal ()
{
normal_x = normal_y = normal_z = data_n[3] = 0.0f;
curvature = 0;
}
inline Normal (float n_x, float n_y, float n_z)
{
normal_x = n_x; normal_y = n_y; normal_z = n_z;
curvature = 0;
data_n[3] = 0.0f;
}
friend std::ostream& operator << (std::ostream& os, const Normal& p);
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
2.3 PointNormal
- PointNormal是存储XYZ数据的point结构体,并且包括采样点对应法线和曲率
struct PointNormal : public _PointNormal
{
inline PointNormal (const _PointNormal &p)
{
x = p.x; y = p.y; z = p.z; data[3] = 1.0f;
normal_x = p.normal_x; normal_y = p.normal_y; normal_z = p.normal_z; data_n[3] = 0.0f;
curvature = p.curvature;
}
inline PointNormal ()
{
x = y = z = 0.0f;
data[3] = 1.0f;
normal_x = normal_y = normal_z = data_n[3] = 0.0f;
}
friend std::ostream& operator << (std::ostream& os, const PointNormal& p);
};