【PCL】教程 supervoxel_clustering执行超体聚类并可视化点云数据及其聚类结果

283b84ee4b86bda667354bac4dc12739.png

[done, 417.125 ms : 307200 points]
Available dimensions: x y z rgba

源点云milk_cartoon_all_small_clorox.pcd

ec9bcf1d875d53a5d2b4874aaff95fef.png

> Loading point cloud...
> Extracting supervoxels!
Found 423 supervoxels
> Getting supervoxel adjacency

这段代码主要是使用PCL(Point Cloud Library)库来执行超体聚类(supervoxel clustering),并将结果显示在3D可视化工具中。现在我分步解释代码中的具体逻辑:

  1. 包含必要的头文件,这些文件用于点云处理和可视化。

  2. 定义使用的点云类型,例如pcl::PointXYZRGBA和pcl::PointNormal

  3. 声明一个函数addSupervoxelConnectionsToViewer用于在视图中添加超体聚类的连接

在main函数中,代码执行如下步骤:

a. 检查命令行参数,确保提供了点云数据文件。
b. 读取点云数据文件,将点云数据载入到PointCloudT类型的智能指针中。
c. 解析命令行参数,根据用户输入设置超体聚类的参数,如体素分辨率、种子分辨率、颜色重要性等
d. 使用pcl::SupervoxelClustering类型创建超体聚类对象,并配置聚类参数。
e. 调用extract方法进行聚类操作,并将聚类结果存储到一个map容器中。
f. 创建一个PCLVisualizer对象用于3D数据的可视化。
g. 将超体聚类的结果添加到可视化对象中,包括体素中心点云和标记的体素云。
h. 计算超体的邻接性,并通过vtkPolyLine来创建和添加显示超体之间连接关系的可视化元素。
i. 启动可视化循环,直到用户关闭3D视图。

最后addSupervoxelConnectionsToViewer函数负责给每一对超体中心和其邻接超体中心之间添加连线,进而在3D视图中形成超体聚类的可视化图。

总结来说,这段代码是一个完整的PCL应用程序,用于执行超体聚类并可视化点云数据及其聚类结果。它可以让用户通过命令行参数来指定不同的聚类参数,并且能够显示每个聚类体素的中心,以及聚类体素之间的连接情况。

