【PCL】(二十八)点云超体素分割

(二十九)点云超体素分割

论文:Voxel Cloud Connectivity Segmentation - Supervoxels for Point Clouds

supervoxel_clustering.cpp

#include <pcl/console/parse.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/segmentation/supervoxel_clustering.h>

//VTK include needed for drawing graph lines
#include <vtkPolyLine.h>

// Types
typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud<PointT> PointCloudT;
typedef pcl::PointNormal PointNT;
typedef pcl::PointCloud<PointNT> PointNCloudT;
typedef pcl::PointXYZL PointLT;
typedef pcl::PointCloud<PointLT> PointLCloudT;

void addSupervoxelConnectionsToViewer (PointT &supervoxel_center,
                                       PointCloudT &adjacent_supervoxel_centers,
                                       std::string supervoxel_name,
                                       pcl::visualization::PCLVisualizer::Ptr & viewer);


int main (int argc, char ** argv)
{
      if (argc < 2)
      {
            pcl::console::print_error ("Syntax is: %s <pcd-file> \n "
                                          "--NT Dsables 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);
      pcl::console::print_highlight ("Loading point cloud...\n");
      if (pcl::io::loadPCDFile<PointT> (argv[1], *cloud))
      {
            pcl::console::print_error ("Error loading cloud file!\n");
            return (1);
      }
     /*
      --NT禁用单视图变换(仅影响有组织云)
      -v设置体素大小,决定基础八叉树结构的叶大小(以米为单位)
      -s设置种子大小,决定超体素的大小(以米为单位)
      -c设置颜色影响超体素的形状的权重
      -z设置空间项的权重-值越高,超体素越规则
      -n设置曲面法线影响超体素的形状的权重
      */

      bool disable_transform = pcl::console::find_switch (argc, argv, "--NT");

      float voxel_resolution = 0.008f;
      bool voxel_res_specified = pcl::console::find_switch (argc, argv, "-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");
      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"))
            pcl::console::parse (argc, argv, "-c", color_importance);

      float spatial_importance = 0.4f;
      if (pcl::console::find_switch (argc, argv, "-z"))
            pcl::console::parse (argc, argv, "-z", spatial_importance);

      float normal_importance = 1.0f;
      if (pcl::console::find_switch (argc, argv, "-n"))
            pcl::console::parse (argc, argv, "-n", normal_importance);


 


      // 超体素聚类
      pcl::SupervoxelClustering<PointT> super (voxel_resolution, seed_resolution);
      if (disable_transform) // 如果收入是有组织的云,而该云的相机坐标不在(0,0,0)且深度不在正Z,则必须将use_transform设置为false
            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;

      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"));
      viewer->setBackgroundColor (0, 0, 0);
      // voxel_centroid_cloud包含由体素质心组成的云
      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");
      //labeled_voxel_cloud 是根据其超体素标签(随机颜色)着色的体素。
      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");
      // sv_normal_cloud包含一个超体素法线云,
      PointNCloudT::Ptr sv_normal_cloud = super.makeSupervoxelNormalCloud (supervoxel_clusters);
      //We have this disabled so graph is easy to see, uncomment to see supervoxel normals
      //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;
      super.getSupervoxelAdjacency (supervoxel_adjacency);
      //To make a graph of the supervoxel adjacency, we need to iterate through the supervoxel adjacency multimap
      for (auto label_itr = supervoxel_adjacency.cbegin (); label_itr != supervoxel_adjacency.cend (); )
      {
            //First get the label  
            std::uint32_t supervoxel_label = label_itr->first;
            //Now get the supervoxel corresponding to the label
            pcl::Supervoxel<PointT>::Ptr supervoxel = supervoxel_clusters.at (supervoxel_label);

            //Now we need to iterate through the adjacent supervoxels and make a point cloud of them
            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_);
            }
            //Now we make a name for this polygon
            std::stringstream ss;
            ss << "supervoxel_" << supervoxel_label;
            //This function is shown below, but is beyond the scope of this tutorial - basically it just generates a "star" polygon mesh from the points given
            addSupervoxelConnectionsToViewer (supervoxel->centroid_, adjacent_supervoxel_centers, ss.str (), viewer);
            //Move iterator forward to next label
            label_itr = supervoxel_adjacency.upper_bound (supervoxel_label);
      }

      while (!viewer->wasStopped ())
      {
            viewer->spinOnce (100);
      }
      return (0);
      }

