pcl 基于颜色的区域生长分割

基于颜色的区域生长分割

基于颜色的区域生长分割原理上和基于曲率,法线的分割方法是一致的,只不过比较目标换成了颜色。可以认为,同一个颜色且挨得近,是一类的可能性很大,比较适合用于室内场景分割。

尤其是复杂室内场景,颜色分割可以轻松的将连续的场景点云变成不同的物体。哪怕是高低不平的地面,设法用采样一致分割器抽掉平面,颜色分割算法对不同的颜色的物体实现分割。

算法主要分为两步:

(1)分割,当前种子点和领域点之间色差小于色差阀值的 视为一个聚类。

(2)合并,聚类之间的色差小于色差阀值和并为一个聚类 ,且当前聚类中点的数量小于聚类点数量的与最近的聚类 合并在一起。

RGB的距离:

基于颜色的区域生长分割:

基于颜色的区域生长分割原理上和基于曲率,法线的分割方法是一致的,只不过比较目标换成了颜色。可以认为,同一个颜色且挨得近,是一类的可能性很大,比较适合用于室内场景分割。尤其是复杂室内场景,颜色分割可以轻松的将连续的场·景点云变成不同的物体。哪怕是高低不平的地面,设法用采样一致分割器抽掉平面,颜色分割算法对不同的颜色的物体实现分割。

 

#include <iostream>
#include <vector>//容器
#include <pcl/point_types.h>//支持点类型
#include <pcl/io/pcd_io.h>
#include <pcl/search/search.h>
#include <pcl/search/kdtree.h>//kdtree
#include <pcl/visualization/cloud_viewer.h>//pcl可视化
#include <pcl/filters/passthrough.h>//直通滤波器
#include <pcl/segmentation/region_growing_rgb.h>//区域增长
//console模块
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>
#include <pcl/features/normal_3d.h>//法线估计
#include <pcl/visualization/pcl_visualizer.h>//pcl可视化



using namespace pcl::console;
int
main (int argc, char** argv)
{

	if(argc<2)
	{
		std::cout<<".exe xx.pcd -b_n 0 -kn 50 -st_n 30 -ct_n 0.05 -bc 0 -fc 10 -nc 0 -dt 10 -ct 6 -rt 5 -mt 600" <<endl;

		return 0;
	}
	time_t start,end,diff[5],option;
	start = time(0); 
	bool Bool_Cuting=false,b_n=false;//创建bool型变量
	int MinClusterSize=600,//设置聚类的大小为600 
		KN_normal=50;//法线估计
	float far_cuting=10,//直通滤波可接受的范围的最大值
		near_cuting=0,//直通滤波可接受的范围的最小值
		DistanceThreshold=10.0,//设置距离阈值为10
		ColorThreshold=6,//设置点与点之间的颜色容差为6
		RegionColorThreshold=5,//设置区域之间的容差为5
		SmoothnessThreshold=30.0,//设置平滑阈值为30
		CurvatureThreshold=0.05;//设置曲率阈值为0.05

	parse_argument (argc, argv, "-b_n", b_n);
	parse_argument (argc, argv, "-kn", KN_normal);//法线估计
	parse_argument (argc, argv, "-st_n", SmoothnessThreshold);//平滑阈值
	parse_argument (argc, argv, "-ct_n", CurvatureThreshold);//曲率阈值


	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, "-dt", DistanceThreshold);//距离阈值
	parse_argument (argc, argv, "-ct", ColorThreshold);//颜色容差
	parse_argument (argc, argv, "-rt", RegionColorThreshold);//区域之间的容差
	parse_argument (argc, argv, "-mt", MinClusterSize);//最小点云集切割



	//frist step load the point cloud 输入点云数据
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);//创建cloud指针
	if ( pcl::io::loadPCDFile <pcl::PointXYZRGB> (argv[1], *cloud) == -1)
	{
		std::cout << "Cloud reading failed." << std::endl;
		return (-1);
	}
	end = time(0); 
	diff[0] = difftime (end, start); 
	PCL_INFO ("\Loading pcd file takes(seconds): %d\n", diff[0]); //计算下载点云文件所花费的时间
	pcl::search::Search <pcl::PointXYZRGB>::Ptr tree = boost::shared_ptr<pcl::search::Search<pcl::PointXYZRGB> > (new pcl::search::KdTree<pcl::PointXYZRGB>);

	//Noraml estimation step(1 parameter)
	//创建共享指针
	pcl::search::Search<pcl::PointXYZRGB>::Ptr tree1 = boost::shared_ptr<pcl::search::Search<pcl::PointXYZRGB> > (new pcl::search::KdTree<pcl::PointXYZRGB>);
	pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);
	pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> normal_estimator;//法线估计 创建法线估计对象
	normal_estimator.setSearchMethod (tree);//设置搜索方式
	normal_estimator.setInputCloud (cloud);//设置输入点云
	normal_estimator.setKSearch (KN_normal);//点云法向计算时,需要搜索的近邻点大小为50
	normal_estimator.compute (*normals); //开始进行法向计算
	end = time(0); 
	diff[1] = difftime (end, start)-diff[0]; 
	PCL_INFO ("\Estimating normal takes(seconds): %d\n", diff[1]); //输出法线估计所用时间
	//Optional step: cutting away the clutter scene too far away from camera
	//可选步骤:切掉离相机太远的杂乱场景
	pcl::IndicesPtr indices (new std::vector <int>);
	if(Bool_Cuting)//是否通过z轴范围对待处理数据进行裁剪
	{

		pcl::PassThrough<pcl::PointXYZRGB> pass;//创建直通滤波器对象
		pass.setInputCloud (cloud);//设置输入点云
		pass.setFilterFieldName ("z");//过滤掉z轴范围的点云
		pass.setFilterLimits (near_cuting, far_cuting);//直通滤波可以接受的范围为(0,10)
		pass.filter (*indices);
	}
	// Region growing RGB 
	//颜色分割
	pcl::RegionGrowingRGB<pcl::PointXYZRGB> reg;//创建颜色分割对象reg
	reg.setInputCloud (cloud);
	if(Bool_Cuting)reg.setIndices (indices);
	reg.setSearchMethod (tree);
	reg.setDistanceThreshold (DistanceThreshold);
	reg.setPointColorThreshold (ColorThreshold);
	reg.setRegionColorThreshold (RegionColorThreshold);
	reg.setMinClusterSize (MinClusterSize);
	if(b_n)
	{
		reg.setSmoothModeFlag(true);
		reg.setCurvatureTestFlag(true);

		reg.setInputNormals (normals);
		reg.setSmoothnessThreshold (SmoothnessThreshold / 180.0 * M_PI);//设置平滑阈值
		reg.setCurvatureThreshold (CurvatureThreshold);
	}
	std::vector <pcl::PointIndices> clusters;
	reg.extract (clusters);//
	//计算分割时间
	end = time(0); 
	diff[2] = difftime (end, start)-diff[0]-diff[1]; 
	PCL_INFO ("\RGB region growing takes(seconds): %d\n", diff[2]); 

	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud ();
	pcl::visualization::CloudViewer viewer ("基于颜色的区域生长算法实现点云分割");
	viewer.showCloud (colored_cloud);
	/*pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("圆柱面平面分割"));*/
	while (!viewer.wasStopped())
	{
		/*viewer.spinOnce();*/
	}
		return (0);
	
}

CMakeLists文件如下所示:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(color_based_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 (color_based_region_growing_segmentation color_based_region_growing_segmentation.cpp)
target_link_libraries (color_based_region_growing_segmentation ${PCL_LIBRARIES})

Ubuntu20.04下的执行命令行为:

./region_growing_rgb_segmentation /home/liqiang/Music/6/color_based_region_growing_segmentation/source/two_human.pcd -b_n 0 -kn 50 -st_n 30 -ct_n 0.05

输出结果为:

Loading pcd file takes(seconds): 1

timating normal takes(seconds): 0

RGB region growing takes(seconds): 18

执行效果如下图所示:

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
参数化的连通区域生长PCL)是一种常用的点云分割方法,通过从种子点开始连续生长来识别和分割点云中的区域PCL首先选择一个种子点作为起始点,并将其标记为当前生长区域的一部分。然后,它会检查该种子点的邻域内的相邻点,并根据一些预定义的规则来判断它们是否属于同一个区域。这些规则可能包括点之间的距离、法向量的相似性以及表面法线之间的差异等。 如果一个相邻点被判定为属于当前生长区域,那么它将被添加到该区域中,并被标记为已被访问。然后,PCL会继续检查这个新加入区域的所有点的邻域,通过遍历这个过程,不断扩展区域的范围。 当没有更多的相邻点可以被添加到区域中时,生长过程停止。该区域中的点将被认为是一个单独的分割,并且可以用不同颜色或标签进行标记。 PCL的基于区域生长的点云分割方法的优点是可以有效地处理不规则形状和复杂的点云。通过设置适当的生长参数,可以实现对所需分割的精确控制。 然而,PCL的基于区域生长的点云分割方法也存在一些限制。在处理非常密集的点云时,生长过程可能会变得非常耗时。此外,当存在重叠的物体或存在不规则形状的区域时,该方法可能无法正确地分割点云。 总而言之,PCL的基于区域生长的点云分割方法是一种流行且有效的分割技术,可以用于处理各种点云数据,并为进一步的分析和处理提供有价值的信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

长沙有肥鱼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值