PCL_BoundaryEstimation边界提取

pcl::BoundaryEstimation用于散乱点云的边界提取,但应该只适用于简单的点云,过于复杂的话效果应该不太好。同时,需要pcl::NormalEstimation先计算法线,算起来也挺慢的。

https://download.csdn.net/download/qq_32867925/10184934  这个资源里有一个文献可以参考理解

获取采样点的近邻点作为局部型面参考数据,以最小二乘法拟合该数据的微切平面,并将其向微切平面投影,根据采样点与其k近邻所对应投影点连线的最大夹角识别散乱点云边界特征。

文献中算法效果,可以看出有些许的改进。

资源代码结果:


pcl源代码:

#include <iostream>
#include <pcl/console/parse.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/features/boundary.h>
#include <math.h>
#include <boost/make_shared.hpp>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/pcd_io.h>

#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/features/normal_3d.h>

#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/covariance_sampling.h>
#include <pcl/filters/normal_space.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/boundary.h>
#include <pcl/io/ply_io.h>


int estimateBorders(pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud,float re,float reforn) 
{ 

	pcl::PointCloud<pcl::Boundary> boundaries; 
	//使用角度标准确定一组点是否位于边界上。该代码利用输入数据集中每个点估计的表面法线
	pcl::BoundaryEstimation<pcl::PointXYZ, pcl::Normal, pcl::Boundary> boundEst; 
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normEst; 
	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); 
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary (new pcl::PointCloud<pcl::PointXYZ>); 
	normEst.setInputCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr(cloud)); 
	normEst.setRadiusSearch(reforn); 
	normEst.compute(*normals); 

	boundEst.setInputCloud(cloud); 
	boundEst.setInputNormals(normals); 
	boundEst.setRadiusSearch(re); 
	boundEst.setAngleThreshold(M_PI/4); 
	boundEst.setSearchMethod(pcl::search::KdTree<pcl::PointXYZ>::Ptr (new pcl::search::KdTree<pcl::PointXYZ>)); 
	boundEst.compute(boundaries); 

	for(int i = 0; i < cloud->points.size(); i++) 
	{ 
		
		if(boundaries[i].boundary_point > 0) 
		{ 
			cloud_boundary->push_back(cloud->points[i]); 
		} 
	} 

	boost::shared_ptr<pcl::visualization::PCLVisualizer> MView (new pcl::visualization::PCLVisualizer ("点云库PCL从入门到精通案例"));
	
	int v1(0); 
	MView->createViewPort (0.0, 0.0, 0.5, 1.0, v1); 
	MView->setBackgroundColor (0.3, 0.3, 0.3, v1); 
	MView->addText ("Raw point clouds", 10, 10, "v1_text", v1); 
	int v2(0); 
	MView->createViewPort (0.5, 0.0, 1, 1.0, v2); 
	MView->setBackgroundColor (0.5, 0.5, 0.5, v2); 
	MView->addText ("Boudary point clouds", 10, 10, "v2_text", v2); 

	MView->addPointCloud<pcl::PointXYZ> (cloud, "sample cloud",v1);
	MView->addPointCloud<pcl::PointXYZ> (cloud_boundary, "cloud_boundary",v2);
	MView->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_COLOR, 1,0,0, "sample cloud",v1);
	MView->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_COLOR, 0,1,0, "cloud_boundary",v2);
	MView->addCoordinateSystem (1.0);
	MView->initCameraParameters ();

	MView->spin();

	return 0; 
} 
int
	main(int argc, char** argv)
{
	//是以当前时间为种子,产生随意数。
	//其中,time(NULL)用来获取当前时间,本质上得到的是一个大整数,然后用这个数来随机数。
	//https://www.cnblogs.com/hangaozu/p/8280397.html 介绍这个函数
	srand(time(NULL));

	float re,reforn;
	re=std::atof(argv[2]);//把字符串转换成浮点数
	reforn=std::atof(argv[3]);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_src (new pcl::PointCloud<pcl::PointXYZ>); 
	pcl::io::loadPCDFile (argv[1], *cloud_src);	
	estimateBorders(cloud_src,re,reforn);

	return 0;
}

结果:

猜你喜欢

转载自blog.csdn.net/yamgyutou/article/details/105493259