《《《总结》》》PCL的42个实例整理:1~24

PCL官网:https://pointclouds.org/

turtorials:https://pcl.readthedocs.io/projects/tutorials/en/latest/

PCL官方提供了一系列案例,方便用户对点云数据进行处理: 

点云库(PCL)是一个独立的、大规模的、开放的项目,用于2D/3D图像和点云处理。PCL是根据BSD许可的条款发布的,因此可以免费用于商业和研究。

无论你是刚刚发现了PCL还是你是一个长期的老手,这个页面包含了一组资源的链接,这些资源将有助于巩固你对PCL和3D处理的知识。开发人员的附加Wiki资源可在https://github.com/PointCloudLibrary/pcl/wiki。

为了简化使用和开发,我们将PCL分成一系列模块化库。PCL中最重要的发布模块集如下所示。                                                                                                                             

《《《总结》》》PCL的42个实例整理:1~24_第1张图片

我们全面的PCL教程列表涵盖了许多主题,从简单的点云输入/输出操作到更复杂的应用程序,包括可视化、特征估计、分割等。

教程中可以用的案例汇总一下

目录

0 PCL源码安装:

0.1 安装依赖

0.2 下载PCL源码

0.3 编译库

0.4 安装OpenNI、OpenNI2(需要PCLVisualizer的话)

1 案例整理

1.1 <滤波>按照坐标信息过滤点云数据

1.2 <滤波>体素化网格降数据

1.3<滤波>根据表面法线、曲率变化去除噪声点

1.4<投影>点投影到平面,球体

1.5<分割>提取平面,曲面元素

1.6<滤波>邻近点个数滤除离散点

《《《总结》》》PCL的42个实例整理:1~24_第2张图片《《《总结》》》PCL的42个实例整理:1~24_第3张图片《《《总结》》》PCL的42个实例整理:1~24_第4张图片

《《《总结》》》PCL的42个实例整理:1~24_第5张图片《《《总结》》》PCL的42个实例整理:1~24_第6张图片《《《总结》》》PCL的42个实例整理:1~24_第7张图片

1.7<分割>提取在平面上的点

1.8<分割>圆柱型分割

1.9 <分割> 欧几里得分割

1.10 <分割> 区域增长细分

1.11 <分割> 基于颜色的区域增长分割

1.12 <分割> 基于最小剪切的细分

《《《总结》》》PCL的42个实例整理:1~24_第8张图片《《《总结》》》PCL的42个实例整理:1~24_第9张图片《《《总结》》》PCL的42个实例整理:1~24_第10张图片

《《《总结》》》PCL的42个实例整理:1~24_第11张图片《《《总结》》》PCL的42个实例整理:1~24_第12张图片《《《总结》》》PCL的42个实例整理:1~24_第13张图片

1.13<分割> 条件欧几里得聚类

1.14 <分割> 基于法线的分割的差异(没有点云数据,不能复现)

1.15 <分割> 将点云聚类为Supervoxels(报错误了不能复现)

1.16 <分割> 分割(没找到官方网址)

1.17 <分割>提取平面或球面的参数模型

1.18 <分割> 基于多项式重构的平滑和法线估计

 

《《《总结》》》PCL的42个实例整理:1~24_第14张图片《《《总结》》》PCL的42个实例整理:1~24_第15张图片《《《总结》》》PCL的42个实例整理:1~24_第16张图片

《《《总结》》》PCL的42个实例整理:1~24_第17张图片《《《总结》》》PCL的42个实例整理:1~24_第18张图片《《《总结》》》PCL的42个实例整理:1~24_第19张图片

1.19 <分割> 为平面模型构造凹凸的船体多边形

1.20 <分割> 无序点云的快速三角剖分

1.21 <分割> 将修剪的B样条曲线拟合到无序点云

1.22  使用积分图像进行正态估计

1.23  如何从范围图像中提取NARF特征

1.24 <分割> 基于惯性矩和偏心率的描述符

《《《总结》》》PCL的42个实例整理:1~24_第20张图片《《《总结》》》PCL的42个实例整理:1~24_第21张图片21

《《《总结》》》PCL的42个实例整理:1~24_第22张图片《《《总结》》》PCL的42个实例整理:1~24_第23张图片《《《总结》》》PCL的42个实例整理:1~24_第24张图片


 

0 PCL源码安装:

环境:ubuntu16.04/18.04

知识共享开源有利于知识迭代本是好事儿,我坚持初心,知道多少写多少,不藏着掖着,

但是如果没有好的激励机制,笔者定会心生倦怠,理解我不容易的,可以下载我整理好的包,请我吃根雪糕

下面的程序使用是没问题的;

0.1 安装依赖

注:中间涉及到的需要选择Y/N,需要一句一句终端运行;带#号的是我自己验证出问题的,忽略这两个,也能用

    sudo apt-get update  
    sudo apt-get install git build-essential linux-libc-dev  
    #sudo apt-get install cmake cmake-gui   
    sudo apt-get install libusb-1.0-0-dev libusb-dev libudev-dev  
    sudo apt-get install mpi-default-dev openmpi-bin openmpi-common    
    sudo apt-get install libflann1.8 libflann-dev  
    sudo apt-get install libeigen3-dev  
    sudo apt-get install libboost-all-dev  
    sudo apt-get install libvtk5.10-qt4 libvtk5.10 libvtk5-dev  
    sudo apt-get install libqhull* libgtest-dev  
    sudo apt-get install freeglut3-dev pkg-config  
    sudo apt-get install libxmu-dev libxi-dev   
    sudo apt-get install mono-complete  
    #sudo apt-get install qt-sdk openjdk-8-jdk openjdk-8-jre 

0.2 下载PCL源码

下载位置:https://github.com/PointCloudLibrary/pcl

《《《总结》》》PCL的42个实例整理:1~24_第25张图片《《《总结》》》PCL的42个实例整理:1~24_第26张图片《《《总结》》》PCL的42个实例整理:1~24_第27张图片

下载后解压到主目录下,默认名字为pcl_版本号,建议下载高于8.0的版本,默认下载是1.7.2,后面教程有的跑不通;

下载解压后,名字统一改成pcl

0.3 编译库

在PCL文件夹下进行cmake编译

ls
cd pcl
mkdir build
cd build 
cmake -DCMAKE_BUILD_TYPE=None -DCMAKE_INSTALL_PREFIX=/usr \ -DBUILD_GPU=ON -DBUILD_apps=ON -DBUILD_examples=ON \ -DCMAKE_INSTALL_PREFIX=/usr ..
make -j8  
sudo make install

0.4 安装OpenNI、OpenNI2(需要PCLVisualizer的话)

sudo apt-get install libopenni-dev 
sudo apt-get install libopenni2-dev

1 案例整理

PCL官方提供的可以用于使用的案例目录太长了,目录如下:https://blog.csdn.net/weixin_36662031/article/details/79352100

我把自己跑通过的案例,进行汇总了一下,便于随时调用:

1.1 <滤波>按照坐标信息过滤点云数据

在本教程中,我们将学习如何删除沿指定维度在用户给定间隔内/外的值的点。

《《《总结》》》PCL的42个实例整理:1~24_第28张图片

注意,坐标轴表示为红色(x),绿色(y)和蓝色(z)。这五个点用绿色表示,表示过滤后剩余的点,用红色表示已被过滤器删除的点。

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/passthrough.html#passthrough

创建目录,终端运行

mkdir 1
cd 1
mkdir passthrough
cd passthrough
gedit passthrough.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
./passthrough

《《《总结》》》PCL的42个实例整理:1~24_第29张图片

代码展示

##########################################
##########################################
##########################################
passthrough.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 

int
 main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud);

  // Fill in the cloud data
  cloud->width  = 5;
  cloud->height = 1;
  cloud->points.resize (cloud->width * cloud->height);

  for (std::size_t i = 0; i < cloud->points.size (); ++i)
  {
    cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
  }

  std::cerr << "Cloud before filtering: " << std::endl;
  for (std::size_t i = 0; i < cloud->points.size (); ++i)
    std::cerr << "    " << cloud->points[i].x << " " 
                        << cloud->points[i].y << " " 
                        << cloud->points[i].z << std::endl;

  // Create the filtering object
  pcl::PassThrough pass;
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0.0, 1.0);
  //pass.setFilterLimitsNegative (true);
  pass.filter (*cloud_filtered);

  std::cerr << "Cloud after filtering: " << std::endl;
  for (std::size_t i = 0; i < cloud_filtered->points.size (); ++i)
    std::cerr << "    " << cloud_filtered->points[i].x << " " 
                        << cloud_filtered->points[i].y << " " 
                        << cloud_filtered->points[i].z << std::endl;

  return (0);
}

##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(passthrough)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (passthrough passthrough.cpp)
target_link_libraries (passthrough ${PCL_LIBRARIES})

<>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.2 <滤波>体素化网格降数据

学习如何使用体素化网格方法对点云数据集进行降采样(即减少点数)

《《《总结》》》PCL的42个实例整理:1~24_第30张图片

官方链接 :https://pcl.readthedocs.io/projects/tutorials/en/latest/voxel_grid.html#voxelgrid

创建目录,终端运行

table_scene_lms400.pcd下载地址:https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_lms400.pcd

mkdir 2
cd 2
mkdir voxel_grid
cd voxel_grid
gedit voxel_grid.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载table_scene_lms400.pcd放到./2/voxel_grid/build目录下
#有代码包的:cp ../../table_scene_lms400.pcd ./
./voxel_grid

显示结果

pcl_viewer table_scene_lms400.pcd#查看之前的pcd文件
#ctrl+shift+t新建一个终端
pcl_viewer table_scene_lms400_downsampled.pcd#查看处理后的文件

代码展示

##########################################
##########################################
##########################################
voxel_grid.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 

int
main (int argc, char** argv)
{
  pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
  pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ());

  // Fill in the cloud data
  pcl::PCDReader reader;
  // Replace the path below with the path where you saved your file
  reader.read ("table_scene_lms400.pcd", *cloud); // Remember to download the file first!

  std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height 
       << " data points (" << pcl::getFieldsList (*cloud) << ")." << std::endl;

  // Create the filtering object
  pcl::VoxelGrid sor;
  sor.setInputCloud (cloud);
  sor.setLeafSize (0.01f, 0.01f, 0.01f);
  sor.filter (*cloud_filtered);

  std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height 
       << " data points (" << pcl::getFieldsList (*cloud_filtered) << ")." << std::endl;

  pcl::PCDWriter writer;
  writer.write ("table_scene_lms400_downsampled.pcd", *cloud_filtered, 
         Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false);

  return (0);
}

##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(voxel_grid)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (voxel_grid voxel_grid.cpp)
target_link_libraries (voxel_grid ${PCL_LIBRARIES})

<>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.3<滤波>根据表面法线、曲率变化去除噪声点

学习如何使用统计分析技术从点云数据集中去除噪声测量值,例如离群值

《《《总结》》》PCL的42个实例整理:1~24_第31张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/statistical_outlier.html#statistical-outlier-removal

创建目录,终端运行

table_scene_lms400.pcd下载地址:https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_lms400.pcd

mkdir 3
cd 3
mkdir statistical_removal
cd statistical_removal
gedit statistical_removal.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载table_scene_lms400.pcd放到./3/statistical_removal/build目录下
#有代码包的:cp ../../table_scene_lms400.pcd ./
./statistical_removal

显示结果

pcl_viewer table_scene_lms400.pcd#查看之前的pcd文件
#ctrl+shift+t新建一个终端
pcl_viewer table_scene_lms400_inliers.pcd#查看处理后的文件
#ctrl+shift+t新建一个终端
pcl_viewer table_scene_lms400_outliers.pcd#查看处理后的文件

《《《总结》》》PCL的42个实例整理:1~24_第32张图片

代码展示

##########################################
##########################################
##########################################
statistical_removal.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 

int
main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud);

  // Fill in the cloud data
  pcl::PCDReader reader;
  // Replace the path below with the path where you saved your file
  reader.read ("table_scene_lms400.pcd", *cloud);

  std::cerr << "Cloud before filtering: " << std::endl;
  std::cerr << *cloud << std::endl;

  // Create the filtering object
  pcl::StatisticalOutlierRemoval sor;
  sor.setInputCloud (cloud);
  sor.setMeanK (50);
  sor.setStddevMulThresh (1.0);
  sor.filter (*cloud_filtered);

  std::cerr << "Cloud after filtering: " << std::endl;
  std::cerr << *cloud_filtered << std::endl;

  pcl::PCDWriter writer;
  writer.write ("table_scene_lms400_inliers.pcd", *cloud_filtered, false);

  sor.setNegative (true);
  sor.filter (*cloud_filtered);
  writer.write ("table_scene_lms400_outliers.pcd", *cloud_filtered, false);

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(statistical_removal)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (statistical_removal statistical_removal.cpp)
target_link_libraries (statistical_removal ${PCL_LIBRARIES})

