超体聚类是一种图像的分割方法。

超体(supervoxel)是一种集合,集合的元素是“体”。与体素滤波器中的体类似,其本质是一个个的小方块。与大部分的分割手段不同,超体聚 类的目的并不是分割出某种特定物体,超体是对点云实施过分割(over segmentation),将场景点云化成很多小块,并研究每个小块之间的关系。这种将更小单元合并的分割思路已经出现了有些年份了,在图像分割中,像 素聚类形成超像素,以超像素关系来理解图像已经广为研究。本质上这种方法是对局部的一种总结,纹理,材质,颜色类似的部分会被自动的分割成一块,有利于后 续识别工作。比如对人的识别,如果能将头发,面部,四肢,躯干分开,则能更好的对各种姿态,性别的人进行识别。

点云和图像不一样,其不存在像素邻接关系。所以,超体聚类之前,必须以八叉树对点云进行划分,获得不同点团之间的邻接关系。与图像相似点云的邻接关系也有很多,如面邻接,线邻接,点邻接。

超体聚类实际上是一种特殊的区域生长算法,和无限制的生长不同,超体聚类首先需要规律的布置区域生长“晶核”。晶核在空间中实际上是均匀分布的,并指定晶核距离(Rseed)。再指定粒子距离(Rvoxel)。再指定最小晶粒(MOV),过小的晶粒需要融入最近的大晶粒。

这些基本参数在接下来的参数中会有设置

#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> // 数据类型
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,
boost::shared_ptr<pcl::visualization::PCLVisualizer> & viewer); int
main (int argc, char ** argv)
{
//解析命令行
if (argc < )
{
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[]);
return ();
} //打开点云
PointCloudT::Ptr cloud = boost::shared_ptr <PointCloudT> (new PointCloudT ());
pcl::console::print_highlight ("Loading point cloud...\n");
if (pcl::io::loadPCDFile<PointT> (argv[], *cloud))
{
pcl::console::print_error ("Error loading cloud file!\n");
return ();
} 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); //如何使用SupervoxelClustering函数
pcl::SupervoxelClustering<PointT> super (voxel_resolution, seed_resolution);
if (disable_transform)//如果设置的是参数--NT 就用默认的参数
super.setUseSingleCameraTransform (false);
super.setInputCloud (cloud);
super.setColorImportance (color_importance); //0.2f
super.setSpatialImportance (spatial_importance); //0.4f
super.setNormalImportance (normal_importance); //1.0f std::map <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 ()); boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
viewer->setBackgroundColor (, , ); 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); //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<uint32_t, 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
//为了使整个超体形成衣服图,我们需要遍历超体的每个临近的个体
std::multimap<uint32_t,uint32_t>::iterator label_itr = supervoxel_adjacency.begin ();
for ( ; label_itr != supervoxel_adjacency.end (); )
{
//First get the label
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;
std::multimap<uint32_t,uint32_t>::iterator adjacent_itr = supervoxel_adjacency.equal_range (supervoxel_label).first;
for ( ; 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 ();
}
return ();
} //VTK可视化构成的聚类图
void
addSupervoxelConnectionsToViewer (PointT &supervoxel_center,
PointCloudT &adjacent_supervoxel_centers,
std::string supervoxel_name,
boost::shared_ptr<pcl::visualization::PCLVisualizer> & 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
PointCloudT::iterator adjacent_itr = adjacent_supervoxel_centers.begin ();
for ( ; 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 = ; 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);
}

可执行文件生成后的图像显示如下

当然也可以自己设定参数生成自己想要的效果。同时在不同的场景中,使用的参数是十分重要的,

只是先了解超体的概念,如果想应用到实际的应用中,还需要很多其他的知识 ,所以这里只是基本的学习

有兴趣这关注我的微信公众号

