Ubuntu 20.04.06 PCL C++学习记录(二十五)

@[TOC]PCL中点云分割模块的学习

学习背景

参考书籍:《点云库PCL从入门到精通》以及官方代码PCL官方代码链接,,PCL版本为1.10.0,CMake版本为3.16,可用点云下载地址

学习内容

使用渐进形态滤波器分割识别地面回波,即执行渐进形态滤波器对地面点进行分割。本文所用点云地址

源代码及所用函数

源代码

cpp 复制代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/extract_indices.h>//提供一个名为 pcl::ExtractIndices 的滤波器类,用于根据一组给定的索引从点云中提取出一部分点。
#include<pcl/segmentation/progressive_morphological_filter.h>//提供渐进式形态学滤波器 (Progressive Morphological Filter) 的实现,用于从点云数据中分割出地面点。

int main()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointIndicesPtr ground(new pcl::PointIndices);
    /************************************************加载PCD文件********************************************/
    pcl::PCDReader reader;
    reader.read<pcl::PointXYZ>("/home/jojo/PointCloud/samp11-utm.pcd",*cloud);
    //将读取的点云打印出来
    // 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);//将分割出的地面点的索引存储到ground->indices中。
    /*************************************************创建过滤对象**************************************/
    pcl::ExtractIndices<pcl::PointXYZ> extract;
    extract.setInputCloud (cloud);
    extract.setIndices (ground);
    extract.filter (*cloud_filtered);//将提取出的地面点存储到cloud_filtered中。
    //将滤波后的点云打印出来
    // std::cerr << "Ground cloud after filtering: " << std::endl;
    // std::cerr << *cloud_filtered << std::endl;
    pcl::PCDWriter writer;
    writer.write<pcl::PointXYZ> ("samp11-utm_ground.pcd", *cloud_filtered, false);
    /***********************************************获取非地面的点云***********************************/
    extract.setNegative (true);
    extract.filter (*cloud_filtered);
    writer.write<pcl::PointXYZ> ("samp11-utm_object.pcd", *cloud_filtered, false);

    return 0;
}

CMakeLists.txt

cpp 复制代码
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)#指定CMake的最低版本要求为3.16
project(project)#设置项目名称
find_package(PCL 1.10 REQUIRED)#查找PCL库,要求版本为1.10或更高。
include_directories(${PCL_INCLUDE_DIRS})#将PCL库的头文件目录添加到包含路径中
link_directories(${PCL_LIBRARY_DIRS})#将PCL库的库文件目录添加到链接器搜索路径中。
add_definitions(${PCL_DEFINITIONS})#添加PCL库的编译器定义
add_executable (bare_earth bare_earth.cpp)
target_link_libraries (bare_earth ${PCL_LIBRARIES})#将PCL库链接到可执行文件目标。

运行结果

地面点云

cpp 复制代码
pcl_viewer samp11-utm_ground.pcd

非地面点云

cpp 复制代码
pcl_viewer samp11-utm_object.pcd

函数

  • pcl::ProgressiveMorphologicalFilter<pcl::PointXYZ>是PCL库中用于地面分割的一种滤波器类。它基于形态学操作(morphological operations)的思想,通过逐步增加窗口大小来识别地面点。

    该滤波器的工作原理如下:

    首先,它使用一个较小的窗口在点云中滑动,计算每个点的最大高度差。如果高度差小于设置的斜率(slope)阈值,则认为这些点属于地面。

    然后,它逐步增大窗口大小,重复上述过程,直到窗口大小达到设置的最大值。

    通过这种逐步增大窗口大小的方式,滤波器可以逐步识别出更大范围内的地面点。

    在使用这个滤波器之前,需要设置以下几个重要参数:

      setMaxWindowSize(int):设置窗口的最大大小。
      setSlope(float):设置识别地面的最大斜率阈值。
      setInitialDistance(float):设置初始窗口的大小。
      setMaxDistance(float):设置窗口增长的最大距离。
    
  • extract.setNegative(true)的作用是设置pcl::ExtractIndices对象的negative标志为true,表示提取点云中不在给定索引集合中的点。

    当negative标志设置为false(默认值)时,pcl::ExtractIndices会提取出与给定索引集合对应的点,并将其存储到输出点云中。

    当negative标志设置为true时,pcl::ExtractIndices会提取出不在给定索引集合中的点,并将其存储到输出点云中。

补充内容

相关推荐
OopspoO16 分钟前
qcow2镜像大小压缩
学习·性能优化
东风吹柳31 分钟前
观察者模式(sigslot in C++)
c++·观察者模式·信号槽·sigslot
A懿轩A39 分钟前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
居居飒1 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
YRr YRr1 小时前
解决Ubuntu 20.04上编译OpenCV 3.2时遇到的stdlib.h缺失错误
linux·opencv·ubuntu
认真学习的小雅兰.1 小时前
如何在Ubuntu上利用Docker和Cpolar实现Excalidraw公网访问高效绘图——“cpolar内网穿透”
linux·ubuntu·docker
kkflash31 小时前
提升专业素养的实用指南
学习·职场和发展
大胆飞猪2 小时前
C++9--前置++和后置++重载,const,日期类的实现(对前几篇知识点的应用)
c++
1 9 J2 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
夕泠爱吃糖2 小时前
C++中如何实现序列化和反序列化?
服务器·数据库·c++