当前位置:网站首页>【PCL自学:Segmentation3】基于PCL的点云分割:区域增长分割
【PCL自学:Segmentation3】基于PCL的点云分割:区域增长分割
2022-06-27 20:59:00 【斯坦福的兔子】
基于PCL的点云区域增长分割
一、什么是区域增长分割
在本文中,我们将学习如何使用pcl:: regiongrow类中实现的区域增长算法。所述算法的目的是将在平滑性约束方面足够接近的点分类。因此,该算法的输出是聚类的集合,其中每个聚类都是一组点,被认为是同一光滑曲面的一部分。该算法的工作是基于点法线之间角度的比较。
二、区域增长分割原理剖析
让我们来看看该算法是如何工作的。
1.首先,它根据它们的曲率值对点进行分类。之所以要这样做是因为这个区域从曲率最小的点开始增长。这是因为曲率最小的点位于平坦的区域(从最平坦的区域增长可以减少分割总数)。
2.选中的点被添加到名为seeds(增长种子集合)的集合中。
3.对于每个种子点,算法找到它的邻近点。
a.每个邻居都被计算它的法线和当前种子点的法线之间的角度。如果角度小于阈值,则将当前点添加到当前种子所在区域。
b.然后对每个邻域进行曲率值测试。如果曲率小于阈值,则将此点添加到种子集合中作为新种子。
c.从种子集合中删除当前的种子。
4.如果种子集变成空的,这意味着算法扩大了区域,这个过程从头开始重复迭代,直到种子集合为空。
三、区域增长分割示例代码
#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> // for pcl::removeNaNFromPointCloud
#include <pcl/segmentation/region_growing.h>
int
main ()
{
// 读取点云pcd文件
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
if ( pcl::io::loadPCDFile <pcl::PointXYZ> ("region_growing_tutorial.pcd", *cloud) == -1)
{
std::cout << "Cloud reading failed." << std::endl;
return (-1);
}
// 建立搜索KD树
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); // 搜索方法为kd树走索
normal_estimator.setInputCloud (cloud); // 填入点云
normal_estimator.setKSearch (50); // 设置搜索范围
normal_estimator.compute (*normals); // 将法相保存在normals
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); // 设置kd树搜索方法
reg.setNumberOfNeighbours (30); // 设置每次邻域搜索数(影响计算速度)
reg.setInputCloud (cloud); // 设置输入点云
reg.setIndices (indices); // 设置输入的索引
reg.setInputNormals (normals); // 设置输入法向
reg.setSmoothnessThreshold (3.0 / 180.0 * M_PI); // 设置平滑度阈值(弧度)
reg.setCurvatureThreshold (1.0); // 设置曲率阈值
// 分类集合 并开始计算
std::vector <pcl::PointIndices> clusters;
reg.extract (clusters);
// 一系列输出
std::cout << "Number of clusters is equal to " << clusters.size () << std::endl;
std::cout << "First cluster has " << clusters[0].indices.size () << " points." << std::endl;
std::cout << "These are the indices of the points of the initial" <<
std::endl << "cloud that belong to the first cluster:" << 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);
}
运行效果如下:
【博主简介】
斯坦福的兔子,男,天津大学工学硕士。毕业至今从事光学三维成像及点云处理相关工作。因工作中使用的三维处理库为公司内部库,不具有普遍适用性,遂自学开源PCL库及其相关数学知识以备使用。谨此将自学过程与君共享。
博主才疏学浅,尚不具有指导能力,如有问题还请各位在评论处留言供大家共同讨论。’
边栏推荐
- 手把手教你移植 tinyriscv 到FPGA上
- [can you really use es] Introduction to es Basics (II)
- 最新云开发微信余额充电器特效小程序源码
- 电子科大(申恒涛团队)&京东AI(梅涛团队)提出用于视频问答的结构化双流注意网络,性能SOTA!优于基于双视频表示的方法!
- 小芯片chiplet技术杂谈
- The latest cloud development wechat balance charger special effect applet source code
- SQL Server 2016详细安装教程(附注册码和资源)
- 基于 ESXi 的黑群晖 DSM 7.0.1 安装 VMware Tools
- 图的存储结构
- Vivado FFT IP的使用说明
猜你喜欢

fiddler 监听不到接口怎么办

Spug - 轻量级自动化运维平台

Advertising is too "wild", Yoshino "surrenders"

The latest cloud development wechat balance charger special effect applet source code

【IDEA】IDEA 格式化 代码技巧 idea 格式化 会加 <p> 标签

PE buys a underwear company

云辅助隐私集合求交(Server-Aided PSI)协议介绍:学习

Stream + Nacos

How vivado adds timing constraints

seata
随机推荐
MSP430F5529 单片机 读取 GY-906 红外温度传感器
Google Earth engine (GEE) 03 vector data type
go日志包 log的使用
golang - new和make的区别
第一性原理(最优解理论)
"Top stream Aidou manufacturing machine" cooperates with four industrial capitals to become LP
上手了一个自然语言模型BLOOM
【AI应用】NVIDIA Tesla V100-PCIE-32GB的详情参数
Swing UI——容器(一)
华为伙伴暨开发者大会2022 | 麒麟软件携手华为共建计算产业,共创数智未来
The choice and trade-off between vector recall and literal recall
撰写外文时怎样引用中文文献?
Advertising is too "wild", Yoshino "surrenders"
Swing UI container (I)
[essay]me53n add button to call URL
手把手教你移植 tinyriscv 到FPGA上
使用SQL进行数据去重的N种方法
[electron] 基础学习
Death of 5 yuan youkuang in Yuanqi forest
Zabbix6.0 upgrade Guide - how to synchronize database upgrades?