【PCL】教程bare_earth.cpp使用PCL的渐进形态滤波器来识别和分离地面点(地面、植被、建筑物等)...

使用PCL进行渐进形态滤波器分割地面点云
本文介绍了如何使用C++和PCL库实现ProgressiveMorphologicalFilter进行点云中地面点的分割,通过读取、处理和保存samp11-utm.pcd数据,分离出地面点和非地面点并分别保存到samp11-utm_ground.pcd和samp11-utm_object.pcd文件中。

实现渐进形态过滤器ProgressiveMorphologicalFilter

来分割地面点云

c3b4554c75224533e8c164c12001e086.png

The viewer window provides interactive commands; for help, press 'h' or 'H' from within the window.
> Loading V:\learn\PCL\pcl\examples\test\samp11-utm.pcd [PCLVisualizer::setUseVbos] Has no effect when OpenGL version is 鈮?2
[done, 357.114 ms : 38010 points]
Available dimensions: x y z

原始点云samp11-utm.pcd

44e77c20bbf5985c305f9fe0a06be8cd.png

samp11-utm_ground.pcd

c04ef306696e9934785a92892ce92f7d.png

samp11-utm_object.pcd

终端输出:

Cloud before filtering:
header: seq: 0 stamp: 0 frame_id:


points[]: 38010
width: 38010
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]


Ground cloud after filtering:
header: seq: 0 stamp: 0 frame_id:


points[]: 18667
width: 18667
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]


Object cloud after filtering:
header: seq: 0 stamp: 0 frame_id:


points[]: 19343
width: 19343
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

这段代码是用于处理点云数据的C++程序,主要使用了Point Cloud Library (PCL) Implements the Progressive Morphological Filter for segmentation of ground points.

首先,包含了所需的头文件,这些头文件提供了点云处理和文件I/O等功能。

  1. 在main函数中,首先创建了两个点云对象cloud和cloud_filtered,以及一个用于存储地面索引的ground对象。这些都是指向点云的智能指针。

  2. 使用pcl::PCDReader对象reader从指定文件(这里是"samp11-utm.pcd")中读取点云到cloud对象中。

  3. 然后输出原始点云数据。

  4. 接着实例化一个pcl::ProgressiveMorphologicalFilter<pcl::PointXYZ>对象pmf,把输入点云设置为cloud。这个过滤器用于从点云中分离出地面点。

  5. 对这个滤波器进行参数设置,包括最大窗口尺寸setMaxWindowSize,斜率setSlope,初始距离setInitialDistance和最大距离setMaxDistance。

  6. 通过调用pmf.extract函数,提取地面点索引,并存储在ground对象中

  7. 使用pcl::ExtractIndices<pcl::PointXYZ>对象extract对点云进行索引提取操作。该对象的输入点云被设置为cloud,提取索引被设置为ground,输出点云设置为cloud_filtered。这样就分离了地面点云。

  8. 输出地面点云数据,并通过pcl::PCDWriter对象writer将其写入到"samp11-utm_ground.pcd"文件中。

  9. 通过设置extract的setNegative为true,可以提取非地面点(即地面点以外的其他点)

  10. 再次使用extract.filter方法提取非地面点并保存到cloud_filtered对象中。

  11. 输出非地面点云数据,并保存到"samp11-utm_object.pcd"文件中。

代码的功能如下:

  • 该程序首先从PCD文件中读取点云数据。

  • 使用渐进形态滤波器(Progressive Morphological Filter)分离点云中的地面点。

  • 将地面点和非地面点分别保存到两个不同的PCD文件中。

方法:

使用PCL库的PCD读写功能来处理文件输入输出。

使用PCL的渐进形态滤波器来识别和分离地面点。

使用索引提取方法来获取和存储分离后的地面点和非地面点。

#include <iostream> // 包含标准输入输出流库
#include <pcl/io/pcd_io.h> // 包含PCL的PCD输入输出操作的头文件
#include <pcl/point_types.h> // 包含PCL中点类型定义的头文件
#include <pcl/filters/extract_indices.h> // 包含PCL中根据索引提取点云数据的过滤器的头文件
#include <pcl/segmentation/progressive_morphological_filter.h> // 包含PCL中进行连续形态学滤波的头文件


int
main ()
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);  // 创建一个新的指向PointCloud的指针,用于存储原始点云
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);  // 创建一个新的指向PointCloud的指针,用于存储过滤后的点云
  pcl::PointIndicesPtr ground (new pcl::PointIndices);  // 创建一个新的指向PointIndices的指针,用于存储地面点索引


  // 填充点云数据
  pcl::PCDReader reader;  // 创建一个PCDReader对象,用于读取PCD文件
  // 将下面的路径替换为你保存文件的路径
  reader.read<pcl::PointXYZ> ("samp11-utm.pcd", *cloud);  // 读取PCD文件中的点云数据


  std::cerr << "Cloud before filtering: " << std::endl;  // 输出过滤前的点云信息
  std::cerr << *cloud << std::endl;  // 输出点云数据


  // 创建滤波器对象
  pcl::ProgressiveMorphologicalFilter<pcl::PointXYZ> pmf;  // 创建一个连续形态学滤波器对象
  pmf.setInputCloud (cloud);  // 设置输入点云
  pmf.setMaxWindowSize (20);  // 设置滤波器的最大窗口大小
  pmf.setSlope (1.0f);  // 设置斜率
  pmf.setInitialDistance (0.5f);  // 设置初始距离
  pmf.setMaxDistance (3.0f);  // 设置最大距离
  pmf.extract (ground->indices);  // 提取地面点索引


  // 创建点云提取滤波器对象
  pcl::ExtractIndices<pcl::PointXYZ> extract;  // 创建一个ExtractIndices滤波器对象
  extract.setInputCloud (cloud);  // 设置输入点云
  extract.setIndices (ground);  // 设置要提取的索引
  extract.filter (*cloud_filtered);  // 提取过滤后的点云


  std::cerr << "Ground cloud after filtering: " << std::endl;  // 输出过滤后的地面点云信息
  std::cerr << *cloud_filtered << std::endl;  // 输出地面点云数据


  pcl::PCDWriter writer;  // 创建一个PCDWriter对象
  writer.write<pcl::PointXYZ> ("samp11-utm_ground.pcd", *cloud_filtered, false);  // 写入过滤后的地面点云到PCD文件


  // 提取非地面返回
  extract.setNegative (true);  // 设置提取模式为负向,即提取非指定索引的点
  extract.filter (*cloud_filtered);  // 对点云进行过滤,得到非地面点云


  std::cerr << "Object cloud after filtering: " << std::endl;  // 输出过滤后的非地面点云信息
  std::cerr << *cloud_filtered << std::endl;  // 输出非地面点云数据


  writer.write<pcl::PointXYZ> ("samp11-utm_object.pcd", *cloud_filtered, false);  // 写入过滤后的非地面点云到PCD文件


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

该代码的主要功能是读取一个PCD文件中的三维点云数据,然后使用连续形态学滤波器来识别并分离地面点云和非地面点云。最后,分别将地面点云和非地面点云写入到两个不同的PCD文件中。这在地形分析、机器人导航等领域中有着重要应用。

A complete description of the algorithm can be found in the article “A Progressive Morphological Filter for Removing Nonground Measurements from Airborne LIDAR Data” by K. Zhang, S. Chen, D. Whitman, M. Shyu, J. Yan, and C. Zhang.

pcl::ProgressiveMorphologicalFilter

7f14905750618d0be2f74dd7abdcee9d.png

pcl::ExtractIndices

1eb77cb17c51e32cf8b307a228dbba8d.png

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值