【PCL】教程 concatenate_clouds 点云的创建、数据填充、拼接合并和字段的合并

命令行参数 -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(点云库)进行处理点云数据的示例程序。其主要流程如下:

  1. 程序首先检查命令行参数的数量,如果不等于2,则输出错误信息并退出程序。这里的命令行参数用于指示程序执行哪种类型的点云合并操作。

  2. 定义了三个点云对象cloud_acloud_bcloud_c以及一个法线点云对象n_cloud_b和点法线云对象p_n_cloud_c

  3. 程序填充点云cloud_acloud_bn_cloud_b的数据。cloud_a固定设置长度为5,cloud_b根据参数可设置长度为3,而n_cloud_b则可以设置为5。

  4. 通过随机数函数rand()cloud_acloud_bn_cloud_b中的每个点生成随机的坐标或法线方向。

  5. 根据命令行参数,执行对应的合并操作:

  • 如果参数为-p,则将cloud_acloud_b两个点云通过简单拼接合并cloud_c

  • 如果参数不为-p,则使用pcl::concatenateFields函数对点云cloud_a和法线云n_cloud_b进行字段结合(即位置和法线信息结合),生成点法线云p_n_cloud_c

将合并后的点云数据输出到标准错误流,cloud_cp_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(点云库)进行点云的基本操作,包括点云的创建、数据填充和字段的合并

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将不同字段点云数据进行拼接,可以使用`pcl::concatenateFields()`函数。这个函数可以将多个点云数据集按照相同的点数和点序列组合成一个新的点云数据集。下面是一个示例代码: ```cpp #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/common/concatenate.h> int main(int argc, char** argv) { // 读取两个点云文件 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud1(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); pcl::io::loadPCDFile("cloud1.pcd", *cloud1); pcl::io::loadPCDFile("normals.pcd", *normals); // 合并两个点云数据pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>); pcl::concatenateFields(*cloud1, *normals, *cloud_with_normals); // 将合并后的点云数据集拆分成两个点云数据pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud2(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::Normal>::Ptr normals2(new pcl::PointCloud<pcl::Normal>); pcl::copyPointCloud(*cloud_with_normals, *cloud2); pcl::copyPointCloud(*cloud_with_normals, *normals2); return 0; } ``` 这个例子中,我们首先读取了两个点云文件,一个包含XYZRGB信息,另一个包含法线信息。然后使用`pcl::concatenateFields()`函数将这两个点云数据合并成一个包含了XYZRGB和法线信息的点云数据集。最后使用`pcl::copyPointCloud()`函数将合并后的点云数据集拆分成两个点云数据集,一个包含XYZRGB信息,另一个包含法线信息。 需要注意的是,调用`pcl::copyPointCloud()`函数时,第一个参数是原始点云数据集,第二个参数是要拆分出来的目标点云数据集,所以在拆分时需要分别为XYZRGB和法线信息创建两个目标点云数据集。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值