PCL 【点云分割2】

一、最小图割(可以用来分割前后景) 

1、最小图割核心代码

#include <pcl/segmentation/min_cut_segmentation.h>//最小图割相关头文件

	pcl::MinCutSegmentation<pcl::PointXYZ> seg;//创建一个PointXYZ类型的最小分割对象
	seg.setInputCloud (cloud);//设置输入点云
	if(Bool_Cuting)seg.setIndices (indices);//如果设置输入点云的索引

	pcl::PointCloud<pcl::PointXYZ>::Ptr foreground_points(new pcl::PointCloud<pcl::PointXYZ> ());//创建一个PointCloud <pcl::PointXYZRGB>共享指针并进行实例化
	pcl::PointXYZ point;//定义中心点并赋值

	point.x =C_x;//中心点坐标
	point.y = C_y;
	point.z = C_z;
	foreground_points->points.push_back(point); //前景中心点
	seg.setForegroundPoints (foreground_points);//输入前景点云(目标物体)的中心点

	seg.setSigma (Sigma);//设置平滑成本的Sigma值
	seg.setRadius (Radius);//设置背景惩罚权重的半径
	seg.setNumberOfNeighbours (NumberOfNeighbours);//设置临近点数目
	seg.setSourceWeight (SourceWeight);//设置前景惩罚权重,设置的越大则分割为前景的概率越大

	std::vector <pcl::PointIndices> clusters;//定义一个点云索引类型的向量,存放分割结果
	seg.extract (clusters);//获取分割的结果,分割结果保存在点云索引的向量中。

	std::cout << "Maximum flow is " << seg.getMaxFlow () << std::endl;//计算并输出分割期间所计算出的流值

	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = seg.getColoredCloud ();//对前景点赋予红色,对背景点赋予白色。

2、完整代码(注释)

#include <iostream>
#include <vector>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/filters/passthrough.h>
#include <pcl/segmentation/min_cut_segmentation.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>
using namespace pcl::console;
int main (int argc, char** argv)
{
	if(argc<2)
	{
		std::cout<<".exe xx.pcd -bc 1 -fc 1.0 -nc 0 -cx 68.97 -cy -18.55 -cz 0.57 -s 0.25 -r 3.0433856 -non 14 -sw 0.5"<<endl;

		return 0;
	}//如果输入参数小于1个,输出提示信息
	time_t start,end,diff[5],option; //计时相关
	start = time(0); //设置起点时刻
	int NumberOfNeighbours=14;//设置默认参数
	bool Bool_Cuting=false;//设置默认参数
	float far_cuting=1,near_cuting=0,C_x=0.071753,C_y= -0.309913,C_z=1.603000,Sigma=0.25,Radius=0.8,SourceWeight=0.5;//设置默认输入参数
	pcl::PointCloud <pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud <pcl::PointXYZ>);// 创建一个PointCloud <pcl::PointXYZ>共享指针并进行实例化,用来读入点云
	if ( pcl::io::loadPCDFile <pcl::PointXYZ> (argv[1], *cloud) == -1 )// 加载点云数据
	{
		std::cout << "Cloud reading failed." << std::endl;
		return (-1);
	}

	parse_argument (argc, argv, "-bc", Bool_Cuting);//是否使用直通滤波
	parse_argument (argc, argv, "-fc", far_cuting);//直通滤波最大距离
	parse_argument (argc, argv, "-nc", near_cuting);//直通滤波最小距离

	parse_argument (argc, argv, "-cx", C_x);//设置中心点
	parse_argument (argc, argv, "-cy", C_y);
	parse_argument (argc, argv, "-cz", C_z);

	parse_argument (argc, argv, "-s", Sigma);//设置平滑成本的Sigma值
	parse_argument (argc, argv, "-r", Radius);//设置背景惩罚权重的半径
	parse_argument (argc, argv, "-non", NumberOfNeighbours);//算法构照图时需要查找的临近点数目
	parse_argument (argc, argv, "-sw", SourceWeight);//设置输入参数方式

	pcl::IndicesPtr indices (new std::vector <int>);//创建一组索引
	if(Bool_Cuting)//判断是否需要直通滤波
	{
		pcl::PassThrough<pcl::PointXYZ> pass;//设置直通滤波器对象
		pass.setInputCloud (cloud);//设置输入点云
		pass.setFilterFieldName ("z");//设置指定过滤的维度
		pass.setFilterLimits (near_cuting, far_cuting);//设置指定纬度过滤的范围
		pass.filter (*indices);//执行滤波,保存滤波结果在上述索引中

	}
	pcl::MinCutSegmentation<pcl::PointXYZ> seg;//创建一个PointXYZ类型的最小分割对象
	seg.setInputCloud (cloud);//设置输入点云
	if(Bool_Cuting)seg.setIndices (indices);//如果设置输入点云的索引

	pcl::PointCloud<pcl::PointXYZ>::Ptr foreground_points(new pcl::PointCloud<pcl::PointXYZ> ());//创建一个PointCloud <pcl::PointXYZRGB>共享指针并进行实例化
	pcl::PointXYZ point;//定义中心点并赋值

	point.x =C_x;//中心点坐标
	point.y = C_y;
	point.z = C_z;
	foreground_points->points.push_back(point); //前景中心点
	seg.setForegroundPoints (foreground_points);//输入前景点云(目标物体)的中心点

	seg.setSigma (Sigma);//设置平滑成本的Sigma值
	seg.setRadius (Radius);//设置背景惩罚权重的半径
	seg.setNumberOfNeighbours (NumberOfNeighbours);//设置临近点数目
	seg.setSourceWeight (SourceWeight);//设置前景惩罚权重,设置的越大则分割为前景的概率越大

	std::vector <pcl::PointIndices> clusters;//定义一个点云索引类型的向量,存放分割结果
	seg.extract (clusters);//获取分割的结果,分割结果保存在点云索引的向量中。

	std::cout << "Maximum flow is " << seg.getMaxFlow () << std::endl;//计算并输出分割期间所计算出的流值

	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = seg.getColoredCloud ();//对前景点赋予红色,对背景点赋予白色。
	pcl::visualization::PCLVisualizer viewer ("PCL min_cut_seg");
	viewer.addPointCloud(colored_cloud);
	viewer.addSphere(point,Radius,122,122,0,"sphere");
	viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY,0.2,"sphere");
	viewer.addCoordinateSystem();
	
	while (!viewer.wasStopped ())
	{
		viewer.spin();
	}//进行可视化

	return (0);
}