void  addSupervoxelConnectionsToViewer (PointT &supervoxel_center,PointCloudT &adjacent_supervoxel_centers,
                               std::string supervoxel_name,pcl::visualization::PCLVisualizer::Ptr & viewer)
{
      vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New ();
      vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New ();
      vtkSmartPointer<vtkPolyLine> polyLine = vtkSmartPointer<vtkPolyLine>::New ();

      //Iterate through all adjacent points, and add a center point to adjacent point pair
      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);
      }
      // Create a polydata to store everything in
      vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New ();
      // Add the points to the dataset
      polyData->SetPoints (points);
      polyLine->GetPointIds  ()->SetNumberOfIds(points->GetNumberOfPoints ());
      for(unsigned int i = 0; i < points->GetNumberOfPoints (); i++)
      polyLine->GetPointIds ()->SetId (i,i);
      cells->InsertNextCell (polyLine);
      // Add the lines to the dataset
      polyData->SetLines (cells);
      viewer->addModelFromPolyData (polyData,supervoxel_name);
}

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(supervoxel_clustering)

find_package(PCL 1.8 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (supervoxel_clustering supervoxel_clustering.cpp)
target_link_libraries (supervoxel_clustering ${PCL_LIBRARIES})

数据样例

编译并运行:

./supervoxel_clustering milk_cartoon_all_small_clorox.pcd --NT -s 0.47

在这里插入图片描述

./supervoxel_clustering milk_cartoon_all_small_clorox.pcd --NT -s 0.1

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

后端使用Long类型数据,前后端传值,主键精度丢失

场景描述 在使用Long类型数据时&#xff0c;根据id获取对象&#xff0c;然后传递到前端&#xff0c;后端获取数据是正常的&#xff0c;但是传递到前端会发生精度丢失。 1). 数据表存在一条数据&#xff0c;以雪花算法作为主键 2). 编写Controller&#xff0c;接受get请求&…

android HAL层崩溃排查记录

要最近在调试系统HDMI CEC功能时&#xff0c;遇到一个奇怪的崩溃问题&#xff0c;这边记录下。 初步分析 先上日志&#xff1a; --------- beginning of crash 03-06 10:48:25.503 1133 1133 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** **…

探索数据可视化:Matplotlib 高级绘图功能(四)

3D图形 线形图&散点图 import numpy as np import matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d.axes3d import Axes3Dx np.linspace(0,60,300) y np.sin(x) z np.cos(x)fig plt.figure(figsize(9,6)) a3 Axes3D(fig) # 二维变成3D a3.plot(x,y,z)plt.figure…

对比学习(Contrastive Learning)和孪生网络(Siamese Network)的区别!

对比学习&#xff08;Contrastive Learning&#xff09;和孪生网络&#xff08;Siamese Network&#xff09;是两种常见的无监督学习方法&#xff0c;它们有着不同的原理和应用场景。 原理与目标&#xff1a; 对比学习旨在通过最小化相似样本对之间的距离&#xff0c;最大化不相…

算法思想总结:二分查找算法

创作不易&#xff0c;感谢三连&#xff01;&#xff01; 一、二分查找算法思路总结 大家先看总结&#xff0c;然后再根据后面的题型去慢慢领悟 二、二分查找&#xff08;easy&#xff09; . - 力扣&#xff08;LeetCode&#xff09;二分查找 思路&#xff1a;&#xff08;模…

基于 K8s 容器集群的容灾架构与方案

作者&#xff1a;庄宇 在设计系统架构时&#xff0c;我们必须假设任何组件和任何基础设施可能会在任何时间失效&#xff0c;例如&#xff1a;自然灾害&#xff0c;电力中断&#xff0c;网络中断&#xff0c;错误的系统变更等。为了应对挑战&#xff0c;我们必须设计合适的容灾…

COOH-PEG-Galactose 羧基-聚乙二醇-半乳糖 Galactose 靶向肝肿瘤细胞

在生物体内&#xff0c;正常细胞通过有氧呼吸将糖类等物质分解代谢产生能量&#xff0c;从而供给细胞的增殖和生 长。而癌细胞似乎更为“蛮横”&#xff0c;它们主要依靠糖酵解作用为生&#xff0c;因此癌细胞代谢葡萄糖的速度比正 常细胞要快得多。值得注意的是&#xff0c;…

Verilog——综合和防真

2.1综合 Verilog 是硬件描述语言&#xff0c;顾名思义&#xff0c;就是用代码的形式描述硬件的功能&#xff0c;最终在硬件电路上实 现该功能。在Verilog描述出硬件功能后需要使用综合器对Verilog代码进行解释并将代码转化成实际 的电路来表示&#xff0c;最终产生实际的电路&a…

PEG(2K)-g-[3.5]-PLL(20k)-g[3.5]-PEG(3.4k)-Biotin 生物素修饰聚乙二醇聚赖氨酸聚乙二醇

PEG-g-PLL-g-PEG-BIOTIN是一种生物素修饰的三嵌段共聚物。 PLL&#xff08;Poly-L-lysine&#xff09;是一种阳离子聚合物&#xff0c;由L-赖氨酸单体组成的聚合物。它具有多种应用&#xff0c;包括细胞培养、基因转染、组织工程和生物传感器等领域。 生物素可以与蛋白质亲和…

案例分析篇15:软件开发方法考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

[JAVAEE]—进程和多线程的认识

文章目录 什么是线程什么是进程进程的组成什么是pcb 进程概括线程线程与进程的关系线程的特点 创建线程创建线程方法创建线程的第二种方法对比 其他的方式匿名内部类创建线程匿名内部类创建Runable的子类lambda表达式创建一个线程 多线程的优势 什么是线程 什么是进程 首先想…

Java基础_内部类

文章目录 1.基本介绍1.定义&#xff1a;2.基本语法&#xff1a;3.内部类的分类 2.局部内部类1.快速入门2.局部内部类的使用 3.匿名内部类1.匿名内部类实现接口2.匿名内部类继承抽象类3.匿名内部类细节4.匿名内部类最佳实践1.匿名内部类作为实参传入函数2.匿名内部类课堂练习 4.…

一文浅谈射频识别RFID

RFID&#xff0c;全称为Radio Frequency Identification&#xff0c;即射频识别&#xff0c;是一种通过无线电信号识别特定目标并读取相关数据的技术。这种技术利用射频信号及其空间耦合、传输特性&#xff0c;实现对静止或移动物品的自动识别。 RFID由以下2个部分组成&#xf…

MongoDB从0到1:高效数据使用方法

MongoDB&#xff0c;作为一种流行的NoSQL数据库。从基础的文档存储到复杂的聚合查询&#xff0c;从索引优化到数据安全都有其独特之处。文末附MongoDB常用命令大全。 目录 1. 引言 MongoDB简介 MongoDB的优势和应用场景 2. 基础篇 安装和配置MongoDB MongoDB基本概念 使…

vue3.x项目,配置项目打包到二级目录

vue3.x项目&#xff0c;配置项目打包到二级目录 一、打开 vite.config.js 文件&#xff0c;添加或修改base字段&#xff0c; 将其值设置为二级目录的路径。例如想将应用部署到服务器上的/my-app目录下&#xff0c;如下设置&#xff1a; export default defineConfig({base: /…

滴滴 Flink 指标系统的架构设计与实践

毫不夸张地说&#xff0c;Flink 指标是洞察 Flink 任务健康状况的关键工具&#xff0c;它们如同 Flink 任务的眼睛一般至关重要。简而言之&#xff0c;这些指标可以被理解为滴滴数据开发平台实时运维系统的数据图谱。在实时计算领域&#xff0c;Flink 指标扮演着举足轻重的角色…

【C++基础】1.认识C++——《跟老吕学C++编程语言》

【C基础】1.认识C——《跟老吕学C编程语言》 认识CC简介C发展历程C四大特性支持数据封装和数据隐藏抽象支持继承和重用支持多态性 C语言工作原理C语言标准C标准库 认识C C简介 C&#xff0c;全称是C Plus Plus。老吕比较喜欢叫它C加加。 C是C语言的继承&#xff1b;C是是编译式…

(免费分享)基于springboot停车场管理平台(修复版)

修复百度车牌识别、修改样式、已知一些bug等 仅供学习交流&#xff0c;请勿随意传播&#xff0c;否则后果自负!! 仅供学习交流&#xff0c;请勿随意传播&#xff0c;否则后果自负!! 仅供学习交流&#xff0c;请勿随意传播&#xff0c;否则后果自负!! 角色&#xff1a; 超级…

Node.js入门基础—day01

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;给自己一个梦想&#xff0c;给世界一个惊喜。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章目录 初识node.js什…

【LeetCode热题100】73. 矩阵置零(矩阵)

一.题目要求 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 二.题目难度 中等 三.输入样例 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0…