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

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

学习背景

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

学习内容

源代码及所用函数

源代码

cpp 复制代码
#include<iostream>
#include<vector>
#include<pcl/point_types.h>
#include<pcl/io/pcd_io.h>
#include<pcl/search/search.h>
#include<pcl/search/kdtree.h>
#include<pcl/features/normal_3d.h>
#include<pcl/visualization/cloud_viewer.h>
#include<pcl/filters/filter_indices.h>
#include<pcl/segmentation/region_growing.h>

int main(int argc,char** argv)
{
    /*********************************读取点云文件**************************************************/
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile("/home/jojo/PointCloud/table_400.pcd",*cloud) == -1)
    {
        std::cout << "没有找到文件" << std::endl;
        return -1;
    }
    /*****************************************计算表面法线****************************************/
    pcl::search::Search<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
    pcl::NormalEstimation<pcl::PointXYZ,pcl::Normal> normal_estimator;
    normal_estimator.setSearchMethod(tree);
    normal_estimator.setInputCloud(cloud);
    normal_estimator.setKSearch(50);
    normal_estimator.compute(*normals);
    /******************************************从点云数据中移除 NaN 值*****************************/
    pcl::IndicesPtr indices(new std::vector<int>);
    pcl::removeNaNFromPointCloud(*cloud,*indices);
    /*******************************************设置区域生长算法**********************************/
    pcl::RegionGrowing<pcl::PointXYZ,pcl::Normal> reg;
    reg.setMinClusterSize(50);//设置最小簇的大小。
    reg.setMaxClusterSize(1000000);//设置最大簇的大小。
    reg.setSearchMethod(tree);//设置搜索方法    
    reg.setNumberOfNeighbours(30);//设置邻域点的数量。
    reg.setInputCloud(cloud);//设置输入点云。
    reg.setIndices(indices);//设置点云索引,指定要处理的点云子集
    reg.setInputNormals (normals);//设置输入点云的法向量
    reg.setSmoothnessThreshold(3.0/180.0*M_PI);//设置平滑度阈值,3.0 表示角度阈值为3度
    reg.setCurvatureThreshold(1.0);//设置曲率阈值

    std::vector<pcl::PointIndices> clusters;
    reg.extract(clusters);

    std::cout << "群集数等于" << clusters.size() << std::endl;
    std::cout << "第一个集群有 " << clusters[0].indices.size () << " 个点." << std::endl;
    std::cout << "这些是初始这些是初始点的指数" <<std::endl << "属于第一个群组的云:" <<std::endl;
    std::size_t counter = 0;
    while (counter < clusters[0].indices.size())
    {
        std::cout << clusters[0].indices[counter] << ", ";
        counter++;
        if (counter%10==0)
        {
            std::cout << std::endl;
        }
    }
    std::cout << std::endl;
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud();
    pcl::visualization::CloudViewer viewer("Cluster Viewer");
    viewer.showCloud(colored_cloud);
    while(!viewer.wasStopped())
    {

    }
    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 (region_growing_segmentation region_growing_segmentation.cpp)
target_link_libraries (region_growing_segmentation ${PCL_LIBRARIES})#将PCL库链接到可执行文件目标。

运行结果

函数

  • pcl::RegionGrowing 是 PCL 库中提供的一种区域生长分割算法,它根据点云的几何特征(如法向量、曲率等)将点云分割成不同的区域。

      pcl::PointXYZ:指定输入点云的类型为 pcl::PointXYZ,表示每个点包含 XYZ 坐标信息。
      pcl::Normal:指定点云的法向量类型为 pcl::Normal,表示每个点的法向量信息。
      
      setInputCloud:设置输入点云。
      setInputNormals:设置输入点云的法向量。
      setSearchMethod:设置搜索方法(如 KdTree)。
      setNumberOfNeighbours:设置邻域点的数量。
      setMinClusterSize:设置最小簇的大小。
      setMaxClusterSize:设置最大簇的大小。
      setSmoothnessThreshold:设置平滑度阈值。
      setCurvatureThreshold:设置曲率阈值。
    
  • reg.getColoredCloud()pcl::RegionGrowing 类的一个成员函数,它返回一个彩色点云。在 pcl::RegionGrowing 算法执行后,不同的区域会被赋予不同的伪随机颜色,以区分不同的簇或分割区域。

补充内容

  • pcl::search::Searchpcl::PointXYZ::Ptrpcl::search::KdTreepcl::PointXYZ::Ptr 区别

    1. pcl::search::Search<pcl::PointXYZ>::Ptr 是一个抽象基类指针,它定义了一组用于搜索点云数据的通用接口。这个基类本身不提供任何具体的实现,而是作为一个通用接口,允许其他具体的搜索算法类继承并实现它。
    2. pcl::search::KdTree<pcl::PointXYZ>::Ptr 是一个具体的搜索算法类指针,它实现了基于 K-D 树数据结构的搜索算法。K-D 树是一种用于存储和查找多维数据的树状数据结构,它能够高效地进行最近邻搜索和范围搜索等操作。

    简单来说,pcl::search::Search<pcl::PointXYZ>::Ptr 是一个通用的搜索接口,pcl::search::KdTree<pcl::PointXYZ>::Ptr 则是一种基于 K-D 树的具体搜索算法实现

相关推荐
_GR10 分钟前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划
蜡笔小新星11 分钟前
Python Kivy库学习路线
开发语言·网络·经验分享·python·学习
攸攸太上25 分钟前
JMeter学习
java·后端·学习·jmeter·微服务
Death20029 分钟前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
六点半88830 分钟前
【C++】速通涉及 “vector” 的经典OJ编程题
开发语言·c++·算法·青少年编程·推荐算法
Ljubim.te1 小时前
Linux基于CentOS学习【进程状态】【进程优先级】【调度与切换】【进程挂起】【进程饥饿】
linux·学习·centos
coduck_S12004zbj1 小时前
csp-j模拟五补题报告
c++·算法·图论
Death2001 小时前
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
c语言·c++·qt·3d·c#
yngsqq1 小时前
031集——文本文件按空格分行——C#学习笔记
笔记·学习·c#
sukalot1 小时前
windows C++-windows C++-使用任务和 XML HTTP 请求进行连接(二)
c++·windows