#include <pcl/console/parse.h> // 导入PCL库的console模块,用于解析命令行参数
#include <pcl/point_cloud.h> // 导入PCL库的点云处理模块
#include <pcl/point_types.h> // 导入PCL库的点类型定义
#include <pcl/io/pcd_io.h> // 导入PCL库的PCD文件输入输出模块
#include <pcl/visualization/pcl_visualizer.h> // 导入PCL库的可视化模块
#include <pcl/segmentation/supervoxel_clustering.h> // 导入PCL库的SuperVoxel聚类模块//VTK include needed for drawing graph lines
#include <vtkPolyLine.h> // 导入VTK库的PolyLine模块,用于绘制图形线条// Types
typedef pcl::PointXYZRGBA PointT; // 定义PointT为pcl::PointXYZRGBA类型
typedef pcl::PointCloud<PointT> PointCloudT; // 定义PointCloudT为PointT类型的点云
typedef pcl::PointNormal PointNT; // 定义PointNT为点的法线类型
typedef pcl::PointCloud<PointNT> PointNCloudT; // 定义PointNCloudT为PointNT类型的点云
typedef pcl::PointXYZL PointLT; // 定义PointLT为带标签的点类型
typedef pcl::PointCloud<PointLT> PointLCloudT; // 定义PointLCloudT为PointLT类型的点云void addSupervoxelConnectionsToViewer (PointT &supervoxel_center,PointCloudT &adjacent_supervoxel_centers,std::string supervoxel_name,pcl::visualization::PCLVisualizer::Ptr & viewer); // 声明函数addSupervoxelConnectionsToViewer,用于向可视化视图中添加超体连接int
main (int argc, char ** argv) // 主函数
{if (argc < 2) // 检查命令行参数数量是否小于2{pcl::console::print_error ("Syntax is: %s <pcd-file> \n ""--NT Disables the single cloud transform \n""-v <voxel resolution>\n-s <seed resolution>\n""-c <color weight> \n-z <spatial weight> \n""-n <normal_weight>\n", argv[0]); // 打印错误信息和使用说明return (1); // 返回错误代码}PointCloudT::Ptr cloud (new PointCloudT); // 创建一个PointCloudT类型的智能指针pcl::console::print_highlight ("Loading point cloud...\n"); // 打印加载点云的提示信息if (pcl::io::loadPCDFile<PointT> (argv[1], *cloud)) // 加载PCD文件{pcl::console::print_error ("Error loading cloud file!\n"); // 打印加载文件错误信息return (1); // 返回错误代码}bool disable_transform = pcl::console::find_switch (argc, argv, "--NT"); // 查找命令行参数中的`--NT`选项float voxel_resolution = 0.008f; // 设置体素分辨率的默认值bool voxel_res_specified = pcl::console::find_switch (argc, argv, "-v"); // 查找命令行参数中的`-v`选项if (voxel_res_specified) // 如果指定了体素分辨率pcl::console::parse (argc, argv, "-v", voxel_resolution); // 解析体素分辨率的值float seed_resolution = 0.1f; // 设置种子分辨率的默认值bool seed_res_specified = pcl::console::find_switch (argc, argv, "-s"); // 查找命令行参数中的`-s`选项if (seed_res_specified) // 如果指定了种子分辨率pcl::console::parse (argc, argv, "-s", seed_resolution); // 解析种子分辨率的值float color_importance = 0.2f; // 设置颜色重要性的默认值if (pcl::console::find_switch (argc, argv, "-c")) // 查找命令行参数中的`-c`选项pcl::console::parse (argc, argv, "-c", color_importance); // 解析颜色重要性的值float spatial_importance = 0.4f; // 设置空间重要性的默认值if (pcl::console::find_switch (argc, argv, "-z")) // 查找命令行参数中的`-z`选项pcl::console::parse (argc, argv, "-z", spatial_importance); // 解析空间重要性的值float normal_importance = 1.0f; // 设置法线重要性的默认值if (pcl::console::find_switch (argc, argv, "-n")) // 查找命令行参数中的`-n`选项pcl::console::parse (argc, argv, "-n", normal_importance); // 解析法线重要性的值// 以下是使用SuperVoxels的示例代码pcl::SupervoxelClustering<PointT> super (voxel_resolution, seed_resolution); // 创建一个SupervoxelClustering对象if (disable_transform) // 检查是否禁用了单一视角变换super.setUseSingleCameraTransform (false); // 禁用单一视角变换super.setInputCloud (cloud); // 设置输入的点云super.setColorImportance (color_importance); // 设置颜色重要性super.setSpatialImportance (spatial_importance); // 设置空间重要性super.setNormalImportance (normal_importance); // 设置法线重要性std::map <std::uint32_t, pcl::Supervoxel<PointT>::Ptr > supervoxel_clusters; // 创建一个map,用于存储超体聚类的结果pcl::console::print_highlight ("Extracting supervoxels!\n"); // 打印提取超体的提示信息super.extract (supervoxel_clusters); // 提取超体聚类pcl::console::print_info ("Found %d supervoxels\n", supervoxel_clusters.size ()); // 打印找到的超体数量pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); // 创建一个3D可视化视图viewer->setBackgroundColor (0, 0, 0); // 设置背景颜色为黑色PointCloudT::Ptr voxel_centroid_cloud = super.getVoxelCentroidCloud (); // 获取体素中心点云viewer->addPointCloud (voxel_centroid_cloud, "voxel centroids"); // 将体素中心点云添加到可视化视图中viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE,2.0, "voxel centroids"); // 设置点云的点大小viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY,0.95, "voxel centroids"); // 设置点云的透明度PointLCloudT::Ptr labeled_voxel_cloud = super.getLabeledVoxelCloud (); // 获取带标签的体素点云viewer->addPointCloud (labeled_voxel_cloud, "labeled voxels"); // 将带标签的体素点云添加到可视化视图中viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY,0.8, "labeled voxels"); // 设置点云的透明度PointNCloudT::Ptr sv_normal_cloud = super.makeSupervoxelNormalCloud (supervoxel_clusters); // 生成超体法线点云// 下面的代码行被注释掉了,如果需要查看超体法线,请取消注释//viewer->addPointCloudNormals<PointNormal> (sv_normal_cloud,1,0.05f, "supervoxel_normals");pcl::console::print_highlight ("Getting supervoxel adjacency\n"); // 打印获取超体邻接信息的提示信息std::multimap<std::uint32_t, std::uint32_t> supervoxel_adjacency; // 创建一个multimap,用于存储超体邻接信息super.getSupervoxelAdjacency (supervoxel_adjacency); // 获取超体邻接信息// 为了生成超体邻接图,需要遍历超体邻接信息的multimapfor (auto label_itr = supervoxel_adjacency.cbegin (); label_itr != supervoxel_adjacency.cend (); ) // 遍历超体邻接信息{// 首先获取标签std::uint32_t supervoxel_label = label_itr->first;// 然后获取对应标签的超体pcl::Supervoxel<PointT>::Ptr supervoxel = supervoxel_clusters.at (supervoxel_label);// 现在需要遍历邻接的超体,并且创建他们的中心点云PointCloudT adjacent_supervoxel_centers;for (auto adjacent_itr = supervoxel_adjacency.equal_range (supervoxel_label).first; adjacent_itr!=supervoxel_adjacency.equal_range (supervoxel_label).second; ++adjacent_itr) // 遍历邻接的超体{pcl::Supervoxel<PointT>::Ptr neighbor_supervoxel = supervoxel_clusters.at (adjacent_itr->second);adjacent_supervoxel_centers.push_back (neighbor_supervoxel->centroid_); // 将邻接超体的中心点添加到点云中}// 现在为这个多边形创建一个名称std::stringstream ss;ss << "supervoxel_" << supervoxel_label;// 下面的函数在本教程的范围之外,基本上它只是从给定的点生成一个“星型”多边形网格addSupervoxelConnectionsToViewer (supervoxel->centroid_, adjacent_supervoxel_centers, ss.str (), viewer); // 向可视化视图中添加超体连接// 将迭代器向前移动到下一个标签label_itr = supervoxel_adjacency.upper_bound (supervoxel_label);}while (!viewer->wasStopped ()) // 当可视化视图没有被关闭时{viewer->spinOnce (100); // 每100毫秒旋转一次可视化视图}return (0); // 正常退出
}void
addSupervoxelConnectionsToViewer (PointT &supervoxel_center,PointCloudT &adjacent_supervoxel_centers,std::string supervoxel_name,pcl::visualization::PCLVisualizer::Ptr & viewer) // addSupervoxelConnectionsToViewer函数定义
{vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New (); // 创建一个vtkPoints对象vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New (); // 创建一个vtkCellArray对象vtkSmartPointer<vtkPolyLine> polyLine = vtkSmartPointer<vtkPolyLine>::New (); // 创建一个vtkPolyLine对象// 遍历所有邻接点,添加一个中心点到邻接点对for (auto adjacent_itr = adjacent_supervoxel_centers.begin (); adjacent_itr != adjacent_supervoxel_centers.end (); ++adjacent_itr) // 遍历邻接的超体中心点{points->InsertNextPoint (supervoxel_center.data); // 插入中心点points->InsertNextPoint (adjacent_itr->data); // 插入邻接点}// 创建一个polydata来存储一切vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New ();// 将点添加到数据集中polyData->SetPoints (points);polyLine->GetPointIds ()->SetNumberOfIds(points->GetNumberOfPoints ()); // 设置polyLine的点ID数量for(unsigned int i = 0; i < points->GetNumberOfPoints (); i++)polyLine->GetPointIds ()->SetId (i,i); // 为polyLine的每个点设置IDcells->InsertNextCell (polyLine); // 将polyLine添加到cells中// 将线添加到数据集中polyData->SetLines (cells);viewer->addModelFromPolyData (polyData,supervoxel_name); // 将模型从PolyData添加到可视化视图中
}

