【PCL】教程 sphere_removal.cpp 自定义的过滤条件来过滤点云中某个区域内的点

终端输出:

Cloud before filtering:
    -1.23392 1.81505 -0.968005
    -0.00934529 1.36497 0.158734
    0.488435 1.96851 -0.0534078
    1.27135 1.16404 -1.00462
    -0.249089 -0.0815883 1.13229
    0.448447 1.48914 1.78378
    1.14143 1.77363 1.68965
    1.08544 -1.01664 -1.13041
    1.1199 0.9951 -1.13308
    1.44268 -1.44434 -0.391739
Cloud after filtering:
    -1.23392 1.81505 -0.968005
    -0.00934529 1.36497 0.158734
    0.488435 1.96851 -0.0534078
    1.27135 1.16404 -1.00462
    1.14143 1.77363 1.68965
    1.08544 -1.01664 -1.13041
    1.1199 0.9951 -1.13308
    1.44268 -1.44434 -0.391739

这段代码使用C++和点云库(PCL)进行点云的处理。下面是代码详细解析:

  1. 首先,代码包含了PCL库的一些必要头文件,用于生成和处理点云数据:

  • <pcl/common/generate.h>:用于生成点云数据

  • <pcl/filters/experimental/functor_filter.h>提供一个函数式过滤器,用于根据自定义条件过滤点云

  • <pcl/point_types.h>:定义了PCL中的点类型。

  • <iostream>:用于输出信息到标准错误流中。

main函数中,首先定义了使用pcl::PointXYZ点类型的点云别名XYZCloud

创建两个shared_ptr类型的XYZCloud对象cloudfiltered_cloud,分别用于存储原始点云和过滤后的点云。

使用pcl::common::CloudGeneratorpcl::common::UniformGenerator生成随机点云数据。这里参数{-2.0, 2, 1234}分别代表随机生成点的坐标范围和种子,然后将生成的10个点填充到cloud点云中。

通过循环输出原始点云中的点坐标。

设置一个圆形区域的中心和半径,用于过滤点云中的点。此处中心设为(0, 0, 2),半径设为2

定义一个过滤条件filter,该条件为一个lambda函数,接受点云和索引号,计算点云中点与设定圆心的欧氏距离,若大于等于半径,则该点满足条件。

使用pcl::experimental::FunctionFilter根据上述过滤条件对原始点云进行过滤,得到过滤后的点云。

循环输出过滤后点云中的点坐标。

总之,这段代码的功能是生成一个随机的点云,并使用自定义的过滤条件(本例中是一个以(0, 0, 2)为中心,半径为2的圆形区域外的点)对该点云进行过滤。过滤后的点云中只包含满足条件的点,然后输出过滤前后的点云信息。这种过滤方式非常灵活,可以根据需要定制过滤条件,非常适合在点云预处理中使用。

#include <pcl/common/generate.h> // 包含生成点云的功能函数
#include <pcl/filters/experimental/functor_filter.h> // 包含过滤点云的函数
#include <pcl/point_types.h> // 包含PCL中点类型的定义


#include <iostream> // 包含输入输出流的库


