首页 > 其他分享 >PCL点云滤波代码

PCL点云滤波代码

时间:2023-11-16 16:04:14浏览次数:37  
标签:PCL 滤波 points pcl 点云 include ptr cloud

PCL点云滤波代码实例

1.直通滤波:

PassThrough           
直接指定保留哪个轴上的范围内的点
#include <pcl/filters/passthrough.h>
如果使用线结构光扫描的方式采集点云,必然物体沿z向分布较广,但x,y向的分布处于有限范围内。
此时可使用直通滤波器,确定点云在x或y方向上的范围,可较快剪除离群点,达到第一步粗处理的目的。

 

 1 /* 创建点云对象 指针
 2 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
 3 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
 4 // 原点云获取后进行滤波
 5 pcl::PassThrough<pcl::PointXYZ> pass;// 创建滤波器对象
 6 pass.setInputCloud (cloud);//设置输入点云
 7 pass.setFilterFieldName ("z");//滤波字段名被设置为Z轴方向
 8 pass.setFilterLimits (0.0, 1.0);//可接受的范围为(0.0,1.0) 
 9 //pass.setFilterLimitsNegative (true);//设置保留范围内 还是 过滤掉范围内
10 pass.filter (*cloud_filtered); //执行滤波,保存过滤结果在cloud_filtered
11 */
12 #include <iostream>
13 #include <pcl/point_types.h>
14 #include <pcl/filters/passthrough.h>//直通滤波器 PassThrough 
15 #include <pcl/visualization/cloud_viewer.h>//点云可视化
16 // 别名
17 typedef pcl::PointCloud<pcl::PointXYZ>  Cloud;
18 
19 int  main (int argc, char** argv)
20 {
21   // 定义 点云对象 指针
22    Cloud::Ptr cloud_ptr(new Cloud());
23    Cloud::Ptr cloud_filtered_ptr(new Cloud());
24   //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
25   //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_ptr (new pcl::PointCloud<pcl::PointXYZ>);
26 
27   // 产生点云数据 
28   cloud_ptr->width  = 10;
29   cloud_ptr->height = 1;
30   cloud_ptr->points.resize (cloud_ptr->width * cloud_ptr->height);
31   for (size_t i = 0; i < cloud_ptr->points.size (); ++i)
32   {
33     cloud_ptr->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
34     cloud_ptr->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
35     cloud_ptr->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
36   }
37 
38   std::cerr << "Cloud before filtering滤波前: " << std::endl;
39   for (size_t i = 0; i < cloud_ptr->points.size (); ++i)
40     std::cerr << "    " << cloud_ptr->points[i].x << " " 
41                         << cloud_ptr->points[i].y << " " 
42                         << cloud_ptr->points[i].z << std::endl;
43 
44   // 创建滤波器对象 Create the filtering object
45   pcl::PassThrough<pcl::PointXYZ> pass;
46   pass.setInputCloud (cloud_ptr);//设置输入点云
47   pass.setFilterFieldName ("z");// 定义轴
48   pass.setFilterLimits (0.0, 1.0);// 范围
49  // pass.setKeepOrganized(true); // 保持 有序点云结构===============
50   pass.setFilterLimitsNegative (false);//标志为false时保留范围内的点
51   pass.filter (*cloud_filtered_ptr);
52 
53   // 输出滤波后的点云
54   std::cerr << "Cloud after filtering滤波后: " << std::endl;
55   for (size_t i = 0; i < cloud_filtered_ptr->points.size (); ++i)
56     std::cerr << "    " << cloud_filtered_ptr->points[i].x << " " 
57                         << cloud_filtered_ptr->points[i].y << " " 
58                         << cloud_filtered_ptr->points[i].z << std::endl;
59   // 程序可视化
60  
61   pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字
62   viewer.showCloud(cloud_filtered_ptr);
63   while (!viewer.wasStopped())
64     {
65         // Do nothing but wait.
66     }
67 
68   return (0);
69 }

 

2.体素滤波器:

VoxelGrid

体素格 (正方体立体空间内 保留一个点(重心点))在网格内减少点数量保证重心位置不变 PCLPointCloud2() 下采样

#include <pcl/filters/voxel_grid.h>

 

注意此点云类型为 pcl::PCLPointCloud2 类型 blob 格子类型
#include <pcl/filters/voxel_grid.h>

 

// 转换为模板点云 pcl::PointCloud<pcl::PointXYZ>
pcl::fromPCLPointCloud2 (*cloud_filtered_blob, *cloud_filtered);

 

如果使用高分辨率相机等设备对点云进行采集,往往点云会较为密集。
过多的点云数量会对后续分割工作带来困难。
体素格滤波器可以达到向下采样同时不破坏点云本身几何结构的功能。
点云几何结构 不仅是宏观的几何外形,也包括其微观的排列方式,
比如横向相似的尺寸,纵向相同的距离。
随机下采样虽然效率比体素滤波器高,但会破坏点云微观结构.

 

使用体素化网格方法实现下采样,即减少点的数量 减少点云数据,
并同时保存点云的形状特征,在提高配准,曲面重建,形状识别等算法速度中非常实用,
PCL是实现的VoxelGrid类通过输入的点云数据创建一个三维体素栅格,
容纳后每个体素内用体素中所有点的重心来*似显示体素中其他点,
这样该体素内所有点都用一个重心点最终表示,对于所有体素处理后得到的过滤后的点云,
这种方法比用体素中心(注意中心和重心)逼*的方法更慢,但是对于采样点对应曲面的表示更为准确。

 

