一、简介
在将两个不同的点云连接为同一个点云之前,要确保两个数据集中字段的类型和维度相同。同时也学习如何连接两个不同点云的字段(例如,颜色、法线),这种操作的强制约束条件是两个数据集中点的数目必须是一样的,例如,点云A是N个点的xyz点,点云B是N个点的rgb点,则连接两个字段形成的点云C是N个点的xyzrgb类型。
二、代码分析
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
int main(int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ> cloud_a, cloud_b, cloud_c; //创建三个点云,点云中的点的类型是XYZ
pcl::PointCloud<pcl::Normal> n_cloud_b; //创建一个点云,点云中的点都是法向量
pcl::PointCloud<pcl::PointNormal> p_n_cloud_b; //创建一个点云,点云中的点都是带法向量的点
cloud_a.width = 5; //初始化点云中点的数量
cloud_a.height = cloud_b.height = n_cloud_b.height = 1; //初始化点云中的点都是有序点
cloud_a.points.resize(cloud_a.width * cloud_a.height); //重新计算点云中的点的大小
for (size_t i = 0;i < cloud_a.points.size();++i) //随机数填充点云
{
cloud_a.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_a.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_a.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
std::cerr << "cloud A:" << std::endl; //循环输出点云A数据
for (size_t i = 0; i < cloud_a.points.size();++i)
{
std::cerr << " " << cloud_a.points[i].x << " " << cloud_a.points[i].y << " " << cloud_a.points[i].z << std::endl;
}
if (strcmp(argv[1], "-p") == 0) //如果是进行点云中点的拼接
{
cloud_b.width = 3; //初始化点云B,其点的数量不需要与A一致
cloud_b.points.resize(cloud_b.width * cloud_b.height);
for (size_t i = 0;i < cloud_b.points.size();++i) //随机填充B
{
cloud_b.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_b.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_b.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
std::cerr << "cloud B:" << std::endl; //循环输出B
for (size_t i = 0; i < cloud_b.points.size();++i)
{
std::cerr << " " << cloud_b.points[i].x << " " << cloud_b.points[i].y << " " << cloud_b.points[i].z << std::endl;
}
cloud_c = cloud_a; //将点云A与点云B进行拼接
cloud_c += cloud_b;
std::cerr << "Connect cloud A with cloud B to get cloud C:" << std::endl;//输出拼接后的点云C
for (size_t i = 0; i < cloud_c.points.size();++i)
{
std::cerr << " " << cloud_c.points[i].x << " " << cloud_c.points[i].y << " " << cloud_c.points[i].z << std::endl;
}
}
else
{
n_cloud_b.width = 5; //如果是进行字段拼接,将法向量拼接至点云,就需要确保法向量的个数与点云一致
n_cloud_b.points.resize(n_cloud_b.width * n_cloud_b.height);
for (size_t i = 0;i < n_cloud_b.points.size();++i)
{
n_cloud_b.points[i].normal[0] = 1024 * rand() / (RAND_MAX + 1.0f);
n_cloud_b.points[i].normal[1] = 1024 * rand() / (RAND_MAX + 1.0f);
n_cloud_b.points[i].normal[2] = 1024 * rand() / (RAND_MAX + 1.0f);
}
std::cerr << "Normal B:" << std::endl;
for (size_t i = 0; i < n_cloud_b.points.size();++i)
{
std::cerr << " " << n_cloud_b.points[i].normal[0] << " " << n_cloud_b.points[i].normal[1] << " " << n_cloud_b.points[i].normal[2] << std::endl;
}
pcl::concatenateFields(cloud_a, n_cloud_b, p_n_cloud_b); //进行字段的拼接
std::cerr << "Connect cloud A with Normal B to get PointNormalCloudB:" << std::endl;
for (size_t i = 0; i < p_n_cloud_b.points.size();++i)
{
std::cerr << " " << p_n_cloud_b.points[i].x << " " << p_n_cloud_b.points[i].y << " " << p_n_cloud_b.points[i].z << " " << p_n_cloud_b.points[i].normal[0] << " " << p_n_cloud_b.points[i].normal[1] << " " << p_n_cloud_b.points[i].normal[2] << std::endl;
}
}
return(0);
}
三、输出结果