当前位置:网站首页>【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库及其相关数学知识以备使用。谨此将自学过程与君共享。
博主才疏学浅,尚不具有指导能力,如有问题还请各位在评论处留言供大家共同讨论。’
边栏推荐
- Feign implements path escape through custom annotations
- 在线JSON转PlainText工具
- ICML 2022: UFRGS |作为最优策略转移基础的乐观线性支持和后继特征
- Started a natural language model bloom
- SQL Server 2016详细安装教程(附注册码和资源)
- The choice and trade-off between vector recall and literal recall
- [electron] basic learning
- 【剑指Offer】47. 礼物的最大价值
- 小芯片chiplet技术杂谈
- Stream + Nacos
猜你喜欢

Swing UI——容器(一)
![[Blue Bridge Cup training 100 questions] scratch digital calculation Blue Bridge Cup competition special prediction programming question collective training simulation exercise question No. 16](/img/7c/d4ea8747ce45fd2eb59a8f968653db.png)
[Blue Bridge Cup training 100 questions] scratch digital calculation Blue Bridge Cup competition special prediction programming question collective training simulation exercise question No. 16

Design of STM32 and rc522 simple bus card system

基于 ESXi 的黑群晖 DSM 7.0.1 安装 VMware Tools

官宣!Apache Doris 从 Apache 孵化器毕业,正式成为 Apache 顶级项目!

Death of 5 yuan youkuang in Yuanqi forest

未能加载文件或程序集“CefSharp.Core.Runtime.dll”或它的某一个依赖项。 不是有效的 Win32 应用程序。 (异常来自 HRESULT:0x800700C1)

ClickOnce error deploying ClickOnce application - the reference in the manifest does not match the identity of the downloaded assembly

MSP430F5529 单片机 读取 GY-906 红外温度传感器

Prediction of benign / malignant breast tumors (logistic regression classifier)
随机推荐
Discuz small fish game wind shadow legend business gbk+utf8 version template /dz game website template
上手了一个自然语言模型BLOOM
vmware虚拟机桥接连通
【经典干货书】数据科学中的信息理论方法,561页pdf
EXCEL 打印设置公共表头
本机部署一个MongoDB单节点服务器,并启用auth验证、开启oplog
发射,接收天线方向图
Getting started with pytorch
MySQL删除表后如何使ID从1开始
Death of 5 yuan youkuang in Yuanqi forest
使用SQL进行数据去重的N种方法
云辅助隐私集合求交(Server-Aided PSI)协议介绍:学习
Stream + Nacos
ICML 2022: UFRGS |作为最优策略转移基础的乐观线性支持和后继特征
Usage of vivado vio IP
小芯片chiplet技术杂谈
How to set the enterprise wechat group robots to send messages regularly?
fiddler 监听不到接口怎么办
支持删除,更新任意结点的优先级队列
Golang - the difference between new and make