激光扫描通常会生成变化的点密度的点云数据集。此外,测量误差会导致稀疏的异常值,从而进一步破坏结果。这会使局部点云特性(例如表面法线或曲率变化)的估计复杂化,从而导致错误的值,进而可能导致点云配准失败。通过对每个点的邻域进行统计分析,并修整不符合特定标准的那些不规则现象,可以解决其中的一些不规则现象。我们稀疏的异常值消除是基于输入数据集中点到邻居距离分布的计算。对于每个点,我们计算从它到所有相邻点的平均距离。假设结果的分布是高斯分布,具有均值和标准差,

下图显示了稀疏离群值分析和删除的效果:原始数据集显示在左侧,而结果数据集显示在右侧。该图显示了滤波前后一个点邻域中的平均k最近邻距离。

《《《总结》》》PCL的42个实例整理:1~24_第33张图片

<>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.4<投影>点投影到平面,球体

学习如何将点投影到参数模型(例如,平面,球体等)上。参数模型通过一组系数给出-在平面情况下,通过其方程式:ax + by + cz + d = 0

《《《总结》》》PCL的42个实例整理:1~24_第34张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/project_inliers.html#project-inliers

创建目录,终端运行

mkdir 4
cd 4
gedit project_inliers.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
./project_inliers

显示结果

《《《总结》》》PCL的42个实例整理:1~24_第35张图片

代码展示

##########################################
##########################################
##########################################
project_inliers.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 

int
 main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_projected (new pcl::PointCloud);

  // Fill in the cloud data
  cloud->width  = 5;
  cloud->height = 1;
  cloud->points.resize (cloud->width * cloud->height);

  for (std::size_t i = 0; i < cloud->points.size (); ++i)
  {
    cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
  }

  std::cerr << "Cloud before projection: " << std::endl;
  for (std::size_t i = 0; i < cloud->points.size (); ++i)
    std::cerr << "    " << cloud->points[i].x << " " 
                        << cloud->points[i].y << " " 
                        << cloud->points[i].z << std::endl;

  // Create a set of planar coefficients with X=Y=0,Z=1
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
  coefficients->values.resize (4);
  coefficients->values[0] = coefficients->values[1] = 0;
  coefficients->values[2] = 1.0;
  coefficients->values[3] = 0;

  // Create the filtering object
  pcl::ProjectInliers proj;
  proj.setModelType (pcl::SACMODEL_PLANE);
  proj.setInputCloud (cloud);
  proj.setModelCoefficients (coefficients);
  proj.filter (*cloud_projected);

  std::cerr << "Cloud after projection: " << std::endl;
  for (std::size_t i = 0; i < cloud_projected->points.size (); ++i)
    std::cerr << "    " << cloud_projected->points[i].x << " " 
                        << cloud_projected->points[i].y << " " 
                        << cloud_projected->points[i].z << std::endl;

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(project_inliers)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (project_inliers project_inliers.cpp)
target_link_libraries (project_inliers ${PCL_LIBRARIES})

<>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.5<分割>提取平面,曲面元素

基于分段算法输出的索引从点云中提取点的子集

《《《总结》》》PCL的42个实例整理:1~24_第36张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/extract_indices.html#extract-indices

创建目录,终端运行

table_scene_lms400.pcd下载链接:https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_lms400.pcd

mkdir 5
cd 5
gedit extract_indices.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载table_scene_lms400.pcd放到./5/extract_indices/build目录下
#有代码包的:cp ../../table_scene_lms400.pcd ./
./extract_indices

结果显示

pcl_viewer table_scene_lms400.pcd#查看之前的pcd文件
#ctrl+shift+t新建一个终端
pcl_viewer table_scene_lms400_downsampled.pcd#查看处理后的文件
#ctrl+shift+t新建一个终端
pcl_viewer pcl_viewer  table_scene_lms400_plane_*.pcd#查看处理后的文件

代码展示

##########################################
##########################################
##########################################
extract_indices.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int
main (int argc, char** argv)
{
  pcl::PCLPointCloud2::Ptr cloud_blob (new pcl::PCLPointCloud2), cloud_filtered_blob (new pcl::PCLPointCloud2);
  pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud), cloud_p (new pcl::PointCloud), cloud_f (new pcl::PointCloud);

  // Fill in the cloud data
  pcl::PCDReader reader;
  reader.read ("table_scene_lms400.pcd", *cloud_blob);

  std::cerr << "PointCloud before filtering: " << cloud_blob->width * cloud_blob->height << " data points." << std::endl;

  // Create the filtering object: downsample the dataset using a leaf size of 1cm
  pcl::VoxelGrid sor;
  sor.setInputCloud (cloud_blob);
  sor.setLeafSize (0.01f, 0.01f, 0.01f);
  sor.filter (*cloud_filtered_blob);

  // Convert to the templated PointCloud
  pcl::fromPCLPointCloud2 (*cloud_filtered_blob, *cloud_filtered);

  std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height << " data points." << std::endl;

  // Write the downsampled version to disk
  pcl::PCDWriter writer;
  writer.write ("table_scene_lms400_downsampled.pcd", *cloud_filtered, false);

  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());
  // Create the segmentation object
  pcl::SACSegmentation seg;
  // Optional
  seg.setOptimizeCoefficients (true);
  // Mandatory
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setMaxIterations (1000);
  seg.setDistanceThreshold (0.01);

  // Create the filtering object
  pcl::ExtractIndices extract;

  int i = 0, nr_points = (int) cloud_filtered->points.size ();
  // While 30% of the original cloud is still there
  while (cloud_filtered->points.size () > 0.3 * nr_points)
  {
    // Segment the largest planar component from the remaining cloud
    seg.setInputCloud (cloud_filtered);
    seg.segment (*inliers, *coefficients);
    if (inliers->indices.size () == 0)
    {
      std::cerr << "Could not estimate a planar model for the given dataset." << std::endl;
      break;
    }

    // Extract the inliers
    extract.setInputCloud (cloud_filtered);
    extract.setIndices (inliers);
    extract.setNegative (false);
    extract.filter (*cloud_p);
    std::cerr << "PointCloud representing the planar component: " << cloud_p->width * cloud_p->height << " data points." << std::endl;

    std::stringstream ss;
    ss << "table_scene_lms400_plane_" << i << ".pcd";
    writer.write (ss.str (), *cloud_p, false);

    // Create the filtering object
    extract.setNegative (true);
    extract.filter (*cloud_f);
    cloud_filtered.swap (cloud_f);
    i++;
  }

  return (0);
}

##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(extract_indices)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (extract_indices extract_indices.cpp)
target_link_libraries (extract_indices ${PCL_LIBRARIES})

<>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.6<滤波>邻近点个数滤除离散点

该过滤器将删除其输入云中在一定范围内没有至少一些邻居的所有索引

每个索引必须具有指定半径内的邻居才能保留在PointCloud中。例如,如果指定了1个邻居,则只会从PointCloud中删除黄点。如果指定了2个邻居,则黄点和绿点都将从PointCloud中删除。

《《《总结》》》PCL的42个实例整理:1~24_第37张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/remove_outliers.html#remove-outliers

创建目录,终端运行

mkdir 6
cd 6
gedit remove_outliers.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
./remove_outliers
./remove_outliers -c
./remove_outliers -r

结果显示

《《《总结》》》PCL的42个实例整理:1~24_第38张图片

代码展示

##########################################
##########################################
##########################################
remove_outliers.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 

int
 main (int argc, char** argv)
{
  if (argc != 2)
  {
    std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
    exit(0);
  }
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud);

  // Fill in the cloud data
  cloud->width  = 5;
  cloud->height = 1;
  cloud->points.resize (cloud->width * cloud->height);

  for (std::size_t i = 0; i < cloud->points.size (); ++i)
  {
    cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
  }

  if (strcmp(argv[1], "-r") == 0){
    pcl::RadiusOutlierRemoval outrem;
    // build the filter
    outrem.setInputCloud(cloud);
    outrem.setRadiusSearch(0.8);
    outrem.setMinNeighborsInRadius (2);
    // apply filter
    outrem.filter (*cloud_filtered);
  }
  else if (strcmp(argv[1], "-c") == 0){
    // build the condition
    pcl::ConditionAnd::Ptr range_cond (new
      pcl::ConditionAnd ());
    range_cond->addComparison (pcl::FieldComparison::ConstPtr (new
      pcl::FieldComparison ("z", pcl::ComparisonOps::GT, 0.0)));
    range_cond->addComparison (pcl::FieldComparison::ConstPtr (new
      pcl::FieldComparison ("z", pcl::ComparisonOps::LT, 0.8)));
    // build the filter
    pcl::ConditionalRemoval condrem;
    condrem.setCondition (range_cond);
    condrem.setInputCloud (cloud);
    condrem.setKeepOrganized(true);
    // apply filter
    condrem.filter (*cloud_filtered);
  }
  else{
    std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
    exit(0);
  }
  std::cerr << "Cloud before filtering: " << std::endl;
  for (std::size_t i = 0; i < cloud->points.size (); ++i)
    std::cerr << "    " << cloud->points[i].x << " "
                        << cloud->points[i].y << " "
                        << cloud->points[i].z << std::endl;
  // display pointcloud after filtering
  std::cerr << "Cloud after filtering: " << std::endl;
  for (std::size_t i = 0; i < cloud_filtered->points.size (); ++i)
    std::cerr << "    " << cloud_filtered->points[i].x << " "
                        << cloud_filtered->points[i].y << " "
                        << cloud_filtered->points[i].z << std::endl;
  return (0);
}

##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(remove_outliers)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (remove_outliers remove_outliers.cpp)
target_link_libraries (remove_outliers ${PCL_LIBRARIES})

<>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.7<分割>提取在平面上的点

学习提取在某一平面上的点

《《《总结》》》PCL的42个实例整理:1~24_第39张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/planar_segmentation.html#planar-segmentation

创建目录,终端运行

mkdir 7
cd 7
gedit planar_segmentation.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
./planar_segmentation

结果显示

《《《总结》》》PCL的42个实例整理:1~24_第40张图片

代码展示

##########################################
##########################################
##########################################
planar_segmentation.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int
 main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud(new pcl::PointCloud);

  // Fill in the cloud data
  cloud->width  = 15;
  cloud->height = 1;
  cloud->points.resize (cloud->width * cloud->height);

  // Generate the data
  for (std::size_t i = 0; i < cloud->points.size (); ++i)
  {
    cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].z = 1.0;
  }

  // Set a few outliers
  cloud->points[0].z = 2.0;
  cloud->points[3].z = -2.0;
  cloud->points[6].z = 4.0;

  std::cerr << "Point cloud data: " << cloud->points.size () << " points" << std::endl;
  for (std::size_t i = 0; i < cloud->points.size (); ++i)
    std::cerr << "    " << cloud->points[i].x << " "
                        << cloud->points[i].y << " "
                        << cloud->points[i].z << std::endl;

  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
  // Create the segmentation object
  pcl::SACSegmentation seg;
  // Optional
  seg.setOptimizeCoefficients (true);
  // Mandatory
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setDistanceThreshold (0.01);

  seg.setInputCloud (cloud);
  seg.segment (*inliers, *coefficients);

  if (inliers->indices.size () == 0)
  {
    PCL_ERROR ("Could not estimate a planar model for the given dataset.");
    return (-1);
  }

  std::cerr << "Model coefficients: " << coefficients->values[0] << " " 
                                      << coefficients->values[1] << " "
                                      << coefficients->values[2] << " " 
                                      << coefficients->values[3] << std::endl;

  std::cerr << "Model inliers: " << inliers->indices.size () << std::endl;
  for (std::size_t i = 0; i < inliers->indices.size (); ++i)
    std::cerr << inliers->indices[i] << "    " << cloud->points[inliers->indices[i]].x << " "
                                               << cloud->points[inliers->indices[i]].y << " "
                                               << cloud->points[inliers->indices[i]].z << std::endl;

  return (0);
}

##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(planar_segmentation)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (planar_segmentation planar_segmentation.cpp)
target_link_libraries (planar_segmentation ${PCL_LIBRARIES})