int 
main()
{
  using XYZCloud = pcl::PointCloud<pcl::PointXYZ>; // 定义一个别名XYZCloud用于表示pcl::PointXYZ类型的点云
  const auto cloud = pcl::make_shared<XYZCloud>(); // 创建一个新的点云共享指针
  const auto filtered_cloud = pcl::make_shared<XYZCloud>(); // 创建一个新的用于存放过滤后点云的共享指针


  // 创建一个随机数生成器填充点云
  pcl::common::CloudGenerator<pcl::PointXYZ, pcl::common::UniformGenerator<float>>
      generator{{-2.0, 2, 1234}}; // 初始化随机数发生器,范围是-2到2,种子是1234
  generator.fill(10, 1, *cloud); // 使用随机数生成器生成10个点填充点云


  std::cerr << "Cloud before filtering: " << std::endl; // 输出过滤前的点云
  for (const auto& pt : *cloud)
    std::cerr << "    " << pt.x << " " << pt.y << " " << pt.z << std::endl; // 遍历并输出点云中的每个点


  // 设置一个条件来拒绝滤波器内的点
  const Eigen::Vector3f center{0, 0, 2}; // 定义一个中心点
  const float radius = 2; // 定义一个半径


  pcl::experimental::FilterFunction<pcl::PointXYZ> filter; // 定义一个过滤函数
  filter = [=](const XYZCloud& cloud, pcl::index_t idx) {
    return ((cloud[idx].getVector3fMap() - center).norm() >= radius); // 如果点到中心的欧式距离大于或等于半径则保留
  };


  // 构建过滤器
  pcl::experimental::FunctionFilter<pcl::PointXYZ> func_filter(filter); // 用上面定义的过滤条件创建过滤器
  func_filter.setInputCloud(cloud); // 设置输入点云


  // 应用过滤器
  func_filter.filter(*filtered_cloud); // 执行过滤操作并把结果点云存储在filtered_cloud中


  // 显示过滤后的点云
  std::cerr << "Cloud after filtering: " << std::endl; // 输出过滤后的点云
  for (const auto& pt : *filtered_cloud)
    std::cerr << "    " << pt.x << " " << pt.y << " " << pt.z << std::endl; // 遍历并输出过滤后点云中的每个点


  return (0); // 程序正常结束
}

这段代码的功能是创建一个含有随机生成的点云数据的点云对象,然后通过一个自定义的过滤条件来过滤点云中某个区域内的点。过滤条件是点到一个中心点的距离大于或等于一个指定的半径。过滤操作之后,输出过滤前和过滤后的点云数据。

const auto cloud = pcl::make_shared<XYZCloud>(); 
与   pcl::PointCloud<pcl::PointXYZ>::Ptr 区别

ee1db471ce0bec1a88bcd5351cd102c0.png

pcl::common::CloudGenerator<pcl::PointXYZ, pcl::common::UniformGenerator<float>>
generator{{-2.0, 2, 1234}};// 定义一个名为generator的CloudGenerator对象
  generator.fill(10, 1, *cloud);// 使用generator填充点云

3b3a5016520a20c6ea27fba28fbe501e.png

6fe8c32fe76b71163c1bd48518095447.png

filter = [=](const XYZCloud& cloud, pcl::index_t idx) {
    return ((cloud[idx].getVector3fMap() - center).norm() >= radius); // 如果点到中心的欧式距离大于或等于半径则保留
  };

这行代码定义了一个过滤器的行为,具体来说就是一个lambda表达式,用来决定点云中的哪些点应该被保留。

  • filter:这是一个pcl::experimental::FilterFunction<pcl::PointXYZ>类型的变量,它用作点云过滤的条件。

  • [=]:这是lambda表达式的捕获列表。[=]表示以值捕获的方式捕获所有外部作用域中的变量(在这个例子中,主要是centerradius)。

  • (const XYZCloud& cloud, pcl::index_t idx):这是lambda表达式的参数列表cloud是一个对点云的引用,idx是点云中点的索引。这意味着这个lambda表达式将对点云中的每一个点进行操作。

  • cloud[idx].getVector3fMap() - center:这部分代码通过点的索引idx访问点云中的点,并获取该点的坐标(使用getVector3fMap()方法获得一个Eigen::Vector3f类型的向量),然后计算该点与一个中心点center的向量差

  • .norm():这是Eigen库中的方法,用于计算向量的欧几里得范数,即从原点到向量指定中心点的直线距离

  • >= radius:这是条件判断,如果点到center的距离大于或等于radius,则表达式的结果为true,这表示这个点应被保留;如果小于radius,则为false,表示这个点应被过滤掉。

综上所述,这个lambda表达式定义的过滤器的作用是检查点云中的每一个点,如果点到一个给定中心center的距离大于或等于指定的半径radius,则这个点满足条件,应被保留;否则,这个点不满足条件,应被过滤掉。这种过滤方式常用于去除一个区域内的所有点,例如,去除距离传感器特定距离内的所有点,以清除噪声或其他不需要的数据

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值