3、可视化

白色的部分被认为是前景点

 

二、基于法线微分的分割

不太懂

1、分割部分代码

  //创建一个对象存放DoN的结果
  PointCloud<PointNormal>::Ptr doncloud (new pcl::PointCloud<PointNormal>);
  copyPointCloud<PointXYZRGB, PointNormal>(*cloud, *doncloud);

  cout << "Calculating DoN... " << endl;
  // Create DoN operator
  pcl::DifferenceOfNormalsEstimation<PointXYZRGB, PointNormal, PointNormal> 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特征向量
  don.computeFeature (*doncloud);//对输入点集,计算每一个点的DoN特征向量,并输出。结果保存至doncloud

2、完整代码(注释)

/**
 * @file don_segmentation.cpp
 * Difference of Normals Example for PCL Segmentation Tutorials.
 *
 * @author Yani Ioannou
 * @date 2012-09-24
 * @修改 2015-6-16
 */
#include <string>

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/search/organized.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d_omp.h>//利用多线程计算法向量相关头文件
#include <pcl/filters/conditional_removal.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/segmentation/impl/extract_clusters.hpp>

#include <pcl/features/don.h>
// for visualization
#include <pcl/visualization/pcl_visualizer.h>

using namespace pcl;
using namespace std;


pcl::PointCloud<pcl::PointXYZRGB>::Ptr getColoredCloud (pcl::PointCloud<pcl::PointXYZ>::Ptr input_, std::vector <pcl::PointIndices> clusters_,float r,float g,float b)
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud;

  if (!clusters_.empty ())
  {
    colored_cloud = (new pcl::PointCloud<pcl::PointXYZRGB>)->makeShared ();

    srand (static_cast<unsigned int> (time (0)));
    std::vector<unsigned char> colors;
    for (size_t i_segment = 0; i_segment < clusters_.size (); i_segment++)
    {
      colors.push_back (static_cast<unsigned char> (rand () % 256));
      colors.push_back (static_cast<unsig
PCL(Point Cloud Library),是一个开源的3D点云处理库,主要用于计算机视觉和机器人技术等领域。在C++中,PCL提供了一系列用于点云分割的工具和算法。点云分割主要是将点云数据划分为有意义的部分,比如物体、地面、障碍物等。 一些常见的点云分割方法有: 1. **基于阈值的方法**:通过设置一定的密度、距离或颜色阈值,将点云分隔成不同的区域。 2. **聚类分割**:如DBSCAN(Density-Based Spatial Clustering of Applications with Noise)算法,根据点之间的空间邻域关系进行分组。 3. **边缘检测**:识别点云中的边缘,然后沿着边缘进行分割。 4. **Region Growing**:从初始种子点开始,逐渐扩大包含相似特征点的区域。 要使用PCL进行点云分割,你需要先加载点云数据,然后选择合适的分割器(例如`pcl::ExtractIndices`),配置参数,并应用到实际的数据上。这里是一些基本步骤: ```cpp // 包含必要的头文件 #include <pcl/point_cloud.h> #include <pcl/filters/passthrough.h> #include <pcl/features/normal_3d.h> // 加载点云 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); // ... 读取数据 // 创建分割pcl::PassThrough<pcl::PointXYZ> pass; pass.setInputCloud(cloud); // 设置分割条件,例如只保留高度在某个范围内的点 pass.setFilterFieldName ("z"); pass.setFilterLimits (min_height, max_height); // 应用分割 pass.filter (*cloud); // 使用其他分割方法,如KMeans、RANSAC分割等 ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tech沉思录

点赞加投币,感谢您的资瓷~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值