PCL(5)點雲聚類 之 VoxelGrid體素取樣與ApproximateVoxelGrid體素取樣
阿新 • • 發佈:2021-03-08
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)
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;
}