2019.10.25更新(带命令行参数)
//体素滤波(下采样)
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
int main(int argc,char** argv) {
if(argc<2){
std::cout<<"参数个数太少: ./demo_voxel_grid pcd"<<std::endl;
return -1;
}
//拼接字符串作为输出结果的保存
std::cout<<argv[1]<<std::endl;
std::cout<< typeid(argv[1]).name()<<std::endl;
std::cout << "Hello, World!" << std::endl;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile(argv[1],*cloud_in);
std::cerr<<"PointCloud before filtering: "<<cloud_in->size()<<" data points ("<<pcl::getFieldsList(*cloud_in)<<" )"<<std::endl;
//???????
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud(cloud_in);
sor.setLeafSize(0.01,0.01,0.01);
sor.filter(*cloud_filtered);
std::cout<<"voxel filter succeed!"<<std::endl;
std::cerr<<"PointCloud after filtering: "<<cloud_filtered->size()<<" data points ("<<pcl::getFieldsList(*cloud_filtered)<<" )"<<std::endl;
//考虑如何将两个字符串组合起来
std::string result;
const std::string str1 = "down_sample_";
const std::string str2 = argv[1];
result = str1;
result += str2;
std::cout<<result<<std::endl;
pcl::io::savePCDFileASCII(result,*cloud_filtered);
std::cout<<result<<" save succeed!"<<std::endl;
//?????
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("demo"));
viewer->initCameraParameters();
int v1(0);//?????????????
viewer->createViewPort(0.0,0.0,0.5,1,v1); //??????????????С??λ????????
viewer->setBackgroundColor(255,0,255,v1);//background of first port
viewer->addText("cloud_in",10,10,"cloud_in",v1);//????????????
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud_in,0,255,0);//????????????????
viewer->addPointCloud<pcl::PointXYZ>(cloud_in,single_color1,"cloud_in",v1);//????????????
int v2(0);//?????????????
viewer->createViewPort(0.5,0.0,1,1,v2); //??????????????С??λ????????
viewer->setBackgroundColor(0,0,0,v2);//background of first port
viewer->addText("cloud_filtered",10,10,"cloud_filtered",v2);//????????????
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color2(cloud_filtered,255,0,0);//????????????????
viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered,single_color2,"cloud_filtered",v2);//????????????
viewer->addCoordinateSystem();
viewer->spin();
return 0;
}
//VoxelGrid filter(体素滤波)
//大致是通过设置一个小正方体的各个边的长度,使其重心来将正方体中的points替代。
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
int main() {
std::cout << "Hello, World!" << std::endl;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("room_scan1.pcd",*cloud_in);
std::cerr<<"PointCloud before filtering: "<<cloud_in->size()<<" data points ("<<pcl::getFieldsList(*cloud_in)<<" )"<<std::endl;//cerr输出为红色
//体素滤波
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud(cloud_in);
sor.setLeafSize(0.05,0.05,0.05);
sor.filter(*cloud_filtered);
std::cout<<"voxel filter succeed!"<<std::endl;
std::cerr<<"PointCloud after filtering: "<<cloud_filtered->size()<<" data points ("<<pcl::getFieldsList(*cloud_filtered)<<" )"<<std::endl;//getFieldsList(*cloud_filtered) 获取点的field(类似于维度)
pcl::io::savePCDFileASCII("room_scan1_filtered",*cloud_filtered);
std::cout<<"save succeed!"<<std::endl;
//可视化
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("demo"));
viewer->initCameraParameters();
int v1(0);//第一个窗口的参数
viewer->createViewPort(0.0,0.0,0.5,1,v1); //设置第一个窗口的大小,位于屏幕左侧
viewer->setBackgroundColor(255,0,255,v1);//background of first port
viewer->addText("cloud_in",10,10,"cloud_in",v1);//好像是一个便签
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud_in,0,255,0);//设置第一个点云的颜色
viewer->addPointCloud<pcl::PointXYZ>(cloud_in,single_color1,"cloud_in",v1);//显示第一个点云
int v2(0);//第一个窗口的参数
viewer->createViewPort(0.5,0.0,1,1,v2); //设置第一个窗口的大小,位于屏幕左侧
viewer->setBackgroundColor(0,0,0,v2);//background of first port
viewer->addText("cloud_filtered",10,10,"cloud_filtered",v2);//好像是一个便签
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color2(cloud_filtered,255,0,0);//设置第一个点云的颜色
viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered,single_color2,"cloud_filtered",v2);//显示第一个点云
viewer->addCoordinateSystem();
viewer->spin();
return 0;
}
可视化结果1(体素=0.05):(依次为原数据、下采样之后的数据)
可视化结果2(体素=0.01):
总结:体素越大,滤除掉的点越少,反之亦然。
下采样可以作为一些大型数据运算处理之前的预处理,以减少运算时间和成本。使用体素下采样仍可以保存点云数据的大致样貌。
例程里面的PointCloud2类型的数据不会可视化,所以选取了PointXYZ类型的数据。知道如何可视化PointCloud2类型的数据的朋友可以指点一下。:)