PCL教程指南-投影参数模型,索引提取点云,条件滤波或半径滤波剔除离群点

PCL教程指南-投影参数模型,索引提取点云,条件滤波,半径滤波

一.Projecting points using a parametric model(投影参数模型)

  • 官方文档原文
  • 目的是将点云投影到某一个模型上,比如平面,球体等
  • 以下对原文代码进行注释解读,并扩展类中其他内容
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/project_inliers.h>

int
 main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected (new pcl::PointCloud<pcl::PointXYZ>);

  // 随机生成5个点的点云数据
  cloud->width  = 5;
  cloud->height = 1;
  cloud->points.resize (cloud->width * cloud->height);

  for (auto& point: *cloud)
  {
    point.x = 1024 * rand () / (RAND_MAX + 1.0f);
    point.y = 1024 * rand () / (RAND_MAX + 1.0f);
    point.z = 1024 * rand () / (RAND_MAX + 1.0f);
  }

  std::cerr << "Cloud before projection: " << std::endl;
  for (const auto& point: *cloud)
    std::cerr << "    " << point.x << " "
                        << point.y << " "
                        << point.z << std::endl;

  // 创建一个平面模型,系数为 X=Y=0,Z=1
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
  //调整系数为4个即 X Y Z 常数
  coefficients->values.resize (4);
  coefficients->values[0] = coefficients->values[1] = 0;
  coefficients->values[2] = 1.0;
  coefficients->values[3] = 0;

  // 创建投影模型类
  pcl::ProjectInliers<pcl::PointXYZ> proj;
  //设置模型类别为平面
  proj.setModelType (pcl::SACMODEL_PLANE);
  proj.setInputCloud (cloud);
  proj.setModelCoefficients (coefficients);
  proj.filter (*cloud_projected);

  std::cerr << "Cloud after projection: " << std::endl;
  for (const auto& point: *cloud_projected)
    std::cerr << "    " << point.x << " "
                        << point.y << " "
                        << point.z << std::endl;

  return (0);
}
  • 其中 pcl::ProjectInliers<pcl::PointT>还有一个常用方法为 void setCopyAllData (bool val)用于设置返回所有数据还是只返回执行投影的点数据(区别在于本来就在模型上的点是否输出)
  • 另外模型除了平面,还有多种内置的采样模型:
 namespace pcl
 {
   enum SacModel
   {
     SACMODEL_PLANE,
     SACMODEL_LINE,
     SACMODEL_CIRCLE2D,
     SACMODEL_CIRCLE3D,
     SACMODEL_SPHERE,
     SACMODEL_CYLINDER,
     SACMODEL_CONE,
     SACMODEL_TORUS,
     SACMODEL_PARALLEL_LINE,
     SACMODEL_PERPENDICULAR_PLANE,
     SACMODEL_PARALLEL_LINES,
     SACMODEL_NORMAL_PLANE,
     SACMODEL_NORMAL_SPHERE,
     SACMODEL_REGISTRATION,
     SACMODEL_REGISTRATION_2D,
     SACMODEL_PARALLEL_PLANE,
     SACMODEL_NORMAL_PARALLEL_PLANE,
     SACMODEL_STICK
   };
 }

二.Extracting indices from a PointCloud(根据索引提取点云数据)

  • 官方文档原文
  • 由于PCL执行操作时一般输出为索引结构以提高效率,但有时我们需要索引代表的完整点云数据,此类即根据索引来提取点云数据
  • 由于原文涉及了分割算法,之后会细讲,对于提取类不会有任何影响所以以下只对关键类进行注释解读,并扩展类中其他内容
// 索引提取点云类
  pcl::ExtractIndices<pcl::PointXYZ> extract;
  //点索引结构体指针
pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());
省略中间赋值过程
    
    extract.setInputCloud (cloud_filtered);
    extract.setIndices (inliers);
    extract.setNegative (false);
    extract.filter (*cloud_p);
   
    // 反向提取
    extract.setNegative (true);
    extract.filter (*cloud_f);
    //点云交换
    cloud_filtered.swap (cloud_f);
   
  • 其中pcl::ExtractIndices<pcl::PointT>类所用方法主要继承自
    • pcl::FilterIndices<pcl::PointT> 索引过滤类;
    • pcl::Filter<pcl::PointT> 过滤类
    • pcl::PCLBase ()<pcl::PointT>PCL基础类;
  • 索引提取类有一个自身实现的特殊的方法
    • void pcl::ExtractIndices< PointT >::filterDirectly ( PointCloudPtr & cloud )
    • 应用过滤器并将结果直接存储在输入云中,这个方法将节省输出云的时间和内存,但不能改变输入云的原始大小:它的操作方式就像setkeepororganized()为真一样,并将覆盖过滤后的点,而不是删除它们。所有过滤点的字段都将被setUserFilterValue() (default = NaN)设置的值所替换。这个方法还可以通过setInputCloud()自动修改输入云集。它不会改变setkeeorganizized()设置的内部keep organized布尔值。

三.Removing outliers using a Conditional or RadiusOutlier removal(使用条件滤波或半径滤波剔除离群点)

  • 官方文档原文
  • 条件滤波通过控制过滤条件去除相关点数据; 半径滤波根据点自身半径范围内邻域数量判断是否剔除
  • 代码较简单,主要分条件滤波和半径滤波分别注释解读,并扩展说明其他内容

半径滤波

//半径滤波对象
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
    outrem.setInputCloud(cloud);
    //设置搜索的半径距离
    outrem.setRadiusSearch(0.8);
    //设置最小邻域数,小于此数 剔除
    outrem.setMinNeighborsInRadius (2);
    //使不满足的数据不被删除
    outrem.setKeepOrganized(true);
    outrem.filter (*cloud_filtered);

条件滤波

// And条件对象
 pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond (new
      pcl::ConditionAnd<pcl::PointXYZ> ());
      //添加比较条件   pcl::ComparisonOps::GT为比较运算符:大于
    range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new
      pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::GT, 0.0)));
      //添加比较条件   pcl::ComparisonOps::LT为比较运算符:小于
    range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new
      pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::LT, 0.8)));
    // 条件剔除对象
    pcl::ConditionalRemoval<pcl::PointXYZ> condrem;
    //设置之前的条件对象
    condrem.setCondition (range_cond);
    condrem.setInputCloud (cloud);
    condrem.setKeepOrganized(true);
   
    condrem.filter (*cloud_filtered);
  • 其中pcl::ConditionAnd<pcl::PointT>继承自pcl::ConditionBase< PointT >类,除了AND(和)运算外还有pcl::ConditionOr<pcl::PointT>或运算
  • 另外,pcl::FieldComparison<pcl::PointT>继承自ComparisonBase<PointT>类,除了字段比较外还有:
作用
PackedRGBComparison< pcl::PointT >比较打包后的RGB(即打包成一个浮点数的RGB)
PackedHSIComparison< pcl::PointT >比较打包的HSI
TfQuadraticXYZComparison< pcl::PointT >坐标XYZ中比较公式为(p’Ap + 2v’p + c [OP] 0) 其中 OP为运算符, p = (x,y,z) 是点云中一点; A 是 3x3矩阵; v是3x1向量; c是常数
  • OP运算符包括 GT, GE, LT, LE or EQ 各意思为 大于,大于等于…(英文缩写对照)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值