PCL教程-几种常见采样方法

目录

 常用采样方法简介

下采样

均匀采样

增采样

实验代码

 实验结果

原始点云

下采样处理

均匀采样处理 

增采样处理 


 常用采样方法简介

下采样

一般下采样是通过构造一个三维体素栅格,然后在每个体素内用体素内的所有点的重心近似显示体素中的其他点,这样体素内所有点就用一个重心点来表示,进行下采样的来达到滤波的效果,这样就大大的减少了数据量,特别是在配准,曲面重建等工作之前作为预处理,可以很好的提高程序的运行速度

均匀采样

这个类基本上是相同的,但它输出的点云索引是选择的关键点在计算描述子的常见方式。

增采样

增采样是一种表面重建方法,当你有比你想象的要少的点云数据时,增采样可以帮你恢复原有的表面(S),通过内插你目前拥有的点云数据,这是一个复杂的猜想假设的过程。所以构建的结果不会百分之一百准确,但有时它是一种可选择的方案。

实验代码

#include<pcl/visualization/cloud_viewer.h>
#include<pcl/visualization/pcl_visualizer.h>
#include<pcl/visualization/point_cloud_color_handlers.h>
#include<pcl/keypoints/uniform_sampling.h>
#include<pcl/surface/mls.h>
#include<iostream>
#include<pcl/io/io.h>
#include<pcl/io/pcd_io.h>
#include<pcl/filters/voxel_grid.h>
#include <pcl/common/common_headers.h>
#include <pcl/features/normal_3d.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>


using namespace std;

//下采样 down_sampling
void down_sampling(pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr dest_cloud)
{
	//创建滤波对象
	pcl::VoxelGrid<pcl::PointXYZ> filter;
	//设置需要过滤的点云
	filter.setInputCloud(source_cloud);

	//设置滤波时创建的体素体积为1cm的立方体
	//设置体素栅格的大小:1*1*1 cm
	filter.setLeafSize(0.01f, 0.01f, 0.01f);
	//执行滤波处理,储存输出点云 
	filter.filter(*dest_cloud);
}

//均匀采样 uniform_sampling
void uniform_sampling(pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr dest_cloud)
{
	//创建滤波对象
	pcl::UniformSampling<pcl::PointXYZ> filter;
	//设置需要过滤的点云
	filter.setInputCloud(source_cloud);

	//设置滤波时创建的体素体积为1cm的立方体
	filter.setRadiusSearch(0.01f);
	//执行滤波处理,储存输出点云 
	filter.filter(*dest_cloud);
}

//增采样表面重建
void up_sampling(pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr dest_cloud)
{
	//滤波对象
	pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ> filter;
	filter.setInputCloud(source_cloud);
	//建立搜索对象
	pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree;
	filter.setSearchMethod(kdtree);
	//设置搜索域的半径为3cm
	filter.setSearchRadius(0.03);
	//Up sampling 采样方法有:DISTINCT_CLOUD, RANDOM_UNIFORM_DENSITY
	filter.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ>::SAMPLE_LOCAL_PLANE);
	//采样的半径是
	filter.setUpsamplingRadius(0.03);
	//采样的步数大小
	filter.setUpsamplingStepSize(0.02);

	filter.process(*dest_cloud);

}

int main(int argc, char** argv)
{
	//加载点云文件到点云对象
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr down_sampling_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr uniform_sampling_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr up_sampling_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	if(argc < 2)
	{
		pcl::io::loadPCDFile<pcl::PointXYZ>("D:\\PCLProject\\cloud_sampling\\cmake_bin\\Debug\\bunny.pcd", *cloud);
	}
	else
	{
		if (pcl::io::loadPCDFile <pcl::PointXYZ>(argv[1], *cloud) == -1)
		{
			std::cout << "Cloud reading failed." << std::endl;
			return (-1);
		}// 加载输入点云数据
	}
	//下采样
	down_sampling(cloud, down_sampling_cloud);
	//均匀采样
	uniform_sampling(cloud, uniform_sampling_cloud);
	//增量采样
	up_sampling(cloud, up_sampling_cloud);

	//==================显示部分
	//创建viewer对象
	pcl::visualization::PCLVisualizer viewer("Cloud Sampling Viewer");//传入的字符串为窗口的名字
	
	int v1(1);
	int v2(2);
	int v3(3);
	int v4(4);
	viewer.createViewPort(0.0, 0.0, 0.5, 0.5, v1);
	viewer.setBackgroundColor(0, 0, 0, v1);

	viewer.createViewPort(0.5, 0.0, 1.0, 0.5, v2);
	viewer.setBackgroundColor(0, 0, 0, v2);

	viewer.createViewPort(0.0, 0.5, 0.5, 1.0, v3);
	viewer.setBackgroundColor(0, 0, 0, v3);

	viewer.createViewPort(0.5, 0.5, 1.0, 1.0, v4);
	viewer.setBackgroundColor(0, 0, 0, v4);

	// The color we will be using

	float bckgr_gray_level = 0.0;  // Black    设置背景颜色
	float txt_gray_lvl = 1.0 - bckgr_gray_level;

	// Original point cloud is white
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_in_color_h(cloud, (int)255 * txt_gray_lvl, (int)255 * txt_gray_lvl, (int)255 * txt_gray_lvl);
	viewer.addPointCloud(cloud, cloud_in_color_h, "cloud_in_v1", v1);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_green(down_sampling_cloud, 0, 255, 0);      // 显示绿色点云
	viewer.addPointCloud(down_sampling_cloud, cloud_out_green, "down_sampling_cloud", v2);

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_orage(uniform_sampling_cloud, 255, 0, 0);     //显示红色点云
	viewer.addPointCloud(uniform_sampling_cloud, cloud_out_orage, "uniform_sampling_cloud", v3);

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_purple(up_sampling_cloud, 255, 0, 255);
	viewer.addPointCloud(up_sampling_cloud, cloud_out_purple, "up_sampling_cloud", v4);

	//打印点云信息
	cout << "原始点云信息:" << endl;
	cout << "width = " << cloud->width << " , height = " << cloud->height << endl;
	cout << "下采样处理后:" << endl;
	cout << "width = " << down_sampling_cloud->width << " , height = " << down_sampling_cloud->height << endl;
	cout << "均匀采样处理后:" << endl;
	cout << "width = " << uniform_sampling_cloud->width << " , height = " << uniform_sampling_cloud->height << endl;
	cout << "增采样处理后:" << endl;
	cout << "width = " << up_sampling_cloud->width << " , height = " << up_sampling_cloud->height << endl;

	viewer.spin();
	//while (!viewer.wasStopped())
	//{
	//	//在此处可以添加其他处理
	//	viewer.spinOnce();
	//	
	//} 

	// 单个窗口显示
	pcl::visualization::PCLVisualizer origin_viewer("origin_viewer");
	origin_viewer.addPointCloud(cloud);
	origin_viewer.spin();

	pcl::visualization::PCLVisualizer viewer_down_samp("down_samping_viewer");
	viewer_down_samp.addPointCloud(down_sampling_cloud, cloud_out_green);
	viewer_down_samp.spin();

	pcl::visualization::PCLVisualizer viewer_uniform_samp("uniform_samping_viewer");
	viewer_uniform_samp.addPointCloud(uniform_sampling_cloud, cloud_out_orage);
	viewer_uniform_samp.spin();

	pcl::visualization::PCLVisualizer viewer_up_samp("up_samping_viewer");
	viewer_up_samp.addPointCloud(up_sampling_cloud, cloud_out_purple);
	viewer_up_samp.spin();

	return 0;
}

 实验结果

原始点云信息:
width = 35947 , height = 1
下采样处理后:
width = 761 , height = 1
均匀采样处理后:
width = 761 , height = 1
增采样处理后:
width = 143788 , height = 1 

原始点云

下采样处理

均匀采样处理 

增采样处理 

可以看到增采样的结果不是特别准确,点云数量增加,并且结果已变形。 

 

 参考文章:

PCl 几种采样对比 - it610.com

 PCL几种采样方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SOC罗三炮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值