此代码主要演示了如何使用PCL库进行点云数据的读取、处理和超体聚类分析,以及如何使用VTK库进行可视化展示。代码主要包括点云数据的加载、超体聚类参数设置、超体聚类结果提取和显示,以及超体邻接关系的可视化展示。

pcl::SupervoxelClustering<PointT>super(voxel_resolution, seed_resolution);

2309011e78408db58aa7464b33cd29e6.png

PointCloudT::Ptr voxel_centroid_cloud =super.getVoxelCentroidCloud(); 
PointLCloudT::Ptr labeled_voxel_cloud =super.getLabeledVoxelCloud();
PointNCloudT::Ptr sv_normal_cloud =super.makeSupervoxelNormalCloud(supervoxel_clusters);
super.getSupervoxelAdjacency(supervoxel_adjacency);

8c1ef5d5855e0157909c1303e8175a79.png

超体聚类(supervoxel clustering)

cf39e232637593ad4a11524c6ac48faf.png

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

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

相关文章

【Linux】创建/扩容swap交换空间swap优化

一、当前交换空间大小 目前交换空间大小为2G 二、创建swap交换空间 #创建大小为2G的交换空间 [roothadoop01 data1]# dd if/dev/zero of/data1/swapfile bs1M count2048 #将文件设置为交换空间 [roothadoop01 data1]# mkswap /data1/swapfile #启用交换空间 [roothadoop01 da…