<>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.8<分割>圆柱型分割

提取圆柱数据

  • 距离1.5米以外的数据点被过滤
  • 估计每个点的表面法线
  • 平面模型(描述我们的演示数据集中的表)被分割并保存到磁盘
  • 圆柱模型(在我们的演示数据集中描述了杯子)被分段并保存到磁盘

《《《总结》》》PCL的42个实例整理:1~24_第41张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/cylinder_segmentation.html#cylinder-segmentation

创建目录,终端运行

table_scene_mug_stereo_textured.pcd下载链接:https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_mug_stereo_textured.pcd

mkdir 8
cd 8
gedit cylinder_segmentation.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载table_scene_mug_stereo_textured.pcd放到./8/cylinder_segmentation/build目录下
#有代码包的:cp ../../table_scene_mug_stereo_textured.pcd ./
./cylinder_segmentation

结果显示

《《《总结》》》PCL的42个实例整理:1~24_第42张图片

代码展示

##########################################
##########################################
##########################################
cylinder_segmentation.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef pcl::PointXYZ PointT;

int
main (int argc, char** argv)
{
  // All the objects needed
  pcl::PCDReader reader;
  pcl::PassThrough pass;
  pcl::NormalEstimation ne;
  pcl::SACSegmentationFromNormals seg; 
  pcl::PCDWriter writer;
  pcl::ExtractIndices extract;
  pcl::ExtractIndices extract_normals;
  pcl::search::KdTree::Ptr tree (new pcl::search::KdTree ());

  // Datasets
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_normals (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_filtered2 (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_normals2 (new pcl::PointCloud);
  pcl::ModelCoefficients::Ptr coefficients_plane (new pcl::ModelCoefficients), coefficients_cylinder (new pcl::ModelCoefficients);
  pcl::PointIndices::Ptr inliers_plane (new pcl::PointIndices), inliers_cylinder (new pcl::PointIndices);

  // Read in the cloud data
  reader.read ("table_scene_mug_stereo_textured.pcd", *cloud);
  std::cerr << "PointCloud has: " << cloud->points.size () << " data points." << std::endl;

  // Build a passthrough filter to remove spurious NaNs
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0, 1.5);
  pass.filter (*cloud_filtered);
  std::cerr << "PointCloud after filtering has: " << cloud_filtered->points.size () << " data points." << std::endl;

  // Estimate point normals
  ne.setSearchMethod (tree);
  ne.setInputCloud (cloud_filtered);
  ne.setKSearch (50);
  ne.compute (*cloud_normals);

  // Create the segmentation object for the planar model and set all the parameters
  seg.setOptimizeCoefficients (true);
  seg.setModelType (pcl::SACMODEL_NORMAL_PLANE);
  seg.setNormalDistanceWeight (0.1);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setMaxIterations (100);
  seg.setDistanceThreshold (0.03);
  seg.setInputCloud (cloud_filtered);
  seg.setInputNormals (cloud_normals);
  // Obtain the plane inliers and coefficients
  seg.segment (*inliers_plane, *coefficients_plane);
  std::cerr << "Plane coefficients: " << *coefficients_plane << std::endl;

  // Extract the planar inliers from the input cloud
  extract.setInputCloud (cloud_filtered);
  extract.setIndices (inliers_plane);
  extract.setNegative (false);

  // Write the planar inliers to disk
  pcl::PointCloud::Ptr cloud_plane (new pcl::PointCloud ());
  extract.filter (*cloud_plane);
  std::cerr << "PointCloud representing the planar component: " << cloud_plane->points.size () << " data points." << std::endl;
  writer.write ("table_scene_mug_stereo_textured_plane.pcd", *cloud_plane, false);

  // Remove the planar inliers, extract the rest
  extract.setNegative (true);
  extract.filter (*cloud_filtered2);
  extract_normals.setNegative (true);
  extract_normals.setInputCloud (cloud_normals);
  extract_normals.setIndices (inliers_plane);
  extract_normals.filter (*cloud_normals2);

  // Create the segmentation object for cylinder segmentation and set all the parameters
  seg.setOptimizeCoefficients (true);
  seg.setModelType (pcl::SACMODEL_CYLINDER);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setNormalDistanceWeight (0.1);
  seg.setMaxIterations (10000);
  seg.setDistanceThreshold (0.05);
  seg.setRadiusLimits (0, 0.1);
  seg.setInputCloud (cloud_filtered2);
  seg.setInputNormals (cloud_normals2);

  // Obtain the cylinder inliers and coefficients
  seg.segment (*inliers_cylinder, *coefficients_cylinder);
  std::cerr << "Cylinder coefficients: " << *coefficients_cylinder << std::endl;

  // Write the cylinder inliers to disk
  extract.setInputCloud (cloud_filtered2);
  extract.setIndices (inliers_cylinder);
  extract.setNegative (false);
  pcl::PointCloud::Ptr cloud_cylinder (new pcl::PointCloud ());
  extract.filter (*cloud_cylinder);
  if (cloud_cylinder->points.empty ()) 
    std::cerr << "Can't find the cylindrical component." << std::endl;
  else
  {
	  std::cerr << "PointCloud representing the cylindrical component: " << cloud_cylinder->points.size () << " data points." << std::endl;
	  writer.write ("table_scene_mug_stereo_textured_cylinder.pcd", *cloud_cylinder, false);
  }
  return (0);
}

##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(cylinder_segmentation)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (cylinder_segmentation cylinder_segmentation.cpp)
target_link_libraries (cylinder_segmentation ${PCL_LIBRARIES})

<>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.9 <分割> 欧几里得分割

学习:欧几里得分割

《《《总结》》》PCL的42个实例整理:1~24_第43张图片

 

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/cluster_extraction.html#cluster-extraction

创建目录,终端运行

table_scene_lms400.pcd下载链接:https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_lms400.pcd

mkdir 9
cd 9
mkdir cluster_extraction
cd cluster_extraction
gedit cluster_extraction.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载table_scene_lms400.pcd放到./9/cluster_extraction/build目录下
#有代码包的:cp ../../table_scene_lms400.pcd ./
./cluster_extraction

结果显示

《《《总结》》》PCL的42个实例整理:1~24_第44张图片

pcl_viewer table_scene_lms400.pcd
ctrl+ shift + t
pcl_viewer  cloud_cluster_*.pcd

代码展示

##########################################
##########################################
##########################################
cluster_extraction.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


int 
main (int argc, char** argv)
{
  // Read in the cloud data
  pcl::PCDReader reader;
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud), cloud_f (new pcl::PointCloud);
  reader.read ("table_scene_lms400.pcd", *cloud);
  std::cout << "PointCloud before filtering has: " << cloud->points.size () << " data points." << std::endl; //*

  // Create the filtering object: downsample the dataset using a leaf size of 1cm
  pcl::VoxelGrid vg;
  pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud);
  vg.setInputCloud (cloud);
  vg.setLeafSize (0.01f, 0.01f, 0.01f);
  vg.filter (*cloud_filtered);
  std::cout << "PointCloud after filtering has: " << cloud_filtered->points.size ()  << " data points." << std::endl; //*

  // Create the segmentation object for the planar model and set all the parameters
  pcl::SACSegmentation seg;
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
  pcl::PointCloud::Ptr cloud_plane (new pcl::PointCloud ());
  pcl::PCDWriter writer;
  seg.setOptimizeCoefficients (true);
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setMaxIterations (100);
  seg.setDistanceThreshold (0.02);

  int i=0, nr_points = (int) cloud_filtered->points.size ();
  while (cloud_filtered->points.size () > 0.3 * nr_points)
  {
    // Segment the largest planar component from the remaining cloud
    seg.setInputCloud (cloud_filtered);
    seg.segment (*inliers, *coefficients);
    if (inliers->indices.size () == 0)
    {
      std::cout << "Could not estimate a planar model for the given dataset." << std::endl;
      break;
    }

    // Extract the planar inliers from the input cloud
    pcl::ExtractIndices extract;
    extract.setInputCloud (cloud_filtered);
    extract.setIndices (inliers);
    extract.setNegative (false);

    // Get the points associated with the planar surface
    extract.filter (*cloud_plane);
    std::cout << "PointCloud representing the planar component: " << cloud_plane->points.size () << " data points." << std::endl;

    // Remove the planar inliers, extract the rest
    extract.setNegative (true);
    extract.filter (*cloud_f);
    *cloud_filtered = *cloud_f;
  }

  // Creating the KdTree object for the search method of the extraction
  pcl::search::KdTree::Ptr tree (new pcl::search::KdTree);
  tree->setInputCloud (cloud_filtered);

  std::vector cluster_indices;
  pcl::EuclideanClusterExtraction ec;
  ec.setClusterTolerance (0.02); // 2cm
  ec.setMinClusterSize (100);
  ec.setMaxClusterSize (25000);
  ec.setSearchMethod (tree);
  ec.setInputCloud (cloud_filtered);
  ec.extract (cluster_indices);

  int j = 0;
  for (std::vector::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it)
  {
    pcl::PointCloud::Ptr cloud_cluster (new pcl::PointCloud);
    for (std::vector::const_iterator pit = it->indices.begin (); pit != it->indices.end (); ++pit)
      cloud_cluster->points.push_back (cloud_filtered->points[*pit]); //*
    cloud_cluster->width = cloud_cluster->points.size ();
    cloud_cluster->height = 1;
    cloud_cluster->is_dense = true;

    std::cout << "PointCloud representing the Cluster: " << cloud_cluster->points.size () << " data points." << std::endl;
    std::stringstream ss;
    ss << "cloud_cluster_" << j << ".pcd";
    writer.write (ss.str (), *cloud_cluster, false); //*
    j++;
  }

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(cluster_extraction)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (cluster_extraction cluster_extraction.cpp)
target_link_libraries (cluster_extraction ${PCL_LIBRARIES})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.10 <分割> 区域增长细分

学习:区域增长细分

学习如何使用在pcl::RegionGrowing课程中实现的区域增长算法。所述算法的目的是合并就平滑度约束而言足够接近的点。因此,该算法的输出是一组聚类,其中每个聚类都是被认为是同一光滑表面一部分的一组点。该算法的工作基于点法线之间的角度比较。

《《《总结》》》PCL的42个实例整理:1~24_第45张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/region_growing_segmentation.html#region-growing-segmentation

创建目录,终端运行

region_growing_tutorial.pcd下载链接:https://raw.github.com/PointCloudLibrary/data/master/tutorials/region_growing_tutorial.pcd

mkdir 10
cd 10
mkdir region_growing_segmentation
cd region_growing_segmentation
gedit region_growing_segmentation.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载region_growing_tutorial.pcd放到./10/region_growing_segmentation/build目录下
#有代码包的:cp ../../region_growing_tutorial.pcd ./
./region_growing_segmentation

结果显示

《《《总结》》》PCL的42个实例整理:1~24_第46张图片

代码展示

##########################################
##########################################
##########################################
region_growing_segmentation.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int
main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  if ( pcl::io::loadPCDFile  ("region_growing_tutorial.pcd", *cloud) == -1)
  {
    std::cout << "Cloud reading failed." << std::endl;
    return (-1);
  }

  pcl::search::Search::Ptr tree = boost::shared_ptr > (new pcl::search::KdTree);
  pcl::PointCloud ::Ptr normals (new pcl::PointCloud );
  pcl::NormalEstimation normal_estimator;
  normal_estimator.setSearchMethod (tree);
  normal_estimator.setInputCloud (cloud);
  normal_estimator.setKSearch (50);
  normal_estimator.compute (*normals);

  pcl::IndicesPtr indices (new std::vector );
  pcl::PassThrough pass;
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0.0, 1.0);
  pass.filter (*indices);

  pcl::RegionGrowing 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  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 ::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})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.11 <分割> 基于颜色的区域增长分割

学习:学习如何使用pcl::RegionGrowingRGB该类中实现的基于颜色的区域增长算法。

《《《总结》》》PCL的42个实例整理:1~24_第47张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/region_growing_rgb_segmentation.html#region-growing-rgb-segmentation

创建目录,终端运行

region_growing_rgb_tutorial.pcd下载链接:https://raw.github.com/PointCloudLibrary/data/master/tutorials/region_growing_rgb_tutorial.pcd

mkdir 11
cd 11
mkdir region_growing_rgb_segmentation
cd region_growing_rgb_segmentation
gedit region_growing_rgb_segmentation.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载region_growing_rgb_tutorial.pcd放到./11/region_growing_rgb_segmentation/build目录下
#有代码包的:cp ../../region_growing_rgb_tutorial.pcd ./
./region_growing_rgb_segmentation

