1. 程式人生 > 其它 >PCL(5)點雲聚類 之 VoxelGrid體素取樣與ApproximateVoxelGrid體素取樣

PCL(5)點雲聚類 之 VoxelGrid體素取樣與ApproximateVoxelGrid體素取樣

1 區別

1.1 原理

  • VoxelGrid體素取樣,對點雲進行體素化,建立一個三維體素柵格。在每個體素裡面,求取該立方體內的所有點雲重心點來代表這個立方體的表示,以此達到下采樣的目的。
  • ApproximateVoxelGrid體素取樣,對點雲用每個體素柵格的中心點來近似該體素內的點,提升了速度,但是也損失了原始點雲的區域性形態精細度。

1.2 引用

  • 1、VoxelGrid體素取樣引入標頭檔案:

#include <pcl/filters/voxel_grid.h>

ApproximateVoxelGrid體素取樣引入標頭檔案:

#include <pcl/filters/approximate_voxel_grid.h>

2常用函式

因為兩種濾波器原理近似,所以常用函式基本相同。下面介紹幾種有代表性的。

  • void pcl::VoxelGrid< PointT >::filter (PointCloud & output )
    功能:保留體素濾波後的點雲檔案。其中引數為輸出點雲的指標。
pcl::VoxelGrid<pcl::PointXYZ> sor;//濾波處理物件
	sor.setInputCloud(cloud);
	sor.filter(*cloud_filter);//直接儲存點雲檔案
  • void pcl::VoxelGrid< PointT >::setDownsampleAllData (bool downsample)
    功能:如果所有欄位都需要取樣,則設為true,如果只有XYZ則設為false。
pcl::VoxelGrid<pcl::PointXYZ> sor;//濾波處理物件
	sor.setInputCloud(cloud);
	sor.setDownsampleAllData(1);//該語句這麼用
	sor.filter(*cloud_filter);
  • void pcl::VoxelGrid< PointT >::setLeafSize (float lx,float ly,float lz )
    功能:設定體素大小。
pcl::VoxelGrid<pcl::PointXYZ>
sor;//濾波處理物件 sor.setInputCloud(cloud); sor.setDownsampleAllData(1); sor.setLeafSize(0.01f, 0.01f, 0.01f);//設定濾波器處理時採用的體素大小的引數 sor.filter(*cloud_filter);

效果:
1、setLeafSize(0.005f, 0.005f, 0.005f)
在這裡插入圖片描述
2、setLeafSize(0.05f, 0.05f, 0.05f)
在這裡插入圖片描述

  • void pcl::VoxelGrid< PointT >::setMinimumPointsNumberPerVoxel (unsigned int min_points_per_voxel)
    功能:設定要使用的體素所需的最小點數。也可以理解成每個體素中要保留的點的個數。
pcl::VoxelGrid<pcl::PointXYZ> sor;//濾波處理物件
	sor.setInputCloud(cloud);
	sor.setDownsampleAllData(1);
	sor.setLeafSize(0.01f, 0.01f, 0.01f);//設定濾波器處理時採用的體素大小的引數
	sor.setMinimumPointsNumberPerVoxel(5);//設定每個體素中的點的個數
	sor.filter(*cloud_filter);

效果:
在這裡插入圖片描述

3最後奉上程式碼

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>  //濾波相關
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/voxel_grid.h>
//直通濾波器
int main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filter(new pcl::PointCloud<pcl::PointXYZ>);
	// 填入點雲資料
	pcl::PCDReader reader;
	// 把路徑改為自己存放檔案的路徑
	reader.read<pcl::PointXYZ>("20201216-14-56-26_sor.pcd", *cloud);
	std::cerr << "Cloud before filtering: " << std::endl;
	std::cerr << *cloud << std::endl;
    pcl::visualization::PCLVisualizer viewer("濾波");
	int v1(0);
	int v2(1);
	viewer.createViewPort(0.0, 0.0, 0.5, 1, v1);
	viewer.setBackgroundColor(1, 1, 1, v1);
	viewer.createViewPort(0.5, 0.0, 1, 1, v2);
	viewer.setBackgroundColor(1, 1, 1, v2);

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_green(cloud, 255, 20, 147);// 顯示綠色點雲
	viewer.addPointCloud(cloud, cloud_out_green, "cloud_out1", v1);

	pcl::VoxelGrid<pcl::PointXYZ> sor;//濾波處理物件
	sor.setInputCloud(cloud);
	sor.setDownsampleAllData(1);
	sor.setLeafSize(0.01f, 0.01f, 0.01f);//設定濾波器處理時採用的體素大小的引數
	sor.setMinimumPointsNumberPerVoxel(5);//設定每個體素中的點的個數
	sor.filter(*cloud_filter);
	std::cerr << "Cloud after filtering: " << *cloud_filter << std::endl;
	pcl::PCDWriter writer;
	writer.write<pcl::PointXYZ> ("20201216-14-56-26_vox.pcd", *cloud_filter, false);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_orage(cloud_filter, 122, 103, 238);//122 103 238
	viewer.addPointCloud(cloud_filter, cloud_out_orage, "cloud_out2", v2);
	//viewer.setSize(960, 780);
	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}
	return 0;
}