Java Web 开发 - 掌握拦截器和监听器

目录 深入了解Java Web的拦截器和监听器 拦截器&#xff08;Interceptor&#xff09; 拦截器的使用场景 拦截器实例 思维导图 ​编辑 监听器&#xff08;Listener&#xff09; 监听器的使用场景 监听器类型 监听器实例 思维导图​编辑 总结 深入了解Java Web的拦截器…

在UI界面中播放视频_unity基础开发教程

在UI界面中播放视频_unity基础开发教程 前言操作步骤结语 前言 之前我写过一篇在场景中播放视频的文章&#xff0c;但是在开发中有时候也会在UI的界面中播放视频&#xff0c;这期我们做一下在UI的界面中播放视频。 操作步骤 首先在场景中创建一个Raw Image&#xff0c;UI->…

0418EmpTomCat项目 初次使用ajax实现局部动态离职

0418EmpTomCat项目包-CSDN博客 数据库字段&#xff1a; 员工部门表 分页查询&#xff1b; 多条件查询&#xff1b; 添加新员工&#xff1b; ajax点击离职操作效果&#xff1a;

【CTF Web】BUUCTF BUU CODE REVIEW 1 Writeup(代码审计+PHP弱类型漏洞+MD5的0e绕过+反序列化)

BUU CODE REVIEW 1 1 https://github.com/glzjin/buusec_2019_code_review_1 解法 <?php /*** Created by PhpStorm.* User: jinzhao* Date: 2019/10/6* Time: 8:04 PM*/highlight_file(__FILE__);class BUU {public $correct "";public $input ""…

动态数据结构中的表扩张性:摊还分析、伪代码与C语言实现

动态数据结构中的表扩张性&#xff1a;摊还分析、伪代码与C语言实现 引言表扩张性的概念摊还分析在表扩张性中的应用伪代码示例&#xff1a;TABLE-INSERT操作C语言实现结论 引言 在处理数据结构时&#xff0c;尤其是表&#xff08;或数组&#xff09;&#xff0c;我们经常面临…

Idea报错:无法访问org.springframework.boot.SpringApplication

在开发项目时&#xff0c;常常会遇到这种问题&#xff0c;报错信息如下图所示 版本号与jdk版本号存在对应关系&#xff0c;61.0对应jdk17&#xff0c;52.0对应jdk8 所以是某个依赖的版本太高&#xff0c;降低该依赖的版本即可 具体步骤&#xff1a; ①修改pom.xml中spring b…

【linuxC语言】exec函数族

文章目录 前言一、exec函数族二、示例代码2.1 代码12.2 代码22.3 代码3 总结 前言 在Linux环境下&#xff0c;C语言提供了一组强大的函数族&#xff0c;即exec函数族&#xff0c;用于执行其他程序。这些函数允许程序在运行时加载并执行不同的程序&#xff0c;从而实现了程序之…

使用docker部署nacos2.2.3单节点

docker部署nacos2.2.3 首先nacos要配合mysql进行初始化数据&#xff0c;部署一个mysql5.7版本的。 systemctl stop firewalld && setenforce 0 关闭防火墙和selinuxdocker pull mysql:5.7 && docker pull nacos/nacos-server:v2.2.3 拉取镜像docker …