PCL超体聚类的更多相关文章

  1. PCL—低层次视觉—点云分割(超体聚类)

    1.超体聚类——一种来自图像的分割方法 超体(supervoxel)是一种集合,集合的元素是“体”.与体素滤波器中的体类似,其本质是一个个的小方块.与之前提到的所有分割手段不同,超体聚类的目的并不是分 ...

  2. PCL—点云分割(超体聚类) 低层次点云处理

    博客转载自:http://www.cnblogs.com/ironstark/p/5013968.html 1.超体聚类——一种来自图像的分割方法 超体(supervoxel)是一种集合,集合的元素是 ...

  3. PCL—低层次视觉—点云分割(基于凹凸性)

    1.图像分割的两条思路 场景分割时机器视觉中的重要任务,尤其对家庭机器人而言,优秀的场景分割算法是实现复杂功能的基础.但是大家搞了几十年也还没搞定——不是我说的,是接下来要介绍的这篇论文说的.图像分割 ...

  4. PCL—点云分割(基于凹凸性) 低层次点云处理

    博客转载自:http://www.cnblogs.com/ironstark/p/5027269.html 1.图像分割的两条思路 场景分割时机器视觉中的重要任务,尤其对家庭机器人而言,优秀的场景分割 ...

  5. 基于传统方法点云分割以及PCL中分割模块

      之前在微信公众号中更新了以下几个章节 1,如何学习PCL以及一些基础的知识 2,PCL中IO口以及common模块的介绍 3,PCL中常用的两种数据结构KDtree以及Octree树的介绍    ...

  6. [PCL]3 欧式距离分类EuclideanClusterExtraction

    EuclideanClusterExtraction这个名字起的很奇怪,欧式距离聚类这个该如何理解?欧式距离只是一种距离测度的方法呀!有了一个Cluster在里面,我以为是某一种聚类算法,层次聚类?k ...

  7. PCL—低层次视觉—点云滤波(基于点云频率)

    1.点云的频率 今天在阅读分割有关的文献时,惊喜的发现,点云和图像一样,有可能也存在频率的概念.但这个概念并未在文献中出现也未被使用,谨在本博文中滥用一下“高频”一词.点云表达的是三维空间中的一种信息 ...

  8. PCL—低层次视觉—点云分割(邻近信息)

    分割给人最直观的影响大概就是邻居和我不一样.比如某条界线这边是中华文明,界线那边是西方文,最简单的分割方式就是在边界上找些居民问:"小伙子,你到底能不能上油管啊?”.然后把能上油管的居民坐标 ...

  9. PCL点云分割(3)

    (1)Euclidean分割 欧几里德分割法是最简单的.检查两点之间的距离.如果小于阈值,则两者被认为属于同一簇.它的工作原理就像一个洪水填充算法:在点云中的一个点被“标记”则表示为选择在一个的集群中 ...

随机推荐

  1. js判断客户端是否是IOS系统

    在手机端应用的开发中,经常会碰到IOS系统跟Android系统去访问同一个内容时的展示效果不同,这时候我们需要区别对待,下面代码就是用js判断手机终端是否IOS系统: //判断是否为ios系统:是IO ...

  2. php分享二十二:php面向对象

    1:static访问符 在类中使用static有两种主要用途.定义静态成员和定义静态方法.静态成员只保留一个变量的值,这个值对所有实例都是有效的 类的方法是static的,他所访问的属性也必须是sta ...

  3. Spring MVC+Hibernate JPA搭建的博客系统项目中所遇到的坑

    标签: springmvc hibernate 2016年12月21日 21:48:035133人阅读 评论(0) 收藏 举报  分类: Spring/Spring MVC(6)  Hibernate ...

  4. Android:percent 布局

    Android 新引入的布局,百分比布局,Percent 布局 主要分为两种:PercentFrameLayout he PercentRelativeLayout 布局 通过 support 库引入 ...

  5. 什么是内联函数(inline function)

    In C, we have used Macro function an optimized technique used by compiler to reduce the execution ti ...

  6. HAProxy压测及参数调优

    背景 小米容器云平台,在构建云厂商集群时,需要通过HAProxy将云厂商LB流量从宿主机转到容器中,但对于HAProxy的性能没有把握.参考网上的一篇HAProxy压测文章,文章中提到HAProxy ...

  7. zabbix 通过自定义key完成网卡监控

    创建执行脚本: # cat /etc/zabbix/monitor_scripts/network.sh #!/bin/bash #set -x usage() { echo "Useage ...

  8. oracle sql合计结果信息使用分组的小问题

    --月统计 Select SUBSTR(t.BalanceDate,1,6) as Mon, t.RechargeType , SUM(t.SumNum) as SumNum , SUM(t.SumF ...

  9. 漫游Kafka之过期数据清理【转】

    转自:http://blog.csdn.net/honglei915/article/details/49683065 Kafka将数据持久化到了硬盘上,允许你配置一定的策略对数据清理,清理的策略有两 ...

  10. 【教程】linux下安装Google Chrome

    google chrome       google浏览器一直都是深受大家喜爱的一个浏览器,而且其跨平台性比较好,这对于书签同步来说是非常重要的.但是在linux下,默认的是火弧浏览器,而google ...