pcl 区域生长算法(三)

区域生长算法:(聚类)

将具有相似性的点云集合起来构成区域。首先对每个需要分割的区域找出一个种子点作为生长的起点,然后将种子点周围邻域中与种子有相同或相似性质的点合并到种子像素所在的区域中。而新的点继续作为种子向四周生长,直到再没有满足条件的像素可以包括进来,一个区域就生长而成了。

我把它理解为往水里扔石子后水波向周围扩散一样当扩散到一定的区域后水波就会停止。

算法流程:

1. 计算法线normal和曲率curvatures,依据曲率升序排序;

2. 选择曲率最低的为初始种子点,种子周围的临近点和种子点云相比较;

3. 法线的方向是否足够相近(法线夹角足够rpy),法线夹角阈值;

4. 曲率是否足够小(表面处在同一个弯曲程度),区域差值阈值;

5. 如果满足2,3则该点可用做种子点;

6. 如果只满足2,则归类而不做种子。

代码所使用的点云文件:

链接:https://pan.baidu.com/s/1WZ_BJs2kGNEZQUsN-aMwVQ 
提取码:6666

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL)
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/segmentation/region_growing.h>//区域生长分割
#include <pcl/features/normal_3d.h>//法线特征估计
#include <pcl/kdtree/kdtree.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <iostream>
#include <vector>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/extract_indices.h>

using namespace pcl;
using namespace std;
typedef PointXYZ PoinT;
int *rand_rgb() {//随机产生颜色
	int *rgb = new int[3];
	rgb[0] = rand() % 255;
	rgb[1] = rand() % 255;
	rgb[2] = rand() % 255;
	return rgb;
}
int main() {
	PointCloud<PoinT>::Ptr cloud(new PointCloud<PoinT>);
	if (io::loadPCDFile("D:\\pclcode\\pcl_segmentation\\region_growing_segmentation2\\source\\scan_003.pcd", *cloud) == -1) {
		PCL_ERROR("read false");
	}
	//降采样
	VoxelGrid<PoinT> vox;
	PointCloud<PoinT>::Ptr vox_cloud(new PointCloud<PoinT>);
	vox.setInputCloud(cloud);
	vox.setLeafSize(0.25, 0.25, 0.25);
	vox.filter(*vox_cloud);//执行滤波,并将结果保存在vox_cloud中
	//去噪声
	StatisticalOutlierRemoval<PoinT>sor;
	PointCloud<PoinT>::Ptr sor_cloud(new PointCloud<PoinT>);
	sor.setInputCloud(vox_cloud);
	sor.setMeanK(20);//设置考虑查询点临近个数为20
	sor.setStddevMulThresh(0.02);//设置判断是否为离群点的阈值为0.02
	sor.filter(*sor_cloud);//执行滤波,并将结果保存在sor_cloud中
	//法向量求解
	NormalEstimation<PoinT, Normal> ne;//创建法向量对象
	search::KdTree<PoinT>::Ptr tree(new search::KdTree<PoinT>);
	PointCloud<Normal>::Ptr normal_cloud(new PointCloud<Normal>);
	ne.setInputCloud(sor_cloud);//设置输入点云
	ne.setKSearch(20);//设置kdtree搜索距离
	ne.setSearchMethod(tree);//设置搜索方式
	ne.compute(*normal_cloud);//进行法向量求解
	//基于法向量和曲率的区域生长算法
	PointCloud<PoinT>::Ptr reg_cloud(new PointCloud<PoinT>);//创建reg_cloud指针
	RegionGrowing<PoinT, Normal> reg;//创建区域生长算法分割对象
	reg.setInputCloud(sor_cloud);//设置输入点云
	reg.setSearchMethod(tree);//设置搜索方式
	reg.setNumberOfNeighbours(20);//设置所搜邻域点的个数
	reg.setMinClusterSize(50);//最小聚类的点数
	reg.setMaxClusterSize(100000);//最大聚类的点数
	reg.setSmoothnessThreshold(3.0 / 180 * M_PI);//设置平滑度 法线插值阈值
	reg.setCurvatureThreshold(1.0);//设置曲率的阈值
	reg.setInputNormals(normal_cloud);//输入的法线

	vector<PointIndices>clusters;
	reg.extract(clusters);
	ExtractIndices<PoinT>ext;
	visualization::PCLVisualizer::Ptr viewer(new visualization::PCLVisualizer("Result of RegionGrowing"));
	for (int iter = 0; iter < clusters.size(); iter++)
	{
		//调用方式 将索引汇总
		PointCloud<PoinT>::Ptr final_cloud(new PointCloud<PoinT>);
		vector<int> inlier = clusters[iter].indices;
		//提取每个索引对应得点云并展示
		boost::shared_ptr<vector<int>>index = boost::make_shared<vector<int>>(inlier);
		ext.setInputCloud(sor_cloud);
		ext.setIndices(index);
		ext.setNegative(false);
		ext.filter(*final_cloud);//执行索引,并将结果保存在final_cloud中

		stringstream ss;
		ss << "D:\\pclcode\\pcl_segmentation\\region_growing_segmentation2\\source\\" << "RegionGrowing_clouds" << iter << ".pcd";
		//io::savePCDFileASCII(ss.str(), *copy_cloud);
		int *rgb = rand_rgb();//随机生成0-255的颜色值
		visualization::PointCloudColorHandlerCustom<PoinT>rgb1(final_cloud, rgb[0], rgb[1], rgb[2]);//提取的平面不同彩色展示
		delete[]rgb;
		viewer->addPointCloud(final_cloud, rgb1, ss.str());
		viewer->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 2, ss.str());//设置点的大小
	}
	viewer->spin();

	return 0;

CmakeLists文件:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(region_growing_segmentation2)
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})

0.3 0.3 0.3

0.25 0.25 0.25

点大小为2

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

长沙有肥鱼

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值