基于区域增长的点云分割

本文介绍了基于区域增长的点云分割方法。首先从当前点集中选择最小曲率的点作为种子点,然后寻找这些种子点的邻域点,如果邻域点与种子点的法向量夹角小且曲率低,就将其纳入同一区域。通过迭代此过程,最终得到一系列分别代表平滑表面的点云类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Region growing segmentation(基于区域增长的点云分割)


pcl::RegionGrowing (该类在PCL 1.7.0才有的)
pcl ::NormalEstimation 计算法向量

算法思路:
  1. 选择种子点:在当前点集A中选择有最小曲率的点加入种子点集
  2. 区域增长:寻找种子点的邻域点,对于位于A中且与种子点的法向量夹角小于阈值的邻域点,将其加入当前区域中,如果其曲率小于阈值则也加入种子点集
  3. 对于每个种子点,重复2,最终输出一组类,每个类的点都认为是同一平滑表面的一部分。


region_growing_segmentation.cpp
#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/passthrough.h>
#include  <pcl/segmentation/region_growing.h>

int
main ( int argc,  char ** argv)
{
  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);
  }

  pcl ::search ::Search <pcl ::PointXYZ >::Ptr tree  = boost ::shared_ptr <pcl ::search ::Search <pcl ::PointXYZ >  > ( 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);
  normal_estimator.setInputCloud (cloud);
  normal_estimator.setKSearch ( 50);
  normal_estimator.compute ( *normals);

  pcl ::IndicesPtr indices ( new std ::vector  < int >);
  pcl ::PassThrough <pcl ::PointXYZ > pass;
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ( "z");
  pass.setFilterLimits ( 0.01.0);
  pass.filter ( *indices);

  pcl ::RegionGrowing <pcl ::PointXYZ, pcl ::Normal > reg;
  reg.setMinClusterSize ( 50);
  reg.setMaxClusterSize ( 1000000);
  reg.setSearchMethod (tree);
  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."  << endl;
  std ::cout  <<  "These are the indices of the points of the initial"  <<
    std ::endl  <<  "cloud that belong to the first cluster:"  << std ::endl;
  int 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);
}

CMakeLists.txt 
cmake_minimum_required( VERSION  2.8  FATAL_ERROR)

project( region_growing_segmentation)

find_package( PCL  1.5  REQUIRED)

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

add_executable ( region_growing_segmentation  region_growing_segmentation.cpp) target_link_libraries ( region_growing_segmentation  ${ PCL_LIBRARIES })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值