redis中的集群模式

主从复制、主从同步(解决高并发读的问题) 主从同步原理&#xff1a; 1.全量同步 slave&#xff08;从节点&#xff09;每次请求数据同步会带两个参数&#xff1a;replid和offset。 replid&#xff1a;第一次请求同步时&#xff0c;replid和master的replid不一样&#xff0c;这…

探索AI工具的巅峰:个人体验与深度剖析

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

[C++] 类和对象 _ 剖析构造、析构与拷贝

一、构造函数 构造函数是特殊的成员函数&#xff0c;它在创建对象时自动调用。其主要作用是初始化对象的成员变量&#xff08;不是开辟空间&#xff09;。构造函数的名字必须与类名相同&#xff0c;且没有返回类型&#xff08;即使是void也不行&#xff09;。 在C中&#xff0…

【Canvas技法】流星雨的实现

【关键点】 流星的绘制&#xff0c;本质上还是绘制一条直线&#xff0c;但在渲染上有差别。 通常绘制直线都是给的固定颜色&#xff0c;绘制流星给的是渐变色&#xff0c;渐变色的开头是与背景色对比度明显的亮色&#xff0c;结尾是与背景色相同的暗色&#xff0c;中间渐变过…

Vue---router实现路由跳转

Vue—router实现路由跳转 目录 Vue---router实现路由跳转基本使用路由跳转html实现路由跳转JS实现路由跳转 基本使用 所谓路由&#xff0c;就是将一个个组件映射到不同的路由url中 首先要将App内的内容换成router-view // App.vue <template><div id"app"…

区间预测 | PSO-RF-KDE的粒子群优化随机森林结合核密度估计多变量回归区间预测(Matlab)

区间预测 | PSO-RF-KDE的粒子群优化随机森林结合核密度估计多变量回归区间预测&#xff08;Matlab&#xff09; 目录 区间预测 | PSO-RF-KDE的粒子群优化随机森林结合核密度估计多变量回归区间预测&#xff08;Matlab&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基…

巧用 TiCDC Syncpiont 构建银行实时交易和准实时计算一体化架构

本文阐述了某商业银行如何利用 TiCDC Syncpoint 功能&#xff0c;在 TiDB 平台上构建一个既能处理实时交易又能进行准实时计算的一体化架构&#xff0c;用以优化其零售资格业务系统的实践。通过迁移到 TiDB 并巧妙应用 Syncpoint&#xff0c;该银行成功解决了原有多个 MySQL 集…

图搜索算法详解与示例代码

在计算机科学领域&#xff0c;图搜索算法是一类用于在图数据结构中查找特定节点或路径的算法。图搜索算法在许多领域都有着广泛的应用&#xff0c;包括网络路由、社交网络分析、游戏开发等。本文将详细介绍几种常见的图搜索算法&#xff0c;包括深度优先搜索&#xff08;DFS&am…

模方试用版水面修整,调整水岸线功能进程缓慢该怎么解决?

答&#xff1a;水面修整&#xff0c;第一个点选取准确的高程位置和水边&#xff0c;其他点就可以包含整个水面范围就行&#xff0c;可以绘制大一些。上图绘制区域没有包含到所有的水面&#xff0c;可以尝试下图的红线绘制区域。 模方是一款针对实景三维模型的冗余碎片、水面残缺…

【Spring 】Spring MVC 入门Ⅱ

Spring MVC 入门Ⅱ 一、接收Cookie / Session 这两者都是用来保存用户信息的&#xff0c;但不同的是&#xff1a; Cookie存在客户端 Session存在服务器 Session产生时会生成一个唯一性的SessionID&#xff0c;这个SessionID可以用于匹配Session和Cookie SessionID可以在Cooki…

模型训练中的过拟合和欠拟合

基本概念 我们知道&#xff0c;所谓的神经网络其实就是一个复杂的非线性函数&#xff0c;网络越深&#xff0c;这个函数就越复杂&#xff0c;相应的表达能力也就越强&#xff0c;神经网络的训练则是一个拟合的过程。   当模型的复杂度小于真实数据的复杂度&#xff0c;模型表…