命令行参数 -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(点云库)进行点云的基本操作,包括点云的创建、数据填充和字段的合并。

被折叠的 条评论
为什么被折叠?