结果显示

ctrl + shift + t
pcl_viewer  region_growing_rgb_tutorial.pcd

代码展示

##########################################
##########################################
##########################################
region_growing_rgb_segmentation.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std::chrono_literals;

int
main (int argc, char** argv)
{
  pcl::search::Search ::Ptr tree (new pcl::search::KdTree);

  pcl::PointCloud ::Ptr cloud (new pcl::PointCloud );
  if ( pcl::io::loadPCDFile  ("region_growing_rgb_tutorial.pcd", *cloud) == -1 )
  {
    std::cout << "Cloud reading failed." << std::endl;
    return (-1);
  }

  pcl::IndicesPtr indices (new std::vector );
  pcl::PassThrough pass;
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0.0, 1.0);
  pass.filter (*indices);

  pcl::RegionGrowingRGB reg;
  reg.setInputCloud (cloud);
  reg.setIndices (indices);
  reg.setSearchMethod (tree);
  reg.setDistanceThreshold (10);
  reg.setPointColorThreshold (6);
  reg.setRegionColorThreshold (5);
  reg.setMinClusterSize (600);

  std::vector  clusters;
  reg.extract (clusters);

  pcl::PointCloud ::Ptr colored_cloud = reg.getColoredCloud ();
  pcl::visualization::CloudViewer viewer ("Cluster viewer");
  viewer.showCloud (colored_cloud);
  while (!viewer.wasStopped ())
  {
    std::this_thread::sleep_for(100us);
  }

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
SET( CMAKE_CXX_FLAGS "-std=c++11 -O3")
project(region_growing_rgb_segmentation)
find_package(PCL 1.5 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
include(CheckCXXCompilerFlag)
add_compile_options(-std=gnu++11)
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (region_growing_rgb_segmentation region_growing_rgb_segmentation.cpp)
target_link_libraries (region_growing_rgb_segmentation ${PCL_LIBRARIES})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.12 <分割> 基于最小剪切的细分

学习:学习如何使用在pcl::MinCutSegmentation类中实现的基于最小剪切的分割算法。该算法对给定的输入云进行了二进制分割。具有对象中心和半径的算法将云分为两组:前景点和背景点(属于对象的点和不属于对象的点)。

《《《总结》》》PCL的42个实例整理:1~24_第48张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/min_cut_segmentation.html#min-cut-segmentation

创建目录,终端运行

min_cut_segmentation_tutorial.pcd下载链接:https://raw.github.com/PointCloudLibrary/data/master/tutorials/min_cut_segmentation_tutorial.pcd

mkdir 12
cd 12
mkdir min_cut_segmentation
cd min_cut_segmentation
gedit min_cut_segmentation.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载min_cut_segmentation_tutorial.pcd放到./12/min_cut_segmentation/build目录下
#有代码包的:cp ../../min_cut_segmentation_tutorial.pcd ./
./min_cut_segmentation

结果显示

ctrl + shift + t
pcl_viewer  min_cut_segmentation_tutorial.pcd

代码展示

##########################################
##########################################
##########################################
min_cut_segmentation.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main (int argc, char** argv)
{
  pcl::PointCloud ::Ptr cloud (new pcl::PointCloud );
  if ( pcl::io::loadPCDFile  ("min_cut_segmentation_tutorial.pcd", *cloud) == -1 )
  {
    std::cout << "Cloud reading failed." << std::endl;
    return (-1);
  }

  pcl::IndicesPtr indices (new std::vector );
  pcl::PassThrough pass;
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0.0, 1.0);
  pass.filter (*indices);

  pcl::MinCutSegmentation seg;
  seg.setInputCloud (cloud);
  seg.setIndices (indices);

  pcl::PointCloud::Ptr foreground_points(new pcl::PointCloud ());
  pcl::PointXYZ point;
  point.x = 68.97;
  point.y = -18.55;
  point.z = 0.57;
  foreground_points->points.push_back(point);
  seg.setForegroundPoints (foreground_points);

  seg.setSigma (0.25);
  seg.setRadius (3.0433856);
  seg.setNumberOfNeighbours (14);
  seg.setSourceWeight (0.8);

  std::vector  clusters;
  seg.extract (clusters);

  std::cout << "Maximum flow is " << seg.getMaxFlow () << std::endl;

  pcl::PointCloud ::Ptr colored_cloud = seg.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(min_cut_segmentation)
find_package(PCL 1.5 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (min_cut_segmentation min_cut_segmentation.cpp)
target_link_libraries (min_cut_segmentation ${PCL_LIBRARIES})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.13<分割> 条件欧几里得聚类

学习:一种分割算法,该算法基于欧几里得距离和需要保持的用户可自定义条件对点进行聚类。

《《《总结》》》PCL的42个实例整理:1~24_第49张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/conditional_euclidean_clustering.html#conditional-euclidean-clustering

创建目录,终端运行

Statues_4.pcd下载链接:https://sourceforge.net/projects/pointclouds/files/PCDdatasets/Trimble/Outdoor1/Statues_4.pcd.zip

mkdir 13
cd 13
mkdir conditional_euclidean_clustering
cd conditional_euclidean_clustering
gedit conditional_euclidean_clustering.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载Statues_4.pcd放到./13/conditional_euclidean_clustering/build目录下
#有代码包的:cp ../../Statues_4.pcd ./
./conditional_euclidean_clustering

结果显示

《《《总结》》》PCL的42个实例整理:1~24_第50张图片

pcl_viewer  output.pcd
ctrl + shift + t
pcl_viewer  Statues_4.pcd
按“ 5”将切换到强度通道可视化。太小的簇将被涂成红色,太大的簇将被涂成蓝色,并且实际的感兴趣的簇/对象将在黄色和青色之间随机着色。

代码展示

##########################################
##########################################
##########################################
conditional_euclidean_clustering.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 

#include 
#include 
#include 

typedef pcl::PointXYZI PointTypeIO;
typedef pcl::PointXYZINormal PointTypeFull;

bool
enforceIntensitySimilarity (const PointTypeFull& point_a, const PointTypeFull& point_b, float squared_distance)
{
  if (fabs (point_a.intensity - point_b.intensity) < 5.0f)
    return (true);
  else
    return (false);
}

bool
enforceCurvatureOrIntensitySimilarity (const PointTypeFull& point_a, const PointTypeFull& point_b, float squared_distance)
{
  Eigen::Map point_a_normal = point_a.getNormalVector3fMap (), point_b_normal = point_b.getNormalVector3fMap ();
  if (fabs (point_a.intensity - point_b.intensity) < 5.0f)
    return (true);
  if (fabs (point_a_normal.dot (point_b_normal)) < 0.05)
    return (true);
  return (false);
}

bool
customRegionGrowing (const PointTypeFull& point_a, const PointTypeFull& point_b, float squared_distance)
{
  Eigen::Map point_a_normal = point_a.getNormalVector3fMap (), point_b_normal = point_b.getNormalVector3fMap ();
  if (squared_distance < 10000)
  {
    if (fabs (point_a.intensity - point_b.intensity) < 8.0f)
      return (true);
    if (fabs (point_a_normal.dot (point_b_normal)) < 0.06)
      return (true);
  }
  else
  {
    if (fabs (point_a.intensity - point_b.intensity) < 3.0f)
      return (true);
  }
  return (false);
}

int
main (int argc, char** argv)
{
  // Data containers used
  pcl::PointCloud::Ptr cloud_in (new pcl::PointCloud), cloud_out (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_with_normals (new pcl::PointCloud);
  pcl::IndicesClustersPtr clusters (new pcl::IndicesClusters), small_clusters (new pcl::IndicesClusters), large_clusters (new pcl::IndicesClusters);
  pcl::search::KdTree::Ptr search_tree (new pcl::search::KdTree);
  pcl::console::TicToc tt;

  // Load the input point cloud
  std::cerr << "Loading...\n", tt.tic ();
  pcl::io::loadPCDFile ("Statues_4.pcd", *cloud_in);
  std::cerr << ">> Done: " << tt.toc () << " ms, " << cloud_in->points.size () << " points\n";

  // Downsample the cloud using a Voxel Grid class
  std::cerr << "Downsampling...\n", tt.tic ();
  pcl::VoxelGrid vg;
  vg.setInputCloud (cloud_in);
  vg.setLeafSize (80.0, 80.0, 80.0);
  vg.setDownsampleAllData (true);
  vg.filter (*cloud_out);
  std::cerr << ">> Done: " << tt.toc () << " ms, " << cloud_out->points.size () << " points\n";

  // Set up a Normal Estimation class and merge data in cloud_with_normals
  std::cerr << "Computing normals...\n", tt.tic ();
  pcl::copyPointCloud (*cloud_out, *cloud_with_normals);
  pcl::NormalEstimation ne;
  ne.setInputCloud (cloud_out);
  ne.setSearchMethod (search_tree);
  ne.setRadiusSearch (300.0);
  ne.compute (*cloud_with_normals);
  std::cerr << ">> Done: " << tt.toc () << " ms\n";

  // Set up a Conditional Euclidean Clustering class
  std::cerr << "Segmenting to clusters...\n", tt.tic ();
  pcl::ConditionalEuclideanClustering cec (true);
  cec.setInputCloud (cloud_with_normals);
  cec.setConditionFunction (&customRegionGrowing);
  cec.setClusterTolerance (500.0);
  cec.setMinClusterSize (cloud_with_normals->points.size () / 1000);
  cec.setMaxClusterSize (cloud_with_normals->points.size () / 5);
  cec.segment (*clusters);
  cec.getRemovedClusters (small_clusters, large_clusters);
  std::cerr << ">> Done: " << tt.toc () << " ms\n";

  // Using the intensity channel for lazy visualization of the output
  for (int i = 0; i < small_clusters->size (); ++i)
    for (int j = 0; j < (*small_clusters)[i].indices.size (); ++j)
      cloud_out->points[(*small_clusters)[i].indices[j]].intensity = -2.0;
  for (int i = 0; i < large_clusters->size (); ++i)
    for (int j = 0; j < (*large_clusters)[i].indices.size (); ++j)
      cloud_out->points[(*large_clusters)[i].indices[j]].intensity = +10.0;
  for (int i = 0; i < clusters->size (); ++i)
  {
    int label = rand () % 8;
    for (int j = 0; j < (*clusters)[i].indices.size (); ++j)
      cloud_out->points[(*clusters)[i].indices[j]].intensity = label;
  }

  // Save the output point cloud
  std::cerr << "Saving...\n", tt.tic ();
  pcl::io::savePCDFile ("output.pcd", *cloud_out);
  std::cerr << ">> Done: " << tt.toc () << " ms\n";

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(conditional_euclidean_clustering)
find_package(PCL 1.7 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (conditional_euclidean_clustering conditional_euclidean_clustering.cpp)
target_link_libraries (conditional_euclidean_clustering ${PCL_LIBRARIES})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.14 <分割> 基于法线的分割的差异(没有点云数据,不能复现)

学习:学习如何使用在pcl::DifferenceOfNormalsEstimation类中实现的“法线差异”功能对无组织点云进行基于比例的分割。

《《《总结》》》PCL的42个实例整理:1~24_第51张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/don_segmentation.html#don-segmentation

创建目录,终端运行

*****.pcd下载链接:

mkdir 14
cd 14
mkdir don_segmentation
cd don_segmentation
gedit don_segmentation.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载*****.pcd放到./14/don_segmentation/build目录下
#有代码包的:cp ../../*****.pcd ./
./don_segmentation

结果显示

 

代码展示

##########################################
##########################################
##########################################
don_segmentation.cpp
##########################################
##########################################
##########################################
/**
 * @file don_segmentation.cpp
 * Difference of Normals Example for PCL Segmentation Tutorials.
 *
 * @author Yani Ioannou
 * @date 2012-09-24
 */
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 

using namespace pcl;
using namespace std;

int
main (int argc, char *argv[])
{
  ///The smallest scale to use in the DoN filter.
  double scale1;

  ///The largest scale to use in the DoN filter.
  double scale2;

  ///The minimum DoN magnitude to threshold by
  double threshold;

  ///segment scene into clusters with given distance tolerance using euclidean clustering
  double segradius;

  if (argc < 6)
  {
    cerr << "usage: " << argv[0] << " inputfile smallscale largescale threshold segradius" << endl;
    exit (EXIT_FAILURE);
  }

  /// the file to read from.
  string infile = argv[1];
  /// small scale
  istringstream (argv[2]) >> scale1;
  /// large scale
  istringstream (argv[3]) >> scale2;
  istringstream (argv[4]) >> threshold;   // threshold for DoN magnitude
  istringstream (argv[5]) >> segradius;   // threshold for radius segmentation

  // Load cloud in blob format
  pcl::PCLPointCloud2 blob;
  pcl::io::loadPCDFile (infile.c_str (), blob);
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::fromPCLPointCloud2 (blob, *cloud);

  // Create a search tree, use KDTreee for non-organized data.
  pcl::search::Search::Ptr tree;
  if (cloud->isOrganized ())
  {
    tree.reset (new pcl::search::OrganizedNeighbor ());
  }
  else
  {
    tree.reset (new pcl::search::KdTree (false));
  }

  // Set the input pointcloud for the search tree
  tree->setInputCloud (cloud);

  if (scale1 >= scale2)
  {
    cerr << "Error: Large scale must be > small scale!" << endl;
    exit (EXIT_FAILURE);
  }

  // Compute normals using both small and large scales at each point
  pcl::NormalEstimationOMP ne;
  ne.setInputCloud (cloud);
  ne.setSearchMethod (tree);

  /**
   * NOTE: setting viewpoint is very important, so that we can ensure
   * normals are all pointed in the same direction!
   */
  ne.setViewPoint (std::numeric_limits::max (), std::numeric_limits::max (), std::numeric_limits::max ());

  // calculate normals with the small scale
  cout << "Calculating normals for scale..." << scale1 << endl;
  pcl::PointCloud::Ptr normals_small_scale (new pcl::PointCloud);

  ne.setRadiusSearch (scale1);
  ne.compute (*normals_small_scale);

  // calculate normals with the large scale
  cout << "Calculating normals for scale..." << scale2 << endl;
  pcl::PointCloud::Ptr normals_large_scale (new pcl::PointCloud);

  ne.setRadiusSearch (scale2);
  ne.compute (*normals_large_scale);

  // Create output cloud for DoN results
  PointCloud::Ptr doncloud (new pcl::PointCloud);
  copyPointCloud(*cloud, *doncloud);

  cout << "Calculating DoN... " << endl;
  // Create DoN operator
  pcl::DifferenceOfNormalsEstimation don;
  don.setInputCloud (cloud);
  don.setNormalScaleLarge (normals_large_scale);
  don.setNormalScaleSmall (normals_small_scale);

  if (!don.initCompute ())
  {
    std::cerr << "Error: Could not intialize DoN feature operator" << std::endl;
    exit (EXIT_FAILURE);
  }

  // Compute DoN
  don.computeFeature (*doncloud);

  // Save DoN features
  pcl::PCDWriter writer;
  writer.write ("don.pcd", *doncloud, false); 

  // Filter by magnitude
  cout << "Filtering out DoN mag <= " << threshold << "..." << endl;

  // Build the condition for filtering
  pcl::ConditionOr::Ptr range_cond (
    new pcl::ConditionOr ()
    );
  range_cond->addComparison (pcl::FieldComparison::ConstPtr (
                               new pcl::FieldComparison ("curvature", pcl::ComparisonOps::GT, threshold))
                             );
  // Build the filter
  pcl::ConditionalRemoval condrem (range_cond);
  condrem.setInputCloud (doncloud);

  pcl::PointCloud::Ptr doncloud_filtered (new pcl::PointCloud);

  // Apply filter
  condrem.filter (*doncloud_filtered);

  doncloud = doncloud_filtered;

  // Save filtered output
  std::cout << "Filtered Pointcloud: " << doncloud->points.size () << " data points." << std::endl;

  writer.write ("don_filtered.pcd", *doncloud, false); 

  // Filter by magnitude
  cout << "Clustering using EuclideanClusterExtraction with tolerance <= " << segradius << "..." << endl;

  pcl::search::KdTree::Ptr segtree (new pcl::search::KdTree);
  segtree->setInputCloud (doncloud);

  std::vector cluster_indices;
  pcl::EuclideanClusterExtraction ec;

  ec.setClusterTolerance (segradius);
  ec.setMinClusterSize (50);
  ec.setMaxClusterSize (100000);
  ec.setSearchMethod (segtree);
  ec.setInputCloud (doncloud);
  ec.extract (cluster_indices);

  int j = 0;
  for (std::vector::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it, j++)
  {
    pcl::PointCloud::Ptr cloud_cluster_don (new pcl::PointCloud);
    for (std::vector::const_iterator pit = it->indices.begin (); pit != it->indices.end (); ++pit)
    {
      cloud_cluster_don->points.push_back (doncloud->points[*pit]);
    }

    cloud_cluster_don->width = int (cloud_cluster_don->points.size ());
    cloud_cluster_don->height = 1;
    cloud_cluster_don->is_dense = true;

    //Save cluster
    cout << "PointCloud representing the Cluster: " << cloud_cluster_don->points.size () << " data points." << std::endl;
    stringstream ss;
    ss << "don_cluster_" << j << ".pcd";
    writer.write (ss.str (), *cloud_cluster_don, false);
  }
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(don_segmentation)
find_package(PCL 1.7 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (don_segmentation don_segmentation.cpp)
target_link_libraries (don_segmentation ${PCL_LIBRARIES})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.15 <分割> 将点云聚类为Supervoxels(报错误了不能复现)

学习:点云聚类为Supervoxels

《《《总结》》》PCL的42个实例整理:1~24_第52张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/supervoxel_clustering.html#supervoxel-clustering

创建目录,终端运行

mkdir 15
cd 15
gedit supervoxel_clustering.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 

./supervoxel_clustering

结果显示

 

代码展示

##########################################
##########################################
##########################################
supervoxel_clustering.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 

//VTK include needed for drawing graph lines
#include 

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

void addSupervoxelConnectionsToViewer (PointT &supervoxel_center,
                                       PointCloudT &adjacent_supervoxel_centers,
                                       std::string supervoxel_name,
                                       boost::shared_ptr & viewer);


int
main (int argc, char ** argv)
{
  if (argc < 2)
  {
    pcl::console::print_error ("Syntax is: %s  \n "
                                "--NT Dsables the single cloud transform \n"
                                "-v \n-s \n"
                                "-c  \n-z  \n"
                                "-n \n", argv[0]);
    return (1);
  }


  PointCloudT::Ptr cloud = boost::shared_ptr  (new PointCloudT ());
  pcl::console::print_highlight ("Loading point cloud...\n");
  if (pcl::io::loadPCDFile (argv[1], *cloud))
  {
    pcl::console::print_error ("Error loading cloud file!\n");
    return (1);
  }


  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);

  //  //
  // This is how to use supervoxels
  //  //

  pcl::SupervoxelClustering super (voxel_resolution, seed_resolution);
  if (disable_transform)
    super.setUseSingleCameraTransform (false);
  super.setInputCloud (cloud);
  super.setColorImportance (color_importance);
  super.setSpatialImportance (spatial_importance);
  super.setNormalImportance (normal_importance);

  std::map ::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 viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
  viewer->setBackgroundColor (0, 0, 0);

  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 (sv_normal_cloud,1,0.05f, "supervoxel_normals");

  pcl::console::print_highlight ("Getting supervoxel adjacency\n");
  std::multimap 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::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::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::iterator adjacent_itr = supervoxel_adjacency.equal_range (supervoxel_label).first;
    for ( ; adjacent_itr!=supervoxel_adjacency.equal_range (supervoxel_label).second; ++adjacent_itr)
    {
      pcl::Supervoxel::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,
                                  boost::shared_ptr & viewer)
{
  vtkSmartPointer points = vtkSmartPointer::New ();
  vtkSmartPointer cells = vtkSmartPointer::New ();
  vtkSmartPointer polyLine = vtkSmartPointer::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 polyData = vtkSmartPointer::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);
}


##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(supervoxel_clustering)

find_package(PCL 1.7 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}) 

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.16 <分割> 分割(没找到官方网址)

学习:

《《《总结》》》PCL的42个实例整理:1~24_第53张图片

官方链接:

创建目录,终端运行

samp11-utm.pcd下载链接:

mkdir 16
cd 16
gedit bare_earth.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载samp11-utm.pcd放到./16/bare_earth/build目录下
#有代码包的:cp ../../samp11-utm.pcd ./
./bare_earth

结果显示

等待时间特别长

《《《总结》》》PCL的42个实例整理:1~24_第54张图片

pcl_viewer samle_tum.pcd
ctrl+shift+t
pcl_viewer samle_tum_object.pcd
ctrl+shift+t
pcl_viewer samle_tum_ground.pcd

代码展示

##########################################
##########################################
##########################################
bare_earth.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 

int
main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud);
  pcl::PointIndicesPtr ground (new pcl::PointIndices);

  // Fill in the cloud data
  pcl::PCDReader reader;
  // Replace the path below with the path where you saved your file
  reader.read ("samp11-utm.pcd", *cloud);

  std::cerr << "Cloud before filtering: " << std::endl;
  std::cerr << *cloud << std::endl;

  // Create the filtering object
  pcl::ProgressiveMorphologicalFilter pmf;
  pmf.setInputCloud (cloud);
  pmf.setMaxWindowSize (20);
  pmf.setSlope (1.0f);
  pmf.setInitialDistance (0.5f);
  pmf.setMaxDistance (3.0f);
  pmf.extract (ground->indices);

  // Create the filtering object
  pcl::ExtractIndices extract;
  extract.setInputCloud (cloud);
  extract.setIndices (ground);
  extract.filter (*cloud_filtered);

  std::cerr << "Ground cloud after filtering: " << std::endl;
  std::cerr << *cloud_filtered << std::endl;

  pcl::PCDWriter writer;
  writer.write ("samp11-utm_ground.pcd", *cloud_filtered, false);

  // Extract non-ground returns
  extract.setNegative (true);
  extract.filter (*cloud_filtered);

  std::cerr << "Object cloud after filtering: " << std::endl;
  std::cerr << *cloud_filtered << std::endl;

  writer.write ("samp11-utm_object.pcd", *cloud_filtered, false);

  return (0);
}

##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(bare_earth)
find_package(PCL 1.7.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (bare_earth bare_earth.cpp)
target_link_libraries (bare_earth ${PCL_LIBRARIES})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.17 <分割>提取平面或球面的参数模型

学习:通过使用具有已知系数的SAC_Models来从PointCloud中提取例如平面或球面的参数模型

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/model_outlier_removal.html#model-outlier-removal

                  https://pcl.readthedocs.io/projects/tutorials/en/latest/random_sample_consensus.html#random-sample-consensus

创建目录,终端运行

mkdir 17
cd 17
gedit model_outlier_removal.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
./model_outlier_removal

结果显示

《《《总结》》》PCL的42个实例整理:1~24_第55张图片

代码展示

##########################################
##########################################
##########################################
model_outlier_removal.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 

int
main ()
{
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PointCloud::Ptr cloud_sphere_filtered (new pcl::PointCloud);

  // 1. Generate cloud data
  int noise_size = 5;
  int sphere_data_size = 10;
  cloud->width = noise_size + sphere_data_size;
  cloud->height = 1;
  cloud->points.resize (cloud->width * cloud->height);
  // 1.1 Add noise
  for (size_t i = 0; i < noise_size; ++i)
  {
    cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
  }
  // 1.2 Add sphere:
  double rand_x1 = 1;
  double rand_x2 = 1;
  for (size_t i = noise_size; i < noise_size + sphere_data_size; ++i)
  {
    // See: http://mathworld.wolfram.com/SpherePointPicking.html
    while (pow (rand_x1, 2) + pow (rand_x2, 2) >= 1)
    {
      rand_x1 = (rand () % 100) / (50.0f) - 1;
      rand_x2 = (rand () % 100) / (50.0f) - 1;
    }
    double pre_calc = sqrt (1 - pow (rand_x1, 2) - pow (rand_x2, 2));
    cloud->points[i].x = 2 * rand_x1 * pre_calc;
    cloud->points[i].y = 2 * rand_x2 * pre_calc;
    cloud->points[i].z = 1 - 2 * (pow (rand_x1, 2) + pow (rand_x2, 2));
    rand_x1 = 1;
    rand_x2 = 1;
  }

  std::cerr << "Cloud before filtering: " << std::endl;
  for (size_t i = 0; i < cloud->points.size (); ++i)
    std::cout << "    " << cloud->points[i].x << " " << cloud->points[i].y << " " << cloud->points[i].z << std::endl;

  // 2. filter sphere:
  // 2.1 generate model:
  // modelparameter for this sphere:
  // position.x: 0, position.y: 0, position.z:0, radius: 1
  pcl::ModelCoefficients sphere_coeff;
  sphere_coeff.values.resize (4);
  sphere_coeff.values[0] = 0;
  sphere_coeff.values[1] = 0;
  sphere_coeff.values[2] = 0;
  sphere_coeff.values[3] = 1;

  pcl::ModelOutlierRemoval sphere_filter;
  sphere_filter.setModelCoefficients (sphere_coeff);
  sphere_filter.setThreshold (0.05);
  sphere_filter.setModelType (pcl::SACMODEL_SPHERE);
  sphere_filter.setInputCloud (cloud);
  sphere_filter.filter (*cloud_sphere_filtered);

  std::cerr << "Sphere after filtering: " << std::endl;
  for (size_t i = 0; i < cloud_sphere_filtered->points.size (); ++i)
    std::cout << "    " << cloud_sphere_filtered->points[i].x << " " << cloud_sphere_filtered->points[i].y << " " << cloud_sphere_filtered->points[i].z
        << std::endl;

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(model_outlier_removal)
find_package(PCL 1.7 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (model_outlier_removal model_outlier_removal.cpp)
target_link_libraries (model_outlier_removal ${PCL_LIBRARIES})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.18 <分割> 分割

学习:使用移动最小二乘(MLS)曲面重构方法来平滑和重采样嘈杂的数据。

《《《总结》》》PCL的42个实例整理:1~24_第56张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/resampling.html#moving-least-squares

bun0.pcd:https://raw.githubusercontent.com/PointCloudLibrary/pcl/master/test/bun0.pcd

创建目录,终端运行

bun0.pcd下载链接:

mkdir 18
cd 18
gedit resampling.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载bun0.pcd放到./18/resampling/build目录下
#有代码包的:cp ../../bun0.pcd ./
./resampling

结果显示

代码展示

##########################################
##########################################
##########################################
resampling.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 

int
main (int argc, char** argv)
{
  // Load input file into a PointCloud with an appropriate type
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud ());
  // Load bun0.pcd -- should be available with the PCL archive in test 
  pcl::io::loadPCDFile ("bun0.pcd", *cloud);

  // Create a KD-Tree
  pcl::search::KdTree::Ptr tree (new pcl::search::KdTree);

  // Output has the PointNormal type in order to store the normals calculated by MLS
  pcl::PointCloud mls_points;

  // Init object (second point type is for the normals, even if unused)
  pcl::MovingLeastSquares mls;
 
  mls.setComputeNormals (true);

  // Set parameters
  mls.setInputCloud (cloud);
  mls.setPolynomialFit (true);
  mls.setSearchMethod (tree);
  mls.setSearchRadius (0.03);

  // Reconstruct
  mls.process (mls_points);

  // Save output
  pcl::io::savePCDFile ("bun0-mls.pcd", mls_points);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(resampling)
find_package(PCL 1.2 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable (resampling resampling.cpp)
target_link_libraries (resampling ${PCL_LIBRARIES})

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.19 <分割> 为平面模型构造凹凸的船体多边形

学习:学习如何为平面所支持的一组点计算简单的2D船体多边形(凹面或凸面)

concave_hull_2d

《《《总结》》》PCL的42个实例整理:1~24_第57张图片

convex_hull_2d

《《《总结》》》PCL的42个实例整理:1~24_第58张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/hull_2d.html#hull-2d

创建目录,终端运行

table_scene_mug_stereo_textured.pcd下载链接:https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_mug_stereo_textured.pcd

mkdir 19
cd 19
mkdir concave_hull_2d
gedit concave_hull_2d.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载table_scene_mug_stereo_textured.pcd放到./19/concave_hull_2d/build目录下
#有代码包的:cp ../../table_scene_mug_stereo_textured.pcd ./
./concave_hull_2d


cd ..
mkdir convex_hull_2d
gedit convex_hull_2d.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载table_scene_mug_stereo_textured.pcd放到./19/convex_hull_2d/build目录下
#有代码包的:cp ../../table_scene_mug_stereo_textured.pcd ./
./convex_hull_2d

结果显示

pcl_viewer bun0.pcd
ctrl+shift+t
pcl_viewer bun0-mls.pcd

代码展示

##########################################
##########################################
##########################################
concave_hull_2d.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int
main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud), 
                                      cloud_filtered (new pcl::PointCloud), 
                                      cloud_projected (new pcl::PointCloud);
  pcl::PCDReader reader;

  reader.read ("table_scene_mug_stereo_textured.pcd", *cloud);
  // Build a filter to remove spurious NaNs
  pcl::PassThrough pass;
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0, 1.1);
  pass.filter (*cloud_filtered);
  std::cerr << "PointCloud after filtering has: "
            << cloud_filtered->points.size () << " data points." << std::endl;

  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
  // Create the segmentation object
  pcl::SACSegmentation seg;
  // Optional
  seg.setOptimizeCoefficients (true);
  // Mandatory
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setDistanceThreshold (0.01);

  seg.setInputCloud (cloud_filtered);
  seg.segment (*inliers, *coefficients);
  std::cerr << "PointCloud after segmentation has: "
            << inliers->indices.size () << " inliers." << std::endl;

  // Project the model inliers
  pcl::ProjectInliers proj;
  proj.setModelType (pcl::SACMODEL_PLANE);
  proj.setIndices (inliers);
  proj.setInputCloud (cloud_filtered);
  proj.setModelCoefficients (coefficients);
  proj.filter (*cloud_projected);
  std::cerr << "PointCloud after projection has: "
            << cloud_projected->points.size () << " data points." << std::endl;

  // Create a Concave Hull representation of the projected inliers
  pcl::PointCloud::Ptr cloud_hull (new pcl::PointCloud);
  pcl::ConcaveHull chull;
  chull.setInputCloud (cloud_projected);
  chull.setAlpha (0.1);
  chull.reconstruct (*cloud_hull);

  std::cerr << "Concave hull has: " << cloud_hull->points.size ()
            << " data points." << std::endl;

  pcl::PCDWriter writer;
  writer.write ("table_scene_mug_stereo_textured_hull.pcd", *cloud_hull, false);

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(concave_hull_2d)

find_package(PCL 1.2 REQUIRED)

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

add_executable (concave_hull_2d concave_hull_2d.cpp)
target_link_libraries (concave_hull_2d ${PCL_LIBRARIES})
##########################################
##########################################
##########################################
convex_hull_2d.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int
 main (int argc, char** argv)
{
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud), cloud_filtered (new pcl::PointCloud), cloud_projected (new pcl::PointCloud);
  pcl::PCDReader reader;
  reader.read ("table_scene_mug_stereo_textured.pcd", *cloud);

  // Build a filter to remove spurious NaNs
  pcl::PassThrough pass;
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0, 1.1);
  pass.filter (*cloud_filtered);
  std::cerr << "PointCloud after filtering has: " << cloud_filtered->points.size () << " data points." << std::endl;

  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
  // Create the segmentation object
  pcl::SACSegmentation seg;
  // Optional
  seg.setOptimizeCoefficients (true);
  // Mandatory
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setDistanceThreshold (0.01);

  seg.setInputCloud (cloud_filtered);
  seg.segment (*inliers, *coefficients);

  // Project the model inliers
  pcl::ProjectInliers proj;
  proj.setModelType (pcl::SACMODEL_PLANE);
  proj.setInputCloud (cloud_filtered);
  proj.setIndices (inliers);
  proj.setModelCoefficients (coefficients);
  proj.filter (*cloud_projected);

  // Create a Convex Hull representation of the projected inliers
  pcl::PointCloud::Ptr cloud_hull (new pcl::PointCloud);
  pcl::ConvexHull chull;
  chull.setInputCloud (cloud_projected);
  chull.reconstruct (*cloud_hull);

  std::cerr << "Convex hull has: " << cloud_hull->points.size () << " data points." << std::endl;

  pcl::PCDWriter writer;
  writer.write ("table_scene_mug_stereo_textured_hull.pcd", *cloud_hull, false);

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(convex_hull_2d)

find_package(PCL 1.2 REQUIRED)

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

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

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.20 <分割> 无序点云的快速三角剖分

学习:该方法通过维护可从其扩展网格的点的列表(“边缘”点)并将其扩展到连接所有可能的点来起作用。它可以处理来自一次或多次扫描并具有多个相连部分的无组织点。如果表面局部光滑并且在具有不同点密度的区域之间存在平滑过渡,则效果最佳。

《《《总结》》》PCL的42个实例整理:1~24_第59张图片官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/greedy_projection.html#greedy-triangulation

创建目录,终端运行

bun0.pcd下载链接:pcl / test / bun0.pcd中找到输入文件

mkdir 20
cd 20
mkdir greedy_projection
gedit greedy_projection.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载bun0.pcd放到./20/greedy_projection/build目录下
#有代码包的:cp ../../bun0.pcd ./
./greedy_projection

结果显示

pcl_viewer bun0.pcd
ctrl+shift+t
pcl_viewer mesh.vtk

代码展示

##########################################
##########################################
##########################################
greedy_projection.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 

int
main (int argc, char** argv)
{
  // Load input file into a PointCloud with an appropriate type
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PCLPointCloud2 cloud_blob;
  pcl::io::loadPCDFile ("bun0.pcd", cloud_blob);
  pcl::fromPCLPointCloud2 (cloud_blob, *cloud);
  //* the data should be available in cloud

  // Normal estimation*
  pcl::NormalEstimation n;
  pcl::PointCloud::Ptr normals (new pcl::PointCloud);
  pcl::search::KdTree::Ptr tree (new pcl::search::KdTree);
  tree->setInputCloud (cloud);
  n.setInputCloud (cloud);
  n.setSearchMethod (tree);
  n.setKSearch (20);
  n.compute (*normals);
  //* normals should not contain the point normals + surface curvatures

  // Concatenate the XYZ and normal fields*
  pcl::PointCloud::Ptr cloud_with_normals (new pcl::PointCloud);
  pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
  //* cloud_with_normals = cloud + normals

  // Create search tree*
  pcl::search::KdTree::Ptr tree2 (new pcl::search::KdTree);
  tree2->setInputCloud (cloud_with_normals);

  // Initialize objects
  pcl::GreedyProjectionTriangulation gp3;
  pcl::PolygonMesh triangles;

  // Set the maximum distance between connected points (maximum edge length)
  gp3.setSearchRadius (0.025);

  // Set typical values for the parameters
  gp3.setMu (2.5);
  gp3.setMaximumNearestNeighbors (100);
  gp3.setMaximumSurfaceAngle(M_PI/4); // 45 degrees
  gp3.setMinimumAngle(M_PI/18); // 10 degrees
  gp3.setMaximumAngle(2*M_PI/3); // 120 degrees
  gp3.setNormalConsistency(false);

  // Get result
  gp3.setInputCloud (cloud_with_normals);
  gp3.setSearchMethod (tree2);
  gp3.reconstruct (triangles);

  // Additional vertex information
  std::vector parts = gp3.getPartIDs();
  std::vector states = gp3.getPointStates();
  
  pcl::io::saveVTKFile ("mesh.vtk", triangles);

  // Finish
  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(greedy_projection)

find_package(PCL 1.2 REQUIRED)

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

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

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.21 <分割> 将修剪的B样条曲线拟合到无序点云

学习:在点云上运行B样条拟合算法,以获得平滑的参数化曲面表示形式

结果图

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/bspline_fitting.html#bspline-fitting

创建目录,终端运行

bunny.pcd下载链接:

mkdir 21
cd 21
mkdir bspline_fitting
gedit bunny.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载bunny.pcd放到./20/bspline_fitting/build目录下
#有代码包的:cp ../../bunny.pcd ./
./bspline_fitting

结果显示

代码展示

##########################################
##########################################
##########################################
bspline_fitting.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 

#include 
#include 
#include 
#include 

typedef pcl::PointXYZ Point;

void
PointCloud2Vector3d (pcl::PointCloud::Ptr cloud, pcl::on_nurbs::vector_vec3d &data);

void
visualizeCurve (ON_NurbsCurve &curve,
                ON_NurbsSurface &surface,
                pcl::visualization::PCLVisualizer &viewer);

int
main (int argc, char *argv[])
{
  std::string pcd_file, file_3dm;

  if (argc < 3)
  {
    printf ("\nUsage: pcl_example_nurbs_fitting_surface pcd-in-file 3dm-out-file\n\n");
    exit (0);
  }
  pcd_file = argv[1];
  file_3dm = argv[2];

  pcl::visualization::PCLVisualizer viewer ("B-spline surface fitting");
  viewer.setSize (800, 600);

  // ############################################################################
  // load point cloud

  printf ("  loading %s\n", pcd_file.c_str ());
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::PCLPointCloud2 cloud2;
  pcl::on_nurbs::NurbsDataSurface data;

  if (pcl::io::loadPCDFile (pcd_file, cloud2) == -1)
    throw std::runtime_error ("  PCD file not found.");

  fromPCLPointCloud2 (cloud2, *cloud);
  PointCloud2Vector3d (cloud, data.interior);
  pcl::visualization::PointCloudColorHandlerCustom handler (cloud, 0, 255, 0);
  viewer.addPointCloud (cloud, handler, "cloud_cylinder");
  printf ("  %lu points in data set\n", cloud->size ());

  // ############################################################################
  // fit B-spline surface

  // parameters
  unsigned order (3);
  unsigned refinement (5);
  unsigned iterations (10);
  unsigned mesh_resolution (256);

  pcl::on_nurbs::FittingSurface::Parameter params;
  params.interior_smoothness = 0.2;
  params.interior_weight = 1.0;
  params.boundary_smoothness = 0.2;
  params.boundary_weight = 0.0;

  // initialize
  printf ("  surface fitting ...\n");
  ON_NurbsSurface nurbs = pcl::on_nurbs::FittingSurface::initNurbsPCABoundingBox (order, &data);
  pcl::on_nurbs::FittingSurface fit (&data, nurbs);
  //  fit.setQuiet (false); // enable/disable debug output

  // mesh for visualization
  pcl::PolygonMesh mesh;
  pcl::PointCloud::Ptr mesh_cloud (new pcl::PointCloud);
  std::vector mesh_vertices;
  std::string mesh_id = "mesh_nurbs";
  pcl::on_nurbs::Triangulation::convertSurface2PolygonMesh (fit.m_nurbs, mesh, mesh_resolution);
  viewer.addPolygonMesh (mesh, mesh_id);

  // surface refinement
  for (unsigned i = 0; i < refinement; i++)
  {
    fit.refine (0);
    fit.refine (1);
    fit.assemble (params);
    fit.solve ();
    pcl::on_nurbs::Triangulation::convertSurface2Vertices (fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);
    viewer.updatePolygonMesh (mesh_cloud, mesh_vertices, mesh_id);
    viewer.spinOnce ();
  }

  // surface fitting with final refinement level
  for (unsigned i = 0; i < iterations; i++)
  {
    fit.assemble (params);
    fit.solve ();
    pcl::on_nurbs::Triangulation::convertSurface2Vertices (fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);
    viewer.updatePolygonMesh (mesh_cloud, mesh_vertices, mesh_id);
    viewer.spinOnce ();
  }

  // ############################################################################
  // fit B-spline curve

  // parameters
  pcl::on_nurbs::FittingCurve2dAPDM::FitParameter curve_params;
  curve_params.addCPsAccuracy = 5e-2;
  curve_params.addCPsIteration = 3;
  curve_params.maxCPs = 200;
  curve_params.accuracy = 1e-3;
  curve_params.iterations = 100;

  curve_params.param.closest_point_resolution = 0;
  curve_params.param.closest_point_weight = 1.0;
  curve_params.param.closest_point_sigma2 = 0.1;
  curve_params.param.interior_sigma2 = 0.00001;
  curve_params.param.smooth_concavity = 1.0;
  curve_params.param.smoothness = 1.0;

  // initialisation (circular)
  printf ("  curve fitting ...\n");
  pcl::on_nurbs::NurbsDataCurve2d curve_data;
  curve_data.interior = data.interior_param;
  curve_data.interior_weight_function.push_back (true);
  ON_NurbsCurve curve_nurbs = pcl::on_nurbs::FittingCurve2dAPDM::initNurbsCurve2D (order, curve_data.interior);

  // curve fitting
  pcl::on_nurbs::FittingCurve2dASDM curve_fit (&curve_data, curve_nurbs);
  // curve_fit.setQuiet (false); // enable/disable debug output
  curve_fit.fitting (curve_params);
  visualizeCurve (curve_fit.m_nurbs, fit.m_nurbs, viewer);

  // ############################################################################
  // triangulation of trimmed surface

  printf ("  triangulate trimmed surface ...\n");
  viewer.removePolygonMesh (mesh_id);
  pcl::on_nurbs::Triangulation::convertTrimmedSurface2PolygonMesh (fit.m_nurbs, curve_fit.m_nurbs, mesh,
                                                                   mesh_resolution);
  viewer.addPolygonMesh (mesh, mesh_id);


  // save trimmed B-spline surface
  if ( fit.m_nurbs.IsValid() )
  {
    ONX_Model model;
    ONX_Model_Object& surf = model.m_object_table.AppendNew();
    surf.m_object = new ON_NurbsSurface(fit.m_nurbs);
    surf.m_bDeleteObject = true;
    surf.m_attributes.m_layer_index = 1;
    surf.m_attributes.m_name = "surface";

    ONX_Model_Object& curv = model.m_object_table.AppendNew();
    curv.m_object = new ON_NurbsCurve(curve_fit.m_nurbs);
    curv.m_bDeleteObject = true;
    curv.m_attributes.m_layer_index = 2;
    curv.m_attributes.m_name = "trimming curve";

    model.Write(file_3dm.c_str());
    printf("  model saved: %s\n", file_3dm.c_str());
  }

  printf ("  ... done.\n");

  viewer.spin ();
  return 0;
}

void
PointCloud2Vector3d (pcl::PointCloud::Ptr cloud, pcl::on_nurbs::vector_vec3d &data)
{
  for (unsigned i = 0; i < cloud->size (); i++)
  {
    Point &p = cloud->at (i);
    if (!pcl_isnan (p.x) && !pcl_isnan (p.y) && !pcl_isnan (p.z))
      data.push_back (Eigen::Vector3d (p.x, p.y, p.z));
  }
}

void
visualizeCurve (ON_NurbsCurve &curve, ON_NurbsSurface &surface, pcl::visualization::PCLVisualizer &viewer)
{
  pcl::PointCloud::Ptr curve_cloud (new pcl::PointCloud);

  pcl::on_nurbs::Triangulation::convertCurve2PointCloud (curve, surface, curve_cloud, 4);
  for (std::size_t i = 0; i < curve_cloud->size () - 1; i++)
  {
    pcl::PointXYZRGB &p1 = curve_cloud->at (i);
    pcl::PointXYZRGB &p2 = curve_cloud->at (i + 1);
    std::ostringstream os;
    os << "line" << i;
    viewer.removeShape (os.str ());
    viewer.addLine (p1, p2, 1.0, 0.0, 0.0, os.str ());
  }

  pcl::PointCloud::Ptr curve_cps (new pcl::PointCloud);
  for (int i = 0; i < curve.CVCount (); i++)
  {
    ON_3dPoint p1;
    curve.GetCV (i, p1);

    double pnt[3];
    surface.Evaluate (p1.x, p1.y, 0, 3, pnt);
    pcl::PointXYZRGB p2;
    p2.x = float (pnt[0]);
    p2.y = float (pnt[1]);
    p2.z = float (pnt[2]);

    p2.r = 255;
    p2.g = 0;
    p2.b = 0;

    curve_cps->push_back (p2);
  }
  viewer.removePointCloud ("cloud_cps");
  viewer.addPointCloud (curve_cps, "cloud_cps");
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(bspline_fitting)

find_package(PCL 1.7 REQUIRED)

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

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

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.22  使用积分图像进行正态估计

学习:我们将学习如何使用积分图像为有组织的点云计算法线。

《《《总结》》》PCL的42个实例整理:1~24_第60张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/normal_estimation_using_integral_images.html#normal-estimation-using-integral-images

创建目录,终端运行

table_scene_mug_stereo_textured.pcd下载链接:未提供

mkdir 22
cd 22
mkdir normal_estimation_using_integral_images
gedit normal_estimation_using_integral_images.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载table_scene_mug_stereo_textured.pcd放到./22/normal_estimation_using_integral_images/build目录下
#有代码包的:cp ../../table_scene_mug_stereo_textured.pcd ./
./normal_estimation_using_integral_images

结果显示

代码展示

##########################################
##########################################
##########################################
normal_estimation_using_integral_images.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
    
int 
main ()
{
    // load point cloud
    pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
    pcl::io::loadPCDFile ("table_scene_mug_stereo_textured.pcd", *cloud);
    
    // estimate normals
    pcl::PointCloud::Ptr normals (new pcl::PointCloud);

    pcl::IntegralImageNormalEstimation ne;
    ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT);
    ne.setMaxDepthChangeFactor(0.02f);
    ne.setNormalSmoothingSize(10.0f);
    ne.setInputCloud(cloud);
    ne.compute(*normals);

    // visualize normals
    pcl::visualization::PCLVisualizer viewer("PCL Viewer");
    viewer.setBackgroundColor (0.0, 0.0, 0.5);
    viewer.addPointCloudNormals(cloud, normals);
    
    while (!viewer.wasStopped ())
    {
      viewer.spinOnce ();
    }
    return 0;
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)

project(normal_estimation_using_integral_images)

find_package(PCL 1.3 REQUIRED)

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

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

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.23  如何从范围图像中提取NARF特征

学习:如何从范围图像中提取NARF关键点位置的NARF描述符

《《《总结》》》PCL的42个实例整理:1~24_第61张图片

 

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/normal_estimation_using_integral_images.html#normal-estimation-using-integral-images

1.pcd :自己下载的

创建目录,终端运行

mkdir 23
cd 23
gedit narf_feature_extraction.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
./narf_feature_extraction 1.pcd

结果显示

《《《总结》》》PCL的42个实例整理:1~24_第62张图片

代码展示

##########################################
##########################################
##########################################
narf_feature_extraction.cpp
##########################################
##########################################
##########################################
/* \author Bastian Steder */

#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef pcl::PointXYZ PointType;

// --------------------
// -----Parameters-----
// --------------------
float angular_resolution = 0.5f;
float support_size = 0.2f;
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
bool setUnseenToMaxRange = false;
bool rotation_invariant = true;

// --------------
// -----Help-----
// --------------
void 
printUsage (const char* progName)
{
  std::cout << "\n\nUsage: "<\n\n"
            << "Options:\n"
            << "-------------------------------------------\n"
            << "-r    angular resolution in degrees (default "<     coordinate frame (default "<< (int)coordinate_frame<<")\n"
            << "-m           Treat all unseen points to max range\n"
            << "-s    support size for the interest points (diameter of the used sphere - "
                                                                  "default "<     switch rotational invariant version of the feature on/off"
            <<               " (default "<< (int)rotation_invariant<<")\n"
            << "-h           this help\n"
            << "\n\n";
}

void 
setViewerPose (pcl::visualization::PCLVisualizer& viewer, const Eigen::Affine3f& viewer_pose)
{
  Eigen::Vector3f pos_vector = viewer_pose * Eigen::Vector3f (0, 0, 0);
  Eigen::Vector3f look_at_vector = viewer_pose.rotation () * Eigen::Vector3f (0, 0, 1) + pos_vector;
  Eigen::Vector3f up_vector = viewer_pose.rotation () * Eigen::Vector3f (0, -1, 0);
  viewer.setCameraPosition (pos_vector[0], pos_vector[1], pos_vector[2],
                            look_at_vector[0], look_at_vector[1], look_at_vector[2],
                            up_vector[0], up_vector[1], up_vector[2]);
}

// --------------
// -----Main-----
// --------------
int 
main (int argc, char** argv)
{
  // --------------------------------------
  // -----Parse Command Line Arguments-----
  // --------------------------------------
  if (pcl::console::find_argument (argc, argv, "-h") >= 0)
  {
    printUsage (argv[0]);
    return 0;
  }
  if (pcl::console::find_argument (argc, argv, "-m") >= 0)
  {
    setUnseenToMaxRange = true;
    cout << "Setting unseen values in range image to maximum range readings.\n";
  }
  if (pcl::console::parse (argc, argv, "-o", rotation_invariant) >= 0)
    cout << "Switching rotation invariant feature version "<< (rotation_invariant ? "on" : "off")<<".\n";
  int tmp_coordinate_frame;
  if (pcl::console::parse (argc, argv, "-c", tmp_coordinate_frame) >= 0)
  {
    coordinate_frame = pcl::RangeImage::CoordinateFrame (tmp_coordinate_frame);
    cout << "Using coordinate frame "<< (int)coordinate_frame<<".\n";
  }
  if (pcl::console::parse (argc, argv, "-s", support_size) >= 0)
    cout << "Setting support size to "<= 0)
    cout << "Setting angular resolution to "<::Ptr point_cloud_ptr (new pcl::PointCloud);
  pcl::PointCloud& point_cloud = *point_cloud_ptr;
  pcl::PointCloud far_ranges;
  Eigen::Affine3f scene_sensor_pose (Eigen::Affine3f::Identity ());
  std::vector pcd_filename_indices = pcl::console::parse_file_extension_argument (argc, argv, "pcd");
  if (!pcd_filename_indices.empty ())
  {
    std::string filename = argv[pcd_filename_indices[0]];
    if (pcl::io::loadPCDFile (filename, point_cloud) == -1)
    {
      cerr << "Was not able to open file \""< Genarating example point cloud.\n\n";
    for (float x=-0.5f; x<=0.5f; x+=0.01f)
    {
      for (float y=-0.5f; y<=0.5f; y+=0.01f)
      {
        PointType point;  point.x = x;  point.y = y;  point.z = 2.0f - y;
        point_cloud.points.push_back (point);
      }
    }
    point_cloud.width = (int) point_cloud.points.size ();  point_cloud.height = 1;
  }
  
  // -----------------------------------------------
  // -----Create RangeImage from the PointCloud-----
  // -----------------------------------------------
  float noise_level = 0.0;
  float min_range = 0.0f;
  int border_size = 1;
  boost::shared_ptr range_image_ptr (new pcl::RangeImage);
  pcl::RangeImage& range_image = *range_image_ptr;   
  range_image.createFromPointCloud (point_cloud, angular_resolution, pcl::deg2rad (360.0f), pcl::deg2rad (180.0f),
                                   scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size);
  range_image.integrateFarRanges (far_ranges);
  if (setUnseenToMaxRange)
    range_image.setUnseenToMaxRange ();
  
  // --------------------------------------------
  // -----Open 3D viewer and add point cloud-----
  // --------------------------------------------
  pcl::visualization::PCLVisualizer viewer ("3D Viewer");
  viewer.setBackgroundColor (1, 1, 1);
  pcl::visualization::PointCloudColorHandlerCustom range_image_color_handler (range_image_ptr, 0, 0, 0);
  viewer.addPointCloud (range_image_ptr, range_image_color_handler, "range image");
  viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "range image");
  //viewer.addCoordinateSystem (1.0f, "global");
  //PointCloudColorHandlerCustom point_cloud_color_handler (point_cloud_ptr, 150, 150, 150);
  //viewer.addPointCloud (point_cloud_ptr, point_cloud_color_handler, "original point cloud");
  viewer.initCameraParameters ();
  setViewerPose (viewer, range_image.getTransformationToWorldSystem ());
  
  // --------------------------
  // -----Show range image-----
  // --------------------------
  pcl::visualization::RangeImageVisualizer range_image_widget ("Range image");
  range_image_widget.showRangeImage (range_image);
  
  // --------------------------------
  // -----Extract NARF keypoints-----
  // --------------------------------
  pcl::RangeImageBorderExtractor range_image_border_extractor;
  pcl::NarfKeypoint narf_keypoint_detector;
  narf_keypoint_detector.setRangeImageBorderExtractor (&range_image_border_extractor);
  narf_keypoint_detector.setRangeImage (&range_image);
  narf_keypoint_detector.getParameters ().support_size = support_size;
  
  pcl::PointCloud keypoint_indices;
  narf_keypoint_detector.compute (keypoint_indices);
  std::cout << "Found "<::Ptr keypoints_ptr (new pcl::PointCloud);
  pcl::PointCloud& keypoints = *keypoints_ptr;
  keypoints.points.resize (keypoint_indices.points.size ());
  for (size_t i=0; i keypoints_color_handler (keypoints_ptr, 0, 255, 0);
  viewer.addPointCloud (keypoints_ptr, keypoints_color_handler, "keypoints");
  viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "keypoints");
  
  // ------------------------------------------------------
  // -----Extract NARF descriptors for interest points-----
  // ------------------------------------------------------
  std::vector keypoint_indices2;
  keypoint_indices2.resize (keypoint_indices.points.size ());
  for (unsigned int i=0; i narf_descriptors;
  narf_descriptor.compute (narf_descriptors);
  cout << "Extracted "<

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

1.24  基于惯性矩和偏心率的描述符

学习:学习如何使用pcl :: MomentOfInertiaEstimation类来获取基于偏心率和惯性矩的描述符。该类还允许提取云的轴对齐和定向的边界框

《《《总结》》》PCL的42个实例整理:1~24_第63张图片《《《总结》》》PCL的42个实例整理:1~24_第64张图片

官方链接:https://pcl.readthedocs.io/projects/tutorials/en/latest/moment_of_inertia.html#moment-of-inertia

创建目录,终端运行

lamppost.pcd下载链接:https://github.com/PointCloudLibrary/data/blob/master/tutorials/min_cut_segmentation_tutorial.pcd

mkdir 24
cd 24
mkdir moment_of_inertia
gedit moment_of_inertia.cpp  ##加入代码
gedit CMakeLists.txt   ##加入代码
mkdir build
cd build 
cmake ..
make 
#下载lamppost.pcd放到./24/moment_of_inertia/build目录下
#有代码包的:cp ../../lamppost.pcd ./
./moment_of_inertia lamppost.pcd

结果显示

代码展示

##########################################
##########################################
##########################################
moment_of_inertia.cpp
##########################################
##########################################
##########################################
#include 
#include 
#include 
#include 
#include 
#include 

int main (int argc, char** argv)
{
  if (argc != 2)
    return (0);

  pcl::PointCloud::Ptr cloud (new pcl::PointCloud ());
  if (pcl::io::loadPCDFile (argv[1], *cloud) == -1)
    return (-1);

  pcl::MomentOfInertiaEstimation  feature_extractor;
  feature_extractor.setInputCloud (cloud);
  feature_extractor.compute ();

  std::vector  moment_of_inertia;
  std::vector  eccentricity;
  pcl::PointXYZ min_point_AABB;
  pcl::PointXYZ max_point_AABB;
  pcl::PointXYZ min_point_OBB;
  pcl::PointXYZ max_point_OBB;
  pcl::PointXYZ position_OBB;
  Eigen::Matrix3f rotational_matrix_OBB;
  float major_value, middle_value, minor_value;
  Eigen::Vector3f major_vector, middle_vector, minor_vector;
  Eigen::Vector3f mass_center;

  feature_extractor.getMomentOfInertia (moment_of_inertia);
  feature_extractor.getEccentricity (eccentricity);
  feature_extractor.getAABB (min_point_AABB, max_point_AABB);
  feature_extractor.getOBB (min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB);
  feature_extractor.getEigenValues (major_value, middle_value, minor_value);
  feature_extractor.getEigenVectors (major_vector, middle_vector, minor_vector);
  feature_extractor.getMassCenter (mass_center);

  boost::shared_ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
  viewer->setBackgroundColor (0, 0, 0);
  viewer->addCoordinateSystem (1.0);
  viewer->initCameraParameters ();
  viewer->addPointCloud (cloud, "sample cloud");
  viewer->addCube (min_point_AABB.x, max_point_AABB.x, min_point_AABB.y, max_point_AABB.y, min_point_AABB.z, max_point_AABB.z, 1.0, 1.0, 0.0, "AABB");

  Eigen::Vector3f position (position_OBB.x, position_OBB.y, position_OBB.z);
  Eigen::Quaternionf quat (rotational_matrix_OBB);
  viewer->addCube (position, quat, max_point_OBB.x - min_point_OBB.x, max_point_OBB.y - min_point_OBB.y, max_point_OBB.z - min_point_OBB.z, "OBB");

  pcl::PointXYZ center (mass_center (0), mass_center (1), mass_center (2));
  pcl::PointXYZ x_axis (major_vector (0) + mass_center (0), major_vector (1) + mass_center (1), major_vector (2) + mass_center (2));
  pcl::PointXYZ y_axis (middle_vector (0) + mass_center (0), middle_vector (1) + mass_center (1), middle_vector (2) + mass_center (2));
  pcl::PointXYZ z_axis (minor_vector (0) + mass_center (0), minor_vector (1) + mass_center (1), minor_vector (2) + mass_center (2));
  viewer->addLine (center, x_axis, 1.0f, 0.0f, 0.0f, "major eigen vector");
  viewer->addLine (center, y_axis, 0.0f, 1.0f, 0.0f, "middle eigen vector");
  viewer->addLine (center, z_axis, 0.0f, 0.0f, 1.0f, "minor eigen vector");

  //Eigen::Vector3f p1 (min_point_OBB.x, min_point_OBB.y, min_point_OBB.z);
  //Eigen::Vector3f p2 (min_point_OBB.x, min_point_OBB.y, max_point_OBB.z);
  //Eigen::Vector3f p3 (max_point_OBB.x, min_point_OBB.y, max_point_OBB.z);
  //Eigen::Vector3f p4 (max_point_OBB.x, min_point_OBB.y, min_point_OBB.z);
  //Eigen::Vector3f p5 (min_point_OBB.x, max_point_OBB.y, min_point_OBB.z);
  //Eigen::Vector3f p6 (min_point_OBB.x, max_point_OBB.y, max_point_OBB.z);
  //Eigen::Vector3f p7 (max_point_OBB.x, max_point_OBB.y, max_point_OBB.z);
  //Eigen::Vector3f p8 (max_point_OBB.x, max_point_OBB.y, min_point_OBB.z);

  //p1 = rotational_matrix_OBB * p1 + position;
  //p2 = rotational_matrix_OBB * p2 + position;
  //p3 = rotational_matrix_OBB * p3 + position;
  //p4 = rotational_matrix_OBB * p4 + position;
  //p5 = rotational_matrix_OBB * p5 + position;
  //p6 = rotational_matrix_OBB * p6 + position;
  //p7 = rotational_matrix_OBB * p7 + position;
  //p8 = rotational_matrix_OBB * p8 + position;

  //pcl::PointXYZ pt1 (p1 (0), p1 (1), p1 (2));
  //pcl::PointXYZ pt2 (p2 (0), p2 (1), p2 (2));
  //pcl::PointXYZ pt3 (p3 (0), p3 (1), p3 (2));
  //pcl::PointXYZ pt4 (p4 (0), p4 (1), p4 (2));
  //pcl::PointXYZ pt5 (p5 (0), p5 (1), p5 (2));
  //pcl::PointXYZ pt6 (p6 (0), p6 (1), p6 (2));
  //pcl::PointXYZ pt7 (p7 (0), p7 (1), p7 (2));
  //pcl::PointXYZ pt8 (p8 (0), p8 (1), p8 (2));

  //viewer->addLine (pt1, pt2, 1.0, 0.0, 0.0, "1 edge");
  //viewer->addLine (pt1, pt4, 1.0, 0.0, 0.0, "2 edge");
  //viewer->addLine (pt1, pt5, 1.0, 0.0, 0.0, "3 edge");
  //viewer->addLine (pt5, pt6, 1.0, 0.0, 0.0, "4 edge");
  //viewer->addLine (pt5, pt8, 1.0, 0.0, 0.0, "5 edge");
  //viewer->addLine (pt2, pt6, 1.0, 0.0, 0.0, "6 edge");
  //viewer->addLine (pt6, pt7, 1.0, 0.0, 0.0, "7 edge");
  //viewer->addLine (pt7, pt8, 1.0, 0.0, 0.0, "8 edge");
  //viewer->addLine (pt2, pt3, 1.0, 0.0, 0.0, "9 edge");
  //viewer->addLine (pt4, pt8, 1.0, 0.0, 0.0, "10 edge");
  //viewer->addLine (pt3, pt4, 1.0, 0.0, 0.0, "11 edge");
  //viewer->addLine (pt3, pt7, 1.0, 0.0, 0.0, "12 edge");

  while(!viewer->wasStopped())
  {
    viewer->spinOnce (100);
    boost::this_thread::sleep (boost::posix_time::microseconds (100000));
  }

  return (0);
}
##########################################
##########################################
##########################################
CMakeLists.txt
##########################################
##########################################
##########################################
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(moment_of_inertia)

find_package(PCL 1.8 REQUIRED)

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

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

<注>如果感觉整理麻烦,请博主吃雪糕,下载整理好的全套代码

你可能感兴趣的:(PCL,总结,pcl)