#include <iostream>
#include <pcl/point_types.h>
//#include <pcl/filters/passthrough.h>
#include <pcl/filters/voxel_grid.h>//体素格滤波器VoxelGrid
#include <pcl/io/pcd_io.h>//点云文件pcd 读写
#include <pcl/visualization/cloud_viewer.h>//点云可视化

using namespace std;
// 别名
typedef pcl::PointCloud<pcl::PointXYZ>  Cloud;

int
main(int argc, char** argv)
{
    // 定义 点云对象 指针
    pcl::PCLPointCloud2::Ptr cloud2_ptr(new pcl::PCLPointCloud2());
    pcl::PCLPointCloud2::Ptr cloud2_filtered_ptr(new pcl::PCLPointCloud2());
    Cloud::Ptr cloud_filtered_ptr(new Cloud);
    // 读取点云文件 填充点云对象
    pcl::PCDReader reader;
    reader.read("../table_scene_lms400.pcd", *cloud2_ptr);
    if (cloud2_ptr == NULL) { cout << "pcd file read err" << endl; return -1; }
    cout << "PointCLoud before filtering 滤波前数量: " << cloud2_ptr->width * cloud2_ptr->height
        << " data points ( " << pcl::getFieldsList(*cloud2_ptr) << "." << endl;

    // 创建滤波器对象 Create the filtering object
    pcl::VoxelGrid<pcl::PCLPointCloud2> vg;
    // pcl::ApproximateVoxelGrid<pcl::PointXYZ> avg;
    vg.setInputCloud(cloud2_ptr);//设置输入点云
    vg.setLeafSize(0.01f, 0.01f, 0.01f);// 体素块大小 1cm
    vg.filter(*cloud2_filtered_ptr);

    // 输出滤波后的点云信息
    cout << "PointCLoud before filtering 滤波后数量: " << cloud2_filtered_ptr->width * cloud2_filtered_ptr->height
        << " data points ( " << pcl::getFieldsList(*cloud2_filtered_ptr) << "." << endl;
    // 写入内存
    pcl::PCDWriter writer;
    writer.write("table_scene_lms400_downsampled.pcd", *cloud2_filtered_ptr,
        Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), false);

    // 调用系统可视化命令行显示
    //system("pcl_viewer table_scene_lms400_inliers.pcd");

    // 转换为模板点云 pcl::PointCloud<pcl::PointXYZ>
    pcl::fromPCLPointCloud2(*cloud2_filtered_ptr, *cloud_filtered_ptr);

    // 程序可视化
    pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字
    viewer.showCloud(cloud_filtered_ptr);
    while (!viewer.wasStopped())
    {
        // Do nothing but wait.
    }

    return (0);
}

3.均匀采样:

UnifromSapling

均匀采样:半径求体内 保留一个点(重心点)

均匀采样:这个类基本上是相同的,但它输出的点云索引是选择的关键点,是在计算描述子的常见方式。

原理同体素格 (正方体立体空间内 保留一个点(重心点))
而 均匀采样:半径求体内 保留一个点(重心点)

 

 1 #include <iostream>
 2 #include <pcl/point_types.h>
 3 //#include <pcl/filters/passthrough.h>
 4 //#include <pcl/filters/voxel_grid.h>//体素格滤波器VoxelGrid
 5 #include <pcl/filters/uniform_sampling.h>//均匀采样
 6 #include <pcl/io/pcd_io.h>//点云文件pcd 读写
 7 #include <pcl/visualization/cloud_viewer.h>//点云可视化
 8 //#include <pcl_conversions/pcl_conversions.h>//点云类型转换
 9 
10 using namespace std;
11 // 别名
12 typedef pcl::PointCloud<pcl::PointXYZ>  Cloud;
13 
14 int
15  main (int argc, char** argv)
16 {
17   // 定义 点云对象 指针
18   //pcl::PCLPointCloud2::Ptr cloud2_ptr(new pcl::PCLPointCloud2());
19   //pcl::PCLPointCloud2::Ptr cloud2_filtered_ptr(new pcl::PCLPointCloud2());
20   Cloud::Ptr cloud_ptr(new Cloud);
21   Cloud::Ptr cloud_filtered_ptr(new Cloud);
22   // 读取点云文件 填充点云对象
23   pcl::PCDReader reader;
24   reader.read( "../table_scene_lms400.pcd", *cloud_ptr);
25   if(cloud_ptr==NULL) { cout << "pcd file read err" << endl; return -1;}
26   cout << "PointCLoud before filtering 滤波前数量: " << cloud_ptr->width * cloud_ptr->height
27        << " data points ( " << pcl::getFieldsList (*cloud_ptr) << "." << endl;
28 
29   // 创建滤波器对象 Create the filtering object
30     pcl::UniformSampling<pcl::PointXYZ> filter;// 均匀采样
31     filter.setInputCloud(cloud_ptr);//输入点云
32     filter.setRadiusSearch(0.01f);//设置半径
33     //pcl::PointCloud<int> keypointIndices;// 索引
34     filter.filter(*cloud_filtered_ptr);
35     //pcl::copyPointCloud(*cloud_ptr, keypointIndices.points, *cloud_filtered_ptr);
36   // 输出滤波后的点云信息
37   cout << "PointCLoud before filtering 滤波后数量: " << cloud_filtered_ptr->width * cloud_filtered_ptr->height
38        << " data points ( " << pcl::getFieldsList (*cloud_filtered_ptr) << "." << endl;
39   // 写入内存
40   //pcl::PCDWriter writer;
41   //writer.write("table_scene_lms400_UniformSampled.pcd",*cloud_filtered_ptr,
42   //             Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false);
43 
44   // 调用系统可视化命令行显示
45   //system("pcl_viewer table_scene_lms400_inliers.pcd");
46 
47   // 转换为模板点云 pcl::PointCloud<pcl::PointXYZ>
48  // pcl::fromPCLPointCloud2 (*cloud2_filtered_ptr, *cloud_filtered_ptr);
49 
50   // 程序可视化
51   pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字
52   viewer.showCloud(cloud_filtered_ptr);
53   while (!viewer.wasStopped())
54     {
55         // Do nothing but wait.
56     }
57 
58   return (0);
59 }

4.统计滤波器:

StatisticalOutlierRemoval  统计滤波器用于去除明显离群点

#include <pcl/filters/statistical_outlier_removal.h>

统计滤波器用于去除明显离群点(离群点往往由测量噪声引入)。其特征是在空间中分布稀疏,可以理解为:每个点都表达一定信息量,某个区域点越密集则可能信息量越大。噪声信息属于无用信息,信息量较小。所以离群点表达的信息可以忽略不计。考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最*的k(设定)个点*均距离。则点云中所有点的距离应构成高斯分布。给定均值与方差,可剔除n个西格玛之外的点激光扫描通常会产生密度不均匀的点云数据集,另外测量中的误差也会产生稀疏的离群点,此时,估计局部点云特征(例如采样点处法向量或曲率变化率)时运算复杂,这会导致错误的数值,反过来就会导致点云配准等后期的处理失败。

解决办法:对每个点的邻域进行一个统计分析,并修剪掉一些不符合标准的点。具体方法为在输入数据中对点到临*点的距离分布的计算,对每一个点,计算它到所有临*点的*均距离(假设得到的结果是一个高斯分布,其形状是由均值和标准差决定),那么*均距离在标准范围之外的点,可以被定义为离群点并从数据中去除。

 

#include <iostream>
#include <pcl/point_types.h>
//#include <pcl/filters/passthrough.h>
//#include <pcl/filters/voxel_grid.h>//体素格滤波器VoxelGrid
#include <pcl/filters/statistical_outlier_removal.h>//统计滤波器 
#include <pcl/io/pcd_io.h>//点云文件pcd 读写
#include <pcl/visualization/cloud_viewer.h>//点云可视化

using namespace std;
// 别名
typedef pcl::PointCloud<pcl::PointXYZ>  Cloud;

int
main(int argc, char** argv)
{
    // 定义 点云对象 指针
    Cloud::Ptr cloud_ptr(new Cloud);
    Cloud::Ptr cloud_filtered_ptr(new Cloud);
    //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
    //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_ptr (new pcl::PointCloud<pcl::PointXYZ>);

    // 读取点云文件 填充点云对象
    pcl::PCDReader reader;
    reader.read("../table_scene_lms400.pcd", *cloud_ptr);
    if (cloud_ptr == NULL) { cout << "pcd file read err" << endl; return -1; }
    cout << "PointCLoud before filtering 滤波前数量: " << cloud_ptr->width * cloud_ptr->height
        << " data points ( " << pcl::getFieldsList(*cloud_ptr) << "." << endl;

    // 创建滤波器,对每个点分析的临*点的个数设置为50 ,并将标准差的倍数设置为1  这意味着如果一
    // 个点的距离超出了*均距离一个标准差以上,则该点被标记为离群点,并将它移除,存储起来
    pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sta;//创建滤波器对象
    sta.setInputCloud(cloud_ptr);            //设置待滤波的点云
    sta.setMeanK(50);                         //设置在进行统计时考虑查询点临*点数
    sta.setStddevMulThresh(1.0);                   //设置判断是否为离群点的阀值
    sta.filter(*cloud_filtered_ptr);             //存储内点

    // 输出滤波后的点云信息
    std::cerr << "Cloud after filtering: " << std::endl;
    std::cerr << *cloud_filtered_ptr << std::endl;

    // 写入内存  保存内点
    pcl::PCDWriter writer;
    writer.write("table_scene_lms400_inliers.pcd", *cloud_filtered_ptr, false);
    // 保存外点 被滤出的点
    sta.setNegative(true);
    sta.filter(*cloud_filtered_ptr);
    writer.write<pcl::PointXYZ>("table_scene_lms400_outliers.pcd", *cloud_filtered_ptr, false);

    // 调用系统可视化命令行显示
    //system("pcl_viewer table_scene_lms400_inliers.pcd");

    // 程序可视化
    pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字
    viewer.showCloud(cloud_filtered_ptr);
    while (!viewer.wasStopped())
    {
        // Do nothing but wait.
    }

    return (0);
}

 

5.半径滤波器:

RadiusOutlinerRemoval   球半径滤波器

#include <pcl/filters/radius_outlier_removal.h>

球半径滤波器与统计滤波器相比更加简单粗暴。以某点为中心 画一个球计算落在该球内的点的数量,当数量大于给定值时,

则保留该点,数量小于给定值则剔除该点。此算法运行速度快,依序迭代留下的点一定是最密集的,但是球的半径和球内点的数目都需要人工指定。RadiusOutlinerRemoval比较适合去除单个的离群点 ConditionalRemoval 比较灵活,可以根据用户设置的条件灵活过滤。 

 

#include <iostream>
#include <pcl/point_types.h>
//#include <pcl/filters/passthrough.h>
//#include <pcl/ModelCoefficients.h>     //模型系数头文件
//#include <pcl/filters/project_inliers.h> //投影滤波类头文件
#include <pcl/io/pcd_io.h>               //点云文件pcd 读写
#include <pcl/filters/radius_outlier_removal.h>// 球半径滤波器
#include <pcl/visualization/cloud_viewer.h>//点云可视化

// 别名
typedef pcl::PointCloud<pcl::PointXYZ>  Cloud;
using namespace std;
int main (int argc, char** argv)
{
  // 定义 点云对象 指针
   Cloud::Ptr cloud_ptr(new Cloud());
   Cloud::Ptr cloud_filtered_ptr(new Cloud());

  // 产生点云数据 
  cloud_ptr->width  = 5;
  cloud_ptr->height = 1;
  cloud_ptr->points.resize (cloud_ptr->width * cloud_ptr->height);
  for (size_t i = 0; i < cloud_ptr->points.size (); ++i)
  {
    cloud_ptr->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud_ptr->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud_ptr->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
  }

  std::cerr << "Cloud before filtering半径滤波前: " << std::endl;
  for (size_t i = 0; i < cloud_ptr->points.size (); ++i)
    std::cerr << "    " << cloud_ptr->points[i].x << " " 
                        << cloud_ptr->points[i].y << " " 
                        << cloud_ptr->points[i].z << std::endl;

  // 可使用 strcmp获取指定命令行参数 if (strcmp(argv[1], "-r") == 0)
  // 创建滤波器 
  pcl::RadiusOutlierRemoval<pcl::PointXYZ> Radius;
  // 建立滤波器
  Radius.setInputCloud(cloud_ptr);
  Radius.setRadiusSearch(1.2);//半径为 0.8m
  Radius.setMinNeighborsInRadius (2);//半径内最少需要 2个点
  // 执行滤波
  Radius.filter (*cloud_filtered_ptr);

  // 输出滤波后的点云
  std::cerr << "Cloud after filtering半径滤波后: " << std::endl;
  for (size_t i = 0; i < cloud_filtered_ptr->points.size (); ++i)
    std::cerr << "    " << cloud_filtered_ptr->points[i].x << " " 
                        << cloud_filtered_ptr->points[i].y << " " 
                        << cloud_filtered_ptr->points[i].z << std::endl;
  // 程序可视化
  pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字
  viewer.showCloud(cloud_filtered_ptr);
  while (!viewer.wasStopped())
    {
        // Do nothing but wait.
    }

  return (0);
}

 

6.条件滤波器:ConditionalRemoval

可以一次删除满足对输入的点云设定的一个或多个条件指标的所有的数据点

删除点云中不符合用户指定的一个或者多个条件的数据点不在条件范围内的点 被替换为 nan

pcl::removeNaNFromPointCloud()去除Nan点
#include <pcl/filters/conditional_removal.h>

 

 1 #include <iostream>
 2 #include <pcl/point_types.h>
 3 //#include <pcl/filters/passthrough.h>
 4 //#include <pcl/ModelCoefficients.h>       //模型系数头文件
 5 //#include <pcl/filters/project_inliers.h> //投影滤波类头文件
 6 #include <pcl/io/pcd_io.h>                 //点云文件pcd 读写
 7 //#include <pcl/filters/radius_outlier_removal.h>// 球半径滤波器
 8 #include <pcl/filters/conditional_removal.h>     //条件滤波器
 9 
10 //#include <pcl/filters/filter.h>
11 
12 #include <pcl/visualization/cloud_viewer.h>//点云可视化
13 
14 // 别名
15 typedef pcl::PointCloud<pcl::PointXYZ>  Cloud;
16 using namespace std;
17 int main(int argc, char** argv)
18 {
19     // 定义 点云对象 指针
20     Cloud::Ptr cloud_ptr(new Cloud());
21     Cloud::Ptr cloud_filtered_ptr(new Cloud());
22 
23     // 产生点云数据 
24     cloud_ptr->width = 5;
25     cloud_ptr->height = 1;
26     cloud_ptr->points.resize(cloud_ptr->width * cloud_ptr->height);
27     for (size_t i = 0; i < cloud_ptr->points.size(); ++i)
28     {
29         cloud_ptr->points[i].x = 1 * rand() / (RAND_MAX + 1.0f);
30         cloud_ptr->points[i].y = 1 * rand() / (RAND_MAX + 1.0f);
31         cloud_ptr->points[i].z = 1 * rand() / (RAND_MAX + 1.0f);
32     }
33 
34     cout << "Cloud before filtering半径滤波前: " << endl;
35     for (size_t i = 0; i < cloud_ptr->points.size(); ++i)
36         cout << cloud_ptr->points[i].x << "," << cloud_ptr->points[i].y << "," << cloud_ptr->points[i].z << endl;
37 
38 
39     // 可使用 strcmp获取指定命令行参数 if (strcmp(argv[1], "-r") == 0)
40     //创建条件定义对象
41     pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond_cptr(new pcl::ConditionAnd<pcl::PointXYZ>());
42     //为条件定义对象添加比较算子
43     range_cond_cptr->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new
44         pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::GT, 0.0)));
45     //添加在Z字段上大于(pcl::ComparisonOps::GT great Then)0的比较算子
46 
47     range_cond_cptr->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new
48         pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::LT, 0.8)));
49     //添加在Z字段上小于(pcl::ComparisonOps::LT Lower Then)0.8的比较算子
50 
51     // 创建滤波器并用条件定义对象初始化
52     pcl::ConditionalRemoval<pcl::PointXYZ> conditrem;//创建条件滤波器
53     conditrem.setCondition(range_cond_cptr);        //并用条件定义对象初始化            
54     conditrem.setInputCloud(cloud_ptr);             //输入点云
55     conditrem.setKeepOrganized(true);                //设置保持点云的结构
56     // 执行滤波
57     conditrem.filter(*cloud_filtered_ptr);           //大于0.0小于0.8这两个条件用于建立滤波器
58     // 不在条件范围内的点 被替换为 nan
59 
60     // 输出滤波后的点云
61     std::cout << "Cloud after filtering半径滤波后: " << std::endl;
62     for (size_t i = 0; i < cloud_filtered_ptr->points.size(); ++i)
63     {
64         std::cout << "    " << cloud_filtered_ptr->points[i].x << " "
65             << cloud_filtered_ptr->points[i].y << " "
66             << cloud_filtered_ptr->points[i].z << std::endl;
67     }
68 
69     // 去除 nan点
70     vector<int> mapping;
71     pcl::removeNaNFromPointCloud(*cloud_filtered_ptr, *cloud_filtered_ptr, mapping);
72     // 输出去除nan后的点云
73     std::cout << "Cloud after delet nan point去除nan点 : " << std::endl;
74     for (size_t i = 0; i < cloud_filtered_ptr->points.size(); ++i)
75     {
76         std::cout << "    " << cloud_filtered_ptr->points[i].x << " "
77             << cloud_filtered_ptr->points[i].y << " "
78             << cloud_filtered_ptr->points[i].z << std::endl;
79 
80     }
81     // 程序可视化
82     pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字
83     viewer.showCloud(cloud_filtered_ptr);
84     while (!viewer.wasStopped())
85     {
86         // Do nothing but wait.
87     }
88 
89     return (0);
90 }

 

7.索引滤波器:

extractIndices 根据点云索引提取对应的点云

 

 1 #include <iostream>
 2 
 3 // PCL
 4 #include <pcl/point_types.h>
 5 #include <pcl/filters/extract_indices.h>
 6 
 7 int main(int, char**)
 8 {
 9     typedef pcl::PointXYZ PointType;
10     typedef pcl::PointCloud<PointType> CloudType;
11     CloudType::Ptr cloud(new CloudType);
12     cloud->is_dense = false;
13     // 生成点云 
14     PointType p;
15     for (unsigned int i = 0; i < 5; ++i)
16     {
17         p.x = p.y = p.z = static_cast<float> (i);
18         cloud->push_back(p);
19     }
20 
21     std::cout << "Cloud has " << cloud->points.size() << " points." << std::endl;
22 
23     pcl::PointIndices indices;// 取得需要的索引
24     indices.indices.push_back(0);
25     indices.indices.push_back(2);
26 
27     pcl::ExtractIndices<PointType> extract_indices;//索引提取器
28     extract_indices.setIndices(boost::make_shared<const pcl::PointIndices>(indices));//设置索引
29     extract_indices.setInputCloud(cloud);//设置输入点云
30     pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>);
31     extract_indices.filter(*output);//提取对于索引的点云
32 
33   // 外点 绿色
34     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_other(new pcl::PointCloud<pcl::PointXYZ>);
35     // *cloud_other = *cloud - *output;
36       // 移去*面局内点,提取剩余点云
37     extract_indices.setNegative(true);
38     extract_indices.filter(*cloud_other);
39     std::cout << "Output has " << output->points.size() << " points." << std::endl;
40     std::cout << output->points[0].x << "," << output->points[0].y << "," << output->points[0].z << std::endl;
41     std::cout << output->points[1].x << "," << output->points[1].y << "," << output->points[1].z << std::endl;
42     return (0);
43 }

 

#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>//分割
#include <pcl/filters/voxel_grid.h>//体素格
#include <pcl/filters/extract_indices.h>//提取索引

#include <pcl/visualization/cloud_viewer.h>//点云可视化

int  main(int argc, char** argv)
{
    pcl::PCLPointCloud2::Ptr cloud_blob(new pcl::PCLPointCloud2), cloud_filtered_blob(new pcl::PCLPointCloud2);//申明滤波前后的点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>), 
        cloud_p(new pcl::PointCloud<pcl::PointXYZ>), cloud_f(new pcl::PointCloud<pcl::PointXYZ>);

    // 读取PCD文件
    pcl::PCDReader reader;
    reader.read("../table_scene_lms400.pcd", *cloud_blob);
    //统计滤波前的点云个数
    std::cerr << "PointCloud before filtering: " << cloud_blob->width * cloud_blob->height << " data points." << std::endl;

    // 创建体素栅格下采样: 下采样的大小为1cm
    pcl::VoxelGrid<pcl::PCLPointCloud2> sor;  // 体素栅格下采样对象
    sor.setInputCloud(cloud_blob);           // 原始点云
    sor.setLeafSize(0.01f, 0.01f, 0.01f);    // 设置采样体素大小 1cm*1cm*1cm
    sor.filter(*cloud_filtered_blob);        // 保存

    // 转换为模板点云 PCLPointCloud2 ---> pcl::PointXYZ
    pcl::fromPCLPointCloud2(*cloud_filtered_blob, *cloud_filtered);
    std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height <<
        " data points." << std::endl;
    // 保存下采样后的点云
    pcl::PCDWriter writer;
    writer.write<pcl::PointXYZ>("table_scene_lms400_downsampled.pcd", *cloud_filtered, false);

    // 点云分割
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices());
    pcl::SACSegmentation<pcl::PointXYZ> seg;               //创建分割对象  PCL采样一致性算法分割
    seg.setOptimizeCoefficients(true);                    //设置对估计模型参数进行优化处理

    seg.setModelType(pcl::SACMODEL_PLANE);                //设置分割模型类别  *面
    seg.setMethodType(pcl::SAC_RANSAC);                   //设置用哪个随机参数估计方法
    seg.setMaxIterations(1000);                           //设置最大迭代次数
    seg.setDistanceThreshold(0.01);                       //判断是否为模型内点的距离阀值

    // 设置ExtractIndices的实际参数
    pcl::ExtractIndices<pcl::PointXYZ> extract;            //创建点云提取对象

    int i = 0, nr_points = (int)cloud_filtered->points.size();
    // While 30% of the original cloud is still there
    while (cloud_filtered->points.size() > 0.3 * nr_points)
    {
        // 为了处理点云包含的多个模型,在一个循环中执行该过程并在每次模型被提取后,保存剩余的点进行迭代
        seg.setInputCloud(cloud_filtered);
        seg.segment(*inliers, *coefficients);
        if (inliers->indices.size() == 0)
        {
            std::cerr << "Could not estimate a planar model for the given dataset." << std::endl;
            break;
        }

        // 有索引提取相应的点  Extract the inliers
        extract.setInputCloud(cloud_filtered);
        extract.setIndices(inliers);
        extract.setNegative(false);
        extract.filter(*cloud_p);
        std::cerr << "PointCloud representing the planar component: " <<
            cloud_p->width * cloud_p->height << " data points." << std::endl;

        std::stringstream ss;
        ss << "table_scene_lms400_plane_" << i << ".pcd";//不同的*面
        writer.write<pcl::PointXYZ>(ss.str(), *cloud_p, false);

        // Create the filtering object
        extract.setNegative(true);
        extract.filter(*cloud_f);
        cloud_filtered.swap(cloud_f);
        i++;
    }

    //pcl:: PointCloud < pcl:: PointXYZ > ::Ptr cloud_load(new pcl:: PointCloud<pcl::PointXYZ>);
    //pcl::io::loadPCDFile("./table_scene_lms400_plane_1.pcd", *cloud_load);
    //pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字
    //viewer.showCloud(cloud_load);

    //pcl::PointCloud < pcl::PointXYZ > ::Ptr cloud_load1(new pcl::PointCloud<pcl::PointXYZ>);
    //pcl::io::loadPCDFile("../table_scene_lms400.pcd", *cloud_load1);
    //pcl::visualization::CloudViewer viewer1("pcd viewer1");// 显示窗口的名字
    //viewer1.showCloud(cloud_load1);


    //while (!viewer1.wasStopped())
    //{
    //    // Do nothing but wait.
    //}

    return (0);
}

   

 

 

8.投影滤波器:

 

ProjectInliers

输出投影后的点的坐标,使用参数化模型投影点云如何将点投影到一个参数化模型上(*面或者球体等),

参数化模型通过一组参数来设定,对于*面来说使用其等式形式。在PCL中有特定存储常见模型系数的数据结构。

投影滤波类就是输入点云和投影模型,输出为投影到模型上之后的点云。

 

 1 #include <iostream>
 2 #include <pcl/point_types.h>
 3 //#include <pcl/filters/passthrough.h>
 4 #include <pcl/ModelCoefficients.h>     //模型系数头文件
 5 #include <pcl/filters/project_inliers.h> //投影滤波类头文件
 6 #include <pcl/io/pcd_io.h>               //点云文件pcd 读写
 7 #include <pcl/visualization/cloud_viewer.h>//点云可视化
 8 
 9 // 别名
10 typedef pcl::PointCloud<pcl::PointXYZ>  Cloud;
11 using namespace std;
12 int main(int argc, char** argv)
13 {
14     // 定义 点云对象 指针
15     Cloud::Ptr cloud_ptr(new Cloud());
16     Cloud::Ptr cloud_filtered_ptr(new Cloud());
17     //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
18     //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_ptr (new pcl::PointCloud<pcl::PointXYZ>);
19 
20     // 产生点云数据 
21     cloud_ptr->width = 5;
22     cloud_ptr->height = 1;
23     cloud_ptr->points.resize(cloud_ptr->width * cloud_ptr->height);
24     for (size_t i = 0; i < cloud_ptr->points.size(); ++i)
25     {
26         cloud_ptr->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
27         cloud_ptr->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
28         cloud_ptr->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
29     }
30 
31     std::cerr << "Cloud before filtering投影滤波前: " << std::endl;
32     for (size_t i = 0; i < cloud_ptr->points.size(); ++i)
33         std::cerr << "    " << cloud_ptr->points[i].x << " "
34         << cloud_ptr->points[i].y << " "
35         << cloud_ptr->points[i].z << std::endl;
36 
37     // 填充ModelCoefficients的值,使用ax+by+cz+d=0*面模型,其中 a=b=d=0,c=1 也就是X——Y*面
38     //定义模型系数对象,并填充对应的数据 创建投影滤波模型重会设置模型类型 pcl::SACMODEL_PLANE
39     pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
40     coefficients->values.resize(4);
41     coefficients->values[0] = coefficients->values[1] = 0;
42     coefficients->values[2] = 1.0;
43     coefficients->values[3] = 0;
44 
45     // 创建投影滤波模型ProjectInliers对象,使用ModelCoefficients作为投影对象的模型参数
46     pcl::ProjectInliers<pcl::PointXYZ> proj;    //创建投影滤波对象
47     proj.setModelType(pcl::SACMODEL_PLANE);    //设置对象对应的投影模型  *面模型
48     proj.setInputCloud(cloud_ptr);        //设置输入点云
49     proj.setModelCoefficients(coefficients);    //设置模型对应的系数
50     proj.filter(*cloud_filtered_ptr);        //投影结果存储
51 
52     // 输出滤波后的点云
53     std::cerr << "Cloud after filtering投影滤波后: " << std::endl;
54     for (size_t i = 0; i < cloud_filtered_ptr->points.size(); ++i)
55         std::cerr << "    " << cloud_filtered_ptr->points[i].x << " "
56         << cloud_filtered_ptr->points[i].y << " "
57         << cloud_filtered_ptr->points[i].z << std::endl;
58     // 程序可视化
59     pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字
60     viewer.showCloud(cloud_filtered_ptr);
61     while (!viewer.wasStopped())
62     {
63         // Do nothing but wait.
64     }
65 
66     return (0);
67 }

 

 

 

9.模型滤波器:

ModelOutlierRemoval   根据模型设置条件进行滤波

 1 #include <iostream>
 2 #include <pcl/point_types.h>
 3 #include <pcl/filters/model_outlier_removal.h>
 4 #include <pcl/visualization/cloud_viewer.h>//点云可视化
 5 
 6 int main()
 7 {
 8     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
 9     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_sphere_filtered(new pcl::PointCloud<pcl::PointXYZ>);
10 
11     // 1. Generate cloud data
12     int noise_size = 5;
13     int sphere_data_size = 10;
14     cloud->width = noise_size + sphere_data_size;
15     cloud->height = 1;
16     cloud->points.resize(cloud->width * cloud->height);
17     // 1.1 Add noise
18     for (size_t i = 0; i < noise_size; ++i)
19     {
20         cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
21         cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
22         cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
23     }
24     // 1.2 Add sphere:
25     double rand_x1 = 1;
26     double rand_x2 = 1;
27     for (size_t i = noise_size; i < noise_size + sphere_data_size; ++i)
28     {
29         // See: http://mathworld.wolfram.com/SpherePointPicking.html
30         while (pow(rand_x1, 2) + pow(rand_x2, 2) >= 1)
31         {
32             rand_x1 = (rand() % 100) / (50.0f) - 1;
33             rand_x2 = (rand() % 100) / (50.0f) - 1;
34         }
35         double pre_calc = sqrt(1 - pow(rand_x1, 2) - pow(rand_x2, 2));
36         cloud->points[i].x = 2 * rand_x1 * pre_calc;
37         cloud->points[i].y = 2 * rand_x2 * pre_calc;
38         cloud->points[i].z = 1 - 2 * (pow(rand_x1, 2) + pow(rand_x2, 2));
39         rand_x1 = 1;
40         rand_x2 = 1;
41     }
42 
43     std::cerr << "Cloud before filtering: " << std::endl;
44     for (size_t i = 0; i < cloud->points.size(); ++i)
45         std::cout << "    " << cloud->points[i].x << " " << cloud->points[i].y << " " << cloud->points[i].z << std::endl;
46 
47     // 2. filter sphere:
48     // 2.1 generate model:
49     // modelparameter for this sphere:
50     // position.x: 0, position.y: 0, position.z:0, radius: 1
51     pcl::ModelCoefficients sphere_coeff;
52     sphere_coeff.values.resize(4);
53     sphere_coeff.values[0] = 0;
54     sphere_coeff.values[1] = 0;
55     sphere_coeff.values[2] = 0;
56     sphere_coeff.values[3] = 1;
57 
58     pcl::ModelOutlierRemoval<pcl::PointXYZ> sphere_filter;
59     sphere_filter.setModelCoefficients(sphere_coeff);
60     sphere_filter.setThreshold(0.05);
61     sphere_filter.setModelType(pcl::SACMODEL_SPHERE);
62     sphere_filter.setInputCloud(cloud);
63     sphere_filter.filter(*cloud_sphere_filtered);
64 
65     std::cerr << "Sphere after filtering: " << std::endl;
66     for (size_t i = 0; i < cloud_sphere_filtered->points.size(); ++i)
67         std::cout << "    " << cloud_sphere_filtered->points[i].x << " " << cloud_sphere_filtered->points[i].y << " " << cloud_sphere_filtered->points[i].z
68         << std::endl;
69 
70     //pcl::PointCloud < pcl::PointXYZ > ::Ptr cloud_load1(new pcl::PointCloud<pcl::PointXYZ>);
71     //pcl::io::loadPCDFile("../table_scene_lms400.pcd", *cloud_load1);
72     pcl::visualization::CloudViewer viewer1("pcd viewer1");// 显示窗口的名字
73     viewer1.showCloud(cloud);
74     
75     
76     while (!viewer1.wasStopped())
77     {
78         // Do nothing but wait.
79     }
80 
81     return (0);
82 }

 

标签:PCL,滤波,points,pcl,点云,include,ptr,cloud
From: https://www.cnblogs.com/Jack-Elvis/p/17836466.html

相关文章

  • C# httpClient.PostAsync时出现问题Result =“ {尚未计算}”
    返回错误1:Id=3129,Status=WaitingForActivation,Method="{null}",Result="{Notyetcomputed}"返回错误2:发生了一个或多个错误Oneormoreerrorsoccurred.atSystem.Threading.Tasks.Task.ThrowIfExceptional(BooleanincludeTaskCanceledExceptions)......
  • PCL滤波大全、原理+代码实例+操作步骤
    #include<pcl/filters/passthrough.h>滤波代码实例:1//Createthefilteringobject2pcl::PassThrough<pcl::PointXYZ>pass;//声明直通滤波3pass.setInputCloud(cloud);//传入点云数据4pass.setFilterFieldName("z");......
  • PCL点云读取与保存
     PCL点云读取与保存:1#include<iostream>2#include<string>34#include<pcl/io/io.h>5#include<pcl/io/pcd_io.h>6#include<pcl/point_types.h>7#include<pcl/visualization/pcl_visualizer.h>89usingnamespa......
  • 三维模型的顶层合并构建的点云抽稀关键技术分析
    三维模型的顶层合并构建的点云抽稀关键技术分析 倾斜摄影超大场景的三维模型的顶层合并通常会生成大量的点云数据,这对于后续处理和应用可能会带来一些挑战。为了减少数据存储和处理的复杂性,可以采用点云抽稀处理技术来降低点云密度和数据量。本文将对几种常见的点云抽稀处理技......
  • 基于FPGA的图像中值滤波开发,包括tb测试文件以及matlab验证代码
    算法运行效果图预览   通过MATLAB调用FPGA的仿真结果,显示滤波效果:   2.算法运行软件版本vivado2019.2 matlab2022a 3.算法理论概述         基于FPGA的图像中值滤波是一种在图像处理中常用的滤波技术,其原理是通过一定的算法将图像中的噪声平......
  • 数字滤波器分析---零极点分析
    数字滤波器分析---零极点分析zplane 函数绘制线性系统的极点和零点。例如,在-1/2处为零且在 0.9e−j2π0.3 和 0.9ej2π0.3 处有一对复极点的简单滤波器为zer=-0.5;pol=0.9*exp(j*2*pi*[-0.30.3]');要查看该滤波器的零极点图,您可以使用 zplane。当系统是零极点形式时......
  • 数字滤波器分析---相位响应
    数字滤波器分析---相位响应MATLAB®函数可用于提取滤波器的相位响应。在给定频率响应的情况下,函数 abs 返回幅值,angle 返回以弧度为单位的相位角。要使用 fvtool 查看巴特沃斯滤波器的幅值和相位,请使用:d=designfilt('lowpassiir','FilterOrder',9,...'HalfPowerFrequ......
  • 数字滤波器分析---频率响应
    数字滤波器分析---频率响应幅值、相位、冲激和阶跃响应、相位和群延迟、零极点分析。分析滤波器的频域和时域响应。可视化复平面中的滤波器极点和零点。频率响应数字域freqz 使用基于FFT的算法来计算数字滤波器的Z变换频率响应。具体来说,语句[h,w]=freqz(b,a,p)返回数字滤波......
  • 滤波器实现
    滤波器实现卷积和滤波    滤波的数学基础是卷积。对于有限冲激响应(FIR)滤波器,滤波运算的输出 y(k) 是输入信号 x(k) 与冲激响应 h(k) 的卷积:y(k)=∞∑l=−∞h(l) x(k−l).    如果输入信号也是有限长度的,您可以使用MATLAB® conv 函数来执行滤波运算。......
  • 补偿 FIR 滤波器引入的延迟
    补偿FIR滤波器引入的延迟对信号进行滤波会引入延迟。这意味着相对于输入,输出信号在时间上有所偏移。此示例向您说明如何抵消这种影响。有限冲激响应滤波器经常将所有频率分量延迟相同的时间量。这样,我们就很容易通过对信号进行时移处理来针对延迟进行校正。以500Hz的频率对心......