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

news2024/11/28 22:55:18

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

学习背景

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

学习内容

PCL中实现欧式聚类提取。在点云处理中,聚类是一种常见的任务,它将点云数据划分为多个独立的簇或集群。每个簇代表点云中的一个独立物体或区域。聚类可以帮助我们从复杂的点云场景中识别出单独的物体,为后续的物体识别、分类和其他处理任务奠定基础。

源代码及所用函数

源代码

#include<pcl/ModelCoefficients.h>//定义名为 pcl::ModelCoefficients 的类,用于存储模型的系数
#include<pcl/point_types.h>
#include<pcl/io/pcd_io.h>
#include<pcl/filters/extract_indices.h>
#include<pcl/filters/voxel_grid.h>
#include<pcl/kdtree/kdtree.h>
#include<pcl/sample_consensus/method_types.h>//随机参数估计方法头文件
#include<pcl/sample_consensus/model_types.h>//定义 PCL 中用于随机采样一致性 (SAC) 方法的枚举类型
#include<pcl/segmentation/sac_segmentation.h>//提供 PCL 中用于基于随机采样一致性 (SAC) 方法进行点云分割的类和函数
#include<pcl/segmentation/extract_clusters.h>//包含 PCL (Point Cloud Library) 中用于点云聚类的头文件

/******************************************************************************
 打开点云数据,并对点云进行滤波重采样预处理,然后采用平面分割模型对点云进行分割处理
 提取出点云中所有在平面上的点集,并将其存盘
******************************************************************************/
int main(int argc,char** argv)
{
    /*********************************************************读取点云数据***************************/
    pcl::PCDReader reader;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    reader.read("/home/jojo/PointCloud/table_400.pcd",*cloud);
    std::cout << "滤波之前有" << cloud->points.size() << "个点" << std::endl;
    /*************************************创建过滤对象:使用 1 厘米大小的叶片对数据集进行下采样************/
    //使用体素化网格方法实现下采样,即减少点的数量 减少点云数据,并同时保存点云的形状特征   
    pcl::VoxelGrid<pcl::PointXYZ> vg;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_f(new pcl::PointCloud<pcl::PointXYZ>);
    vg.setInputCloud(cloud);//设置需要过滤的点云给滤波对象
    vg.setLeafSize(0.01f,0.01f,0.01f);//设置滤波时创建的体素体积为1cm的立方体
    vg.filter(*cloud_filtered); //执行滤波处理,存储输出
    std::cout << "滤波之后有" << cloud_filtered->points.size() << "个点" << std::endl;
    /****************************创建平面模型分割的对象并设置参数************************************/
    pcl::SACSegmentation<pcl::PointXYZ> seg;
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane(new pcl::PointCloud<pcl::PointXYZ>());
    pcl::PCDWriter writer;
    seg.setOptimizeCoefficients(true);
    seg.setModelType(pcl::SACMODEL_PLANE);//分割模型
    seg.setMethodType(pcl::SAC_RANSAC);//随机参数估计方法
    seg.setMaxIterations(100);//最大的迭代次数
    seg.setDistanceThreshold(0.02);//设置阈值

    int i = 0,nr_points = (int)cloud_filtered->points.size();
    while (cloud_filtered->points.size() > 0.3 * nr_points)
    {
        /**********************************从剩余云中分离出最大的平面***************************/
        seg.setInputCloud(cloud_filtered);
        seg.segment(*inliers,*coefficients);
        if(inliers->indices.size() == 0)
        {
            std::cout << "找不到平面对象" << std::endl;
            break;
        }
        pcl::ExtractIndices<pcl::PointXYZ> extract;
        extract.setInputCloud(cloud_filtered);
        extract.setIndices(inliers);
        extract.setNegative(false);
        /********************************获取与平面相关的点**********************************/
        extract.filter(*cloud_plane);
        std::cout << "代表平面组件的点云有:" << cloud_plane->points.size() << "个" << std::endl;
        /******************************移去平面局内点,提取剩余点云****************************/
        extract.setNegative(true);
        extract.filter(*cloud_f);
        *cloud_filtered = *cloud_f;
    }
    /******************************创建KD树对象****************************************/
    pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
    kdtree->setInputCloud(cloud_filtered);

    std::vector<pcl::PointIndices> cluster_indices;
    pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;//欧式聚类对象
    ec.setClusterTolerance(0.02);// 设置近邻搜索的搜索半径为2cm
    ec.setMinClusterSize(100);//设置一个聚类需要的最少的点数目为100
    ec.setMaxClusterSize(25000);//设置一个聚类需要的最大点数目为25000
    ec.setSearchMethod(kdtree);//设置点云的搜索机制
    ec.setInputCloud(cloud_filtered);
    ec.extract(cluster_indices);//从点云中提取聚类,并将点云索引保存在cluster_indices中
    //迭代访问点云索引cluster_indices,直到分割处所有聚类
    int j = 0;
    for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin();it != cluster_indices.end();++it)
    {
        pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);
        for (std::vector<int>::const_iterator pit = it->indices.begin();pit != it->indices.end();pit++)
        {
            cloud_cluster->points.push_back(cloud_filtered->points[*pit]);
        }
        cloud_cluster->width = cloud_cluster->points.size();
        cloud_cluster->height = 1;
        cloud_cluster->is_dense = true;
        std::cout << "代表集群的点云:" << cloud_cluster->points.size() << "个" << std::endl;
        std::stringstream ss;
        ss << "cloud_cluster_" << j << ".pcd";
        writer.write<pcl::PointXYZ>(ss.str(),*cloud_cluster,false);
        j++;
        
    }
    return 0;
    
}

CMakeLists.txt

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

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

函数

  • pcl/segmentation/extract_clusters.h包含 PCL (Point Cloud Library) 中用于点云聚类的头文件

补充内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1576734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Microbiome|北京林业大学生物多样性研究团队揭示土壤原核生物群落在推动亚热带森林植物多样性与生产力关系中的重要作用

生物多样性与生态系统功能&#xff08;BEF&#xff09;之间的关系是生态研究的重要课题之一。土壤微生物群落的变化可能是调节这种关系的关键因素之一。关于森林中真菌群落对树木多样性-生产力关系的影响&#xff0c;已有大量研究。然而&#xff0c;对于细菌和古细菌&#xff0…

第四届计算机、物联网与控制工程国际学术会议(CITCE 2024)

先投稿&#xff0c;先送审&#xff0c;先录用&#xff01;快至投稿后三天录用&#xff01; 第四届计算机、物联网与控制工程国际学术会议&#xff08;CITCE 2024) The 4th International Conference on Computer, Internet of Things and Control Engineering&#xff08;CITCE…

exe签名证书

我们需要明白什么是exe签名证书&#xff1f;exe签名证书是一种数字证书&#xff0c;用于对可执行文件&#xff08;即.exe文件&#xff09;进行数字签名。这种签名可以确保软件的完整性和来源&#xff0c;防止软件被恶意篡改。同时&#xff0c;它也提供了一种机制&#xff0c;使…

THREE.JS 数据纹理简明教程

我一直在研究从 Three.js 中的数据创建纹理。 这非常简单&#xff0c;但有一些注意事项&#xff0c;有些部分可能会令人困惑。 很多年前我曾陷入过一些陷阱&#xff0c;最近又再次陷入其中&#xff0c;所以我决定写下来&#xff01; NSDT工具推荐&#xff1a; Three.js AI纹理开…

通过自动化部署消除人为操作:不断提高提交部署比率

三十年后&#xff0c;我仍然热爱成为一名软件工程师。事实上&#xff0c;我最近读了威尔拉森&#xff08;Will Larson&#xff09;的《员工工程师&#xff1a;超越管理轨道的领导力》&#xff0c;这进一步点燃了我以编程方式解决复杂问题的热情。知道雇主继续照顾员工、原则和杰…

222,完全二叉树的节点数

给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都达到最大值&#xff0c;并且最下面一层的节点都集中在该层最左边的若干位置。若最…

2024/4/2—力扣—二叉树的最近公共祖先

代码实现&#xff1a; 思路&#xff1a; 递归判断左子树和右子树&#xff0c;查找p或者q是否在当前节点的子树上 1&#xff0c;在同一子树上&#xff0c;同一左子树&#xff0c;返回第一个找到的相同值&#xff0c;同一右子树上&#xff0c;返回第一个找到的相同值 2&#xff0…

ES学习日记(十一)-------Java操作ES之基本操作

前言 此篇博客还是一些基础操作&#xff0c;没什么可写的&#xff0c;需要的同学直接抄作业进行测试就可以 上一节写了连接和测试新增操作,这一节写java操作ES的基本操作,也就是增删改查,在这里补充一点知识,我们之前用了指定的索引进行指定添加 有一个情况是,如果我们指定了…

git提交代码时报错,提不了

问题 今天在换了新电脑&#xff0c;提交代码时报错 ✖ eslint --fix found some errors. Please fix them and try committing again. ✖ 21 problems (20 errors, 1 warning) husky > pre-commit hook failed (add --no-verify to bypass) 解决 通过 --no-verify 解决&…

✌2024/4/3—力扣—最长回文子串

代码实现&#xff1a; 解法一&#xff1a;动态规划——回文子串 char* longestPalindrome(char *s) {int n strlen(s);if (s NULL || n 0 || n 1) {return s;}int dp[n][n];memset(dp, 0, sizeof(dp));for (int i n - 1; i > 0; i--) { // 从下到上for (int j i; j &l…

C语言面试题之判定字符是否唯一

判定字符是否唯一 实例要求 实现一个算法&#xff0c;确定一个字符串 s 的所有字符是否全都不同 实例分析 1、使用一个大小为 256 的bool数组 charSet 来记录字符是否出现过&#xff1b;2、遍历字符串时&#xff0c;如果字符已经在数组中标记过&#xff0c;则返回 false&a…

SpringCloud Alibaba Sentinel 创建流控规则

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第十四篇&#xff0c;即介绍 SpringCloud Alibaba Sentinel 创建流控规则。 二、基本介绍 我们在 senti…

腾讯视频号新玩法,有人已经“遥遥领先”了~

我是王路飞。 抖音的流量红利让用户看到了新的变现方式。 短视频、开直播、开店铺卖货、图文带货等等&#xff0c;都是依托于抖音这个平台去发展起来的。 而抖音的巨大成功&#xff0c;被吸引到的还有互联网行业巨头&#xff0c;比如腾讯。 而腾讯视频号的上线就表明了&…

智能网联汽车自动驾驶数据记录系统DSSAD数据元素

目录 第一章 数据元素分级 第二章 数据元素分类 第三章 数据元素基本信息表 表1 车辆及自动驾驶数据记录系统基本信息 表2 车辆状态及动态信息 表3 自动驾驶系统运行信息 表4 行车环境信息 表5 驾驶员操作及状态信息 第一章 数据元素分级 自动驾驶数据记录系统记录的数…

git Failed to connect to 你的网址 port 8282: Timed out

git Failed to connect to 你的网址 port 8282: Timed out 出现这个问题的原因是&#xff1a;原来的仓库换了网址&#xff0c;原版网址不可用了。 解决方法如下&#xff1a; 方法一&#xff1a;查看git用户配置是否有如下配置 http.proxyhttp://xxx https.proxyhttp://xxx如果…

DIY可视化UniApp表格组件

表格组件在移动端的用处非常广泛&#xff0c;特别是在那些需要展示结构化数据、进行比较分析或提供详细信息的场景中。数据展示与整理&#xff1a;表格是展示结构化数据的理想方式&#xff0c;特别是在需要展示多列和多行数据时。通过表格&#xff0c;用户可以轻松浏览和理解数…

2024新版PHP在线客服系统多商户AI智能在线客服系统源码机器人自动回复即时通讯聊天系统源码PC+H5

搭建环境&#xff1a; 服务器 CPU 2核心 ↑ 运存 2G ↑ 宽带 5M ↑ 服务器操作系统 Linux Centos7.6-7.9 ↑ 运行环境&#xff1a; 宝塔面板 Nginx1.18- 1.22 PHP 7.1-7.3 MYSQL 5.6 -5.7 朵米客服系统是一款全功能的客户服务解决方案&#xff0c;提供多渠道支持…

深度学习理论基础(七)Transformer编码器和解码器

学习目录&#xff1a; 深度学习理论基础&#xff08;一&#xff09;Python及Torch基础篇 深度学习理论基础&#xff08;二&#xff09;深度神经网络DNN 深度学习理论基础&#xff08;三&#xff09;封装数据集及手写数字识别 深度学习理论基础&#xff08;四&#xff09;Parse…

能不能换DB吗?--抽象工厂模式

1.1 就不能不换DB吗&#xff1f; 都是换数据库惹的祸。 "我们团队前段时间用.net的C#来开发好一个项目&#xff0c;是给一家企业做的电子商务网站&#xff0c;是用SQL Server作为数据库的&#xff0c;应该说上线后除了开始有些小问题&#xff0c;基本都还可以。而后&#…

婴儿洗衣机买几公斤的合适?四大黑马婴儿洗衣机强势来袭

选择适合婴儿使用的洗衣机&#xff0c;是每个家长都关心的问题。在选择的时候&#xff0c;我们需要考虑一些因素&#xff0c;比如安全性、易操作性和洗涤效果等。同时&#xff0c;也要根据婴儿的年龄和需求来选择合适的洗衣机。婴儿洗衣机的出现&#xff0c;为宝妈们带来了极大…