命令行参数 -f, 合并字段 点+法向量
Cloud A:
1.28125 577.094 197.938
828.125 599.031 491.375
358.688 917.438 842.562
764.5 178.281 879.531
727.531 525.844 311.281
Cloud B:
15.3438 93.5938 373.188
150.844 169.875 1012.22
456.375 121.938 4.78125
9.125 386.938 544.406
584.875 616.188 621.719
Cloud C:
1.28125 577.094 197.938 15.3438 93.5938 373.188
828.125 599.031 491.375 150.844 169.875 1012.22
358.688 917.438 842.562 456.375 121.938 4.78125
764.5 178.281 879.531 9.125 386.938 544.406
727.531 525.844 311.281 584.875 616.188 621.719
参数 -p 点云拼接合并
Cloud A:
1.28125 577.094 197.938
828.125 599.031 491.375
358.688 917.438 842.562
764.5 178.281 879.531
727.531 525.844 311.281
Cloud B:
15.3438 93.5938 373.188
150.844 169.875 1012.22
456.375 121.938 4.78125
Cloud C:
1.28125 577.094 197.938
828.125 599.031 491.375
358.688 917.438 842.562
764.5 178.281 879.531
727.531 525.844 311.281
15.3438 93.5938 373.188
150.844 169.875 1012.22
456.375 121.938 4.78125
这段代码是一个使用PCL(点云库)进行处理点云数据的示例程序。其主要流程如下:
程序首先检查命令行参数的数量,如果不等于2,则输出错误信息并退出程序。这里的命令行参数用于指示程序执行哪种类型的点云合并操作。
定义了三个点云对象
cloud_a
,cloud_b
,cloud_c
以及一个法线点云对象n_cloud_b
和点法线云对象p_n_cloud_c
。程序填充点云
cloud_a
与cloud_b
或n_cloud_b
的数据。cloud_a
固定设置长度为5,cloud_b
根据参数可设置长度为3,而n_cloud_b
则可以设置为5。通过随机数函数
rand()
为cloud_a
和cloud_b
或n_cloud_b
中的每个点生成随机的坐标或法线方向。根据命令行参数,执行对应的合并操作:
如果参数为
-p
,则将cloud_a
和cloud_b
两个点云通过简单拼接合并成cloud_c
。如果参数不为
-p
,则使用pcl::concatenateFields
函数对点云cloud_a
和法线云n_cloud_b
进行字段结合(即位置和法线信息结合),生成点法线云p_n_cloud_c
。
将合并后的点云数据输出到标准错误流,cloud_c
或p_n_cloud_c
的每个点按格式打印输出。
综合上述,本段代码的核心功能是生成和合并点云数据,并展示如何使用PCL库进行点云的基本操作。它涉及到点云的生成、合并(简单拼接或带有法线信息的合并)以及输出显示点云的内容。用于演示点云数据结构的操作,为进一步的点云处理如注册、分析等提供基础数据操作示例。
#include <iostream> // 引入输入输出流库
#include <pcl/point_types.h> // 引入PCL库的点云类型头文件
#include <pcl/common/io.h> // 引入PCL库的IO(输入输出)相关功能,例如字段的合并
int
main (int argc, char** argv) // 主函数入口
{
if (argc != 2) // 检查命令行参数数量是否正确
{
std::cerr << "please specify command line arg '-f' or '-p'" << std::endl; // 如果不正确,则打印错误信息
exit(0); // 并退出程序
}
pcl::PointCloud<pcl::PointXYZ> cloud_a, cloud_b, cloud_c; // 定义三个点云变量,用于存储不同的点云数据
pcl::PointCloud<pcl::Normal> n_cloud_b; // 定义一个法线点云变量,用于存储点云B的法线信息
pcl::PointCloud<pcl::PointNormal> p_n_cloud_c; // 定义一个包含位置和法线信息的点云变量,用于存储合并后的点云数据
// 填充点云数据
cloud_a.width = 5; // 设置点云A的宽度
cloud_a.height = cloud_b.height = n_cloud_b.height = 1; // 设置点云A、B和n_cloud_b的高度为1,表示这些点云是无序的
cloud_a.resize(cloud_a.width * cloud_a.height); // 调整点云A的大小以容纳所有点
if (strcmp(argv[1], "-p") == 0) // 根据命令行参数决定点云B的初始化方式
{
cloud_b.width = 3; // 设置点云B的宽度
cloud_b.resize (cloud_b.width * cloud_b.height); // 调整点云B的大小
}
else{
n_cloud_b.width = 5; // 设置法线点云的宽度
n_cloud_b.resize (n_cloud_b.width * n_cloud_b.height); // 调整法线点云的大小
}
for (std::size_t i = 0; i < cloud_a.size (); ++i) // 为点云A生成随机坐标值
{
// 生成点云A中每个点的x, y, z坐标
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);
}
if (strcmp(argv[1], "-p") == 0) // 如果命令行参数为"-p",为点云B生成随机坐标值
for (std::size_t i = 0; i < cloud_b.size (); ++i)
{
// 生成点云B中每个点的x, y, z坐标
cloud_b[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
cloud_b[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
cloud_b[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
}
else // 否则,为法线点云生成随机法线方向值
for (std::size_t i = 0; i < n_cloud_b.size (); ++i)
{
// 生成法线点云中每个点的法线方向
n_cloud_b[i].normal[0] = 1024 * rand () / (RAND_MAX + 1.0f);
n_cloud_b[i].normal[1] = 1024 * rand () / (RAND_MAX + 1.0f);
n_cloud_b[i].normal[2] = 1024 * rand () / (RAND_MAX + 1.0f);
}
std::cerr << "Cloud A: " << std::endl; // 打印点云A的信息
for (std::size_t i = 0; i < cloud_a.size (); ++i)
// 循环打印点云A中每个点的坐标
std::cerr << " " << cloud_a[i].x << " " << cloud_a[i].y << " " << cloud_a[i].z << std::endl;
std::cerr << "Cloud B: " << std::endl; // 打印点云B的信息
if (strcmp(argv[1], "-p") == 0) // 如果命令行参数为"-p",则打印点云B中每个点的坐标
for (std::size_t i = 0; i < cloud_b.size (); ++i)
std::cerr << " " << cloud_b[i].x << " " << cloud_b[i].y << " " << cloud_b[i].z << std::endl;
else // 否则,打印法线点云中每个点的法线方向
for (std::size_t i = 0; i < n_cloud_b.size (); ++i)
std::cerr << " " << n_cloud_b[i].normal[0] << " " << n_cloud_b[i].normal[1] << " " << n_cloud_b[i].normal[2] << std::endl;
// 复制点云数据
if (strcmp(argv[1], "-p") == 0) // 如果命令行参数为"-p",则将点云A和点云B合并至点云C
{
cloud_c = cloud_a; // 将点云A的内容复制到点云C
cloud_c += cloud_b; // 将点云B的内容添加到点云C
std::cerr << "Cloud C: " << std::endl; // 打印点云C的信息
for (std::size_t i = 0; i < cloud_c.size (); ++i)
// 循环打印点云C中每个点的坐标
std::cerr << " " << cloud_c[i].x << " " << cloud_c[i].y << " " << cloud_c[i].z << " " << std::endl;
}
else
{
// 如果命令行参数不是"-p",则将点云A和法线点云合并,生成一个包含位置和法线信息的点云
pcl::concatenateFields (cloud_a, n_cloud_b, p_n_cloud_c);
std::cerr << "Cloud C: " << std::endl; // 打印合并后的点云C的信息
for (std::size_t i = 0; i < p_n_cloud_c.size (); ++i)
// 循环打印点云C中每个点的位置和法线信息
std::cerr << " " <<
p_n_cloud_c[i].x << " " << p_n_cloud_c[i].y << " " << p_n_cloud_c[i].z << " " <<
p_n_cloud_c[i].normal[0] << " " << p_n_cloud_c[i].normal[1] << " " << p_n_cloud_c[i].normal[2] << std::endl;
}
return (0); // 程序正常结束
}
此段代码的主要功能是,根据命令行参数,创建和初始化几个点云变量,为它们填入随机生成的位置和/或法线方向数据,然后根据命令行指定的模式将它们进行合并,并打印出合并前后的点云数据。这可以用于演示如何使用PCL(点云库)进行点云的基本操作,包括点云的创建、数据填充和字段的合并。