linux下pcl安装
github地址
/* 直通滤波器 PassThrough 直接指定保留哪个轴上的范围内的点 #include <pcl/filters/passthrough.h> 如果使用线结构光扫描的方式采集点云,必然物体沿z向分布较广, 但x,y向的分布处于有限范围内。 此时可使用直通滤波器,确定点云在x或y方向上的范围, 可较快剪除离群点,达到第一步粗处理的目的。 // 创建点云对象 指针 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>); // 原点云获取后进行滤波 pcl::PassThrough<pcl::PointXYZ> pass;// 创建滤波器对象 pass.setInputCloud (cloud);//设置输入点云 pass.setFilterFieldName ("z");//滤波字段名被设置为Z轴方向 pass.setFilterLimits (0.0, 1.0);//可接受的范围为(0.0,1.0) //pass.setFilterLimitsNegative (true);//设置保留范围内 还是 过滤掉范围内 pass.filter (*cloud_filtered); //执行滤波,保存过滤结果在cloud_filtered */ #include <iostream> #include <pcl/point_types.h> #include <pcl/filters/passthrough.h>//直通滤波器 PassThrough #include <pcl/visualization/cloud_viewer.h>//点云可视化 // 别名 typedef pcl::PointCloud<pcl::PointXYZ> Cloud; int main (int argc, char** argv) { // 定义 点云对象 指针 Cloud::Ptr cloud_ptr(new Cloud()); Cloud::Ptr cloud_filtered_ptr(new Cloud()); //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>); //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_ptr (new pcl::PointCloud<pcl::PointXYZ>); // 产生点云数据 cloud_ptr->width = 5; cloud_ptr->height = 1; cloud_ptr->points.resize (cloud_ptr->width * cloud_ptr->height); for (size_t i = 0; i < cloud_ptr->points.size (); ++i) { cloud_ptr->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud_ptr->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud_ptr->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); } std::cerr << "Cloud before filtering滤波前: " << std::endl; for (size_t i = 0; i < cloud_ptr->points.size (); ++i) std::cerr << " " << cloud_ptr->points[i].x << " " << cloud_ptr->points[i].y << " " << cloud_ptr->points[i].z << std::endl; // 创建滤波器对象 Create the filtering object pcl::PassThrough<pcl::PointXYZ> pass; pass.setInputCloud (cloud_ptr);//设置输入点云 pass.setFilterFieldName ("z");// 定义轴 pass.setFilterLimits (0.0, 1.0);// 范围 pass.setFilterLimitsNegative (true);//标志为false时保留范围内的点 pass.filter (*cloud_filtered_ptr); // 输出滤波后的点云 std::cerr << "Cloud after filtering滤波后: " << std::endl; for (size_t i = 0; i < cloud_filtered_ptr->points.size (); ++i) std::cerr << " " << cloud_filtered_ptr->points[i].x << " " << cloud_filtered_ptr->points[i].y << " " << cloud_filtered_ptr->points[i].z << std::endl; // 程序可视化 pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字 viewer.showCloud(cloud_filtered_ptr); while (!viewer.wasStopped()) { // Do nothing but wait. } return (0); }代码地址
/* 下载桌子点云数据 https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_lms400.pcd 体素格滤波器VoxelGrid 在网格内减少点数量保证重心位置不变 PCLPointCloud2() 下采样 #include <pcl/filters/voxel_grid.h> 注意此点云类型为 pcl::PCLPointCloud2 类型 blob 格子类型 #include <pcl/filters/voxel_grid.h> // 转换为模板点云 pcl::PointCloud<pcl::PointXYZ> pcl::fromPCLPointCloud2 (*cloud_filtered_blob, *cloud_filtered); 如果使用高分辨率相机等设备对点云进行采集,往往点云会较为密集。 过多的点云数量会对后续分割工作带来困难。 体素格滤波器可以达到向下采样同时不破坏点云本身几何结构的功能。 点云几何结构 不仅是宏观的几何外形,也包括其微观的排列方式, 比如横向相似的尺寸,纵向相同的距离。 随机下采样虽然效率比体素滤波器高,但会破坏点云微观结构. 使用体素化网格方法实现下采样,即减少点的数量 减少点云数据, 并同时保存点云的形状特征,在提高配准,曲面重建,形状识别等算法速度中非常实用, PCL是实现的VoxelGrid类通过输入的点云数据创建一个三维体素栅格, 容纳后每个体素内用体素中所有点的重心来近似显示体素中其他点, 这样该体素内所有点都用一个重心点最终表示,对于所有体素处理后得到的过滤后的点云, 这种方法比用体素中心(注意中心和重心)逼近的方法更慢,但是对于采样点对应曲面的表示更为准确。 */ #include <iostream> #include <pcl/point_types.h> //#include <pcl/filters/passthrough.h> #include <pcl/filters/voxel_grid.h>//体素格滤波器VoxelGrid #include <pcl/io/pcd_io.h>//点云文件pcd 读写 #include <pcl/visualization/cloud_viewer.h>//点云可视化 #include <pcl_conversions/pcl_conversions.h>//点云类型转换 /* CloudViewer是简单显示点云的可视化工具,可以使用比较少的代码查看点云, 但是这个是不能用于多线程应用程序当中的。 下面的代码的工作是关于如何在可视化线程中运行代码的例子, PCLVisualizer是CloudViewer的后端,但它在自己的线程中运行, 如果要使用PCLVisualizer类必须使用调用函数,这样可以避免可视化的并发问题。 但是在实际调用的时候要注意,以防出现核心已转储这一类很麻烦的问题。 */ using namespace std; // 别名 typedef pcl::PointCloud<pcl::PointXYZ> Cloud; int main (int argc, char** argv) { // 定义 点云对象 指针 pcl::PCLPointCloud2::Ptr cloud2_ptr(new pcl::PCLPointCloud2()); pcl::PCLPointCloud2::Ptr cloud2_filtered_ptr(new pcl::PCLPointCloud2()); Cloud::Ptr cloud_filtered_ptr(new Cloud); // 读取点云文件 填充点云对象 pcl::PCDReader reader; reader.read( "../table_scene_lms400.pcd", *cloud2_ptr); if(cloud2_ptr==NULL) { cout << "pcd file read err" << endl; return -1;} cout << "PointCLoud before filtering 滤波前数量: " << cloud2_ptr->width * cloud2_ptr->height << " data points ( " << pcl::getFieldsList (*cloud2_ptr) << "." << endl; // 创建滤波器对象 Create the filtering object pcl::VoxelGrid<pcl::PCLPointCloud2> vg; vg.setInputCloud (cloud2_ptr);//设置输入点云 vg.setLeafSize(0.01f, 0.01f, 0.01f);// 体素块大小 1cm vg.filter (*cloud2_filtered_ptr); // 输出滤波后的点云信息 cout << "PointCLoud before filtering 滤波后数量: " << cloud2_filtered_ptr->width * cloud2_filtered_ptr->height << " data points ( " << pcl::getFieldsList (*cloud2_filtered_ptr) << "." << endl; // 写入内存 pcl::PCDWriter writer; writer.write("table_scene_lms400_downsampled.pcd",*cloud2_filtered_ptr, Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false); // 调用系统可视化命令行显示 //system("pcl_viewer table_scene_lms400_inliers.pcd"); // 转换为模板点云 pcl::PointCloud<pcl::PointXYZ> pcl::fromPCLPointCloud2 (*cloud2_filtered_ptr, *cloud_filtered_ptr); // 程序可视化 pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字 viewer.showCloud(cloud_filtered_ptr); while (!viewer.wasStopped()) { // Do nothing but wait. } return (0); }代码地址
/* 条件滤波器 可以一次删除满足对输入的点云设定的一个或多个条件指标的所有的数据点 删除点云中不符合用户指定的一个或者多个条件的数据点 不在条件范围内的点 被替换为 nan #include <pcl/filters/conditional_removal.h> */ #include <iostream> #include <pcl/point_types.h> //#include <pcl/filters/passthrough.h> //#include <pcl/ModelCoefficients.h> //模型系数头文件 //#include <pcl/filters/project_inliers.h> //投影滤波类头文件 #include <pcl/io/pcd_io.h> //点云文件pcd 读写 //#include <pcl/filters/radius_outlier_removal.h>// 球半径滤波器 #include <pcl/filters/conditional_removal.h> //条件滤波器 //#include <pcl/filters/filter.h> #include <pcl/visualization/cloud_viewer.h>//点云可视化 // 别名 typedef pcl::PointCloud<pcl::PointXYZ> Cloud; using namespace std; int main (int argc, char** argv) { // 定义 点云对象 指针 Cloud::Ptr cloud_ptr(new Cloud()); Cloud::Ptr cloud_filtered_ptr(new Cloud()); // 产生点云数据 cloud_ptr->width = 5; cloud_ptr->height = 1; cloud_ptr->points.resize (cloud_ptr->width * cloud_ptr->height); for (size_t i = 0; i < cloud_ptr->points.size (); ++i) { cloud_ptr->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud_ptr->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud_ptr->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); } std::cerr << "Cloud before filtering半径滤波前: " << std::endl; for (size_t i = 0; i < cloud_ptr->points.size (); ++i) std::cerr << " " << cloud_ptr->points[i].x << " " << cloud_ptr->points[i].y << " " << cloud_ptr->points[i].z << std::endl; // 可使用 strcmp获取指定命令行参数 if (strcmp(argv[1], "-r") == 0) //创建条件定义对象 pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond_cptr(new pcl::ConditionAnd<pcl::PointXYZ>()); //为条件定义对象添加比较算子 range_cond_cptr->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::GT, 0.0))); //添加在Z字段上大于(pcl::ComparisonOps::GT great Then)0的比较算子 range_cond_cptr->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::LT, 0.8))); //添加在Z字段上小于(pcl::ComparisonOps::LT Lower Then)0.8的比较算子 // 创建滤波器并用条件定义对象初始化 pcl::ConditionalRemoval<pcl::PointXYZ> conditrem;//创建条件滤波器 conditrem.setCondition (range_cond_cptr); //并用条件定义对象初始化 conditrem.setInputCloud (cloud_ptr); //输入点云 conditrem.setKeepOrganized(true); //设置保持点云的结构 // 执行滤波 conditrem.filter(*cloud_filtered_ptr); //大于0.0小于0.8这两个条件用于建立滤波器 // 不在条件范围内的点 被替换为 nan // 输出滤波后的点云 std::cerr << "Cloud after filtering半径滤波后: " << std::endl; for (size_t i = 0; i < cloud_filtered_ptr->points.size (); ++i) std::cerr << " " << cloud_filtered_ptr->points[i].x << " " << cloud_filtered_ptr->points[i].y << " " << cloud_filtered_ptr->points[i].z << std::endl; // 去除 nan点 std::vector<int> mapping; pcl::removeNaNFromPointCloud(*cloud_filtered_ptr, *cloud_filtered_ptr, mapping); // 输出去除nan后的点云 std::cerr << "Cloud after delet nan point去除nan点 : " << std::endl; for (size_t i = 0; i < cloud_filtered_ptr->points.size (); ++i) std::cerr << " " << cloud_filtered_ptr->points[i].x << " " << cloud_filtered_ptr->points[i].y << " " << cloud_filtered_ptr->points[i].z << std::endl; // 程序可视化 pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字 viewer.showCloud(cloud_filtered_ptr); while (!viewer.wasStopped()) { // Do nothing but wait. } return (0); }代码地址
/* 投影滤波 输出投影后的点的坐标 使用参数化模型投影点云 如何将点投影到一个参数化模型上(平面或者球体等), 参数化模型通过一组参数来设定,对于平面来说使用其等式形式。 在PCL中有特定存储常见模型系数的数据结构。 #include <pcl/ModelCoefficients.h> //模型系数头文件 #include <pcl/filters/project_inliers.h> //投影滤波类头文件 */ #include <iostream> #include <pcl/point_types.h> //#include <pcl/filters/passthrough.h> #include <pcl/ModelCoefficients.h> //模型系数头文件 #include <pcl/filters/project_inliers.h> //投影滤波类头文件 #include <pcl/io/pcd_io.h> //点云文件pcd 读写 #include <pcl/visualization/cloud_viewer.h>//点云可视化 // 别名 typedef pcl::PointCloud<pcl::PointXYZ> Cloud; using namespace std; int main (int argc, char** argv) { // 定义 点云对象 指针 Cloud::Ptr cloud_ptr(new Cloud()); Cloud::Ptr cloud_filtered_ptr(new Cloud()); //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>); //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_ptr (new pcl::PointCloud<pcl::PointXYZ>); // 产生点云数据 cloud_ptr->width = 5; cloud_ptr->height = 1; cloud_ptr->points.resize (cloud_ptr->width * cloud_ptr->height); for (size_t i = 0; i < cloud_ptr->points.size (); ++i) { cloud_ptr->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud_ptr->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud_ptr->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); } std::cerr << "Cloud before filtering投影滤波前: " << std::endl; for (size_t i = 0; i < cloud_ptr->points.size (); ++i) std::cerr << " " << cloud_ptr->points[i].x << " " << cloud_ptr->points[i].y << " " << cloud_ptr->points[i].z << std::endl; // 填充ModelCoefficients的值,使用ax+by+cz+d=0平面模型,其中 a=b=d=0,c=1 也就是X——Y平面 //定义模型系数对象,并填充对应的数据 创建投影滤波模型重会设置模型类型 pcl::SACMODEL_PLANE pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients()); coefficients->values.resize (4); coefficients->values[0] = coefficients->values[1] = 0; coefficients->values[2] = 1.0; coefficients->values[3] = 0; // 创建投影滤波模型ProjectInliers对象,使用ModelCoefficients作为投影对象的模型参数 pcl::ProjectInliers<pcl::PointXYZ> proj; //创建投影滤波对象 proj.setModelType (pcl::SACMODEL_PLANE); //设置对象对应的投影模型 平面模型 proj.setInputCloud (cloud_ptr); //设置输入点云 proj.setModelCoefficients (coefficients); //设置模型对应的系数 proj.filter (*cloud_filtered_ptr); //投影结果存储 // 输出滤波后的点云 std::cerr << "Cloud after filtering投影滤波后: " << std::endl; for (size_t i = 0; i < cloud_filtered_ptr->points.size (); ++i) std::cerr << " " << cloud_filtered_ptr->points[i].x << " " << cloud_filtered_ptr->points[i].y << " " << cloud_filtered_ptr->points[i].z << std::endl; // 程序可视化 pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字 viewer.showCloud(cloud_filtered_ptr); while (!viewer.wasStopped()) { // Do nothing but wait. } return (0); }代码地址
/* 球半径滤波器 #include <pcl/filters/radius_outlier_removal.h> 球半径滤波器与统计滤波器相比更加简单粗暴。 以某点为中心 画一个球计算落在该球内的点的数量,当数量大于给定值时, 则保留该点,数量小于给定值则剔除该点。 此算法运行速度快,依序迭代留下的点一定是最密集的, 但是球的半径和球内点的数目都需要人工指定。 */ #include <iostream> #include <pcl/point_types.h> //#include <pcl/filters/passthrough.h> //#include <pcl/ModelCoefficients.h> //模型系数头文件 //#include <pcl/filters/project_inliers.h> //投影滤波类头文件 #include <pcl/io/pcd_io.h> //点云文件pcd 读写 #include <pcl/filters/radius_outlier_removal.h>// 球半径滤波器 #include <pcl/visualization/cloud_viewer.h>//点云可视化 // 别名 typedef pcl::PointCloud<pcl::PointXYZ> Cloud; using namespace std; int main (int argc, char** argv) { // 定义 点云对象 指针 Cloud::Ptr cloud_ptr(new Cloud()); Cloud::Ptr cloud_filtered_ptr(new Cloud()); // 产生点云数据 cloud_ptr->width = 5; cloud_ptr->height = 1; cloud_ptr->points.resize (cloud_ptr->width * cloud_ptr->height); for (size_t i = 0; i < cloud_ptr->points.size (); ++i) { cloud_ptr->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud_ptr->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud_ptr->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); } std::cerr << "Cloud before filtering半径滤波前: " << std::endl; for (size_t i = 0; i < cloud_ptr->points.size (); ++i) std::cerr << " " << cloud_ptr->points[i].x << " " << cloud_ptr->points[i].y << " " << cloud_ptr->points[i].z << std::endl; // 可使用 strcmp获取指定命令行参数 if (strcmp(argv[1], "-r") == 0) // 创建滤波器 pcl::RadiusOutlierRemoval<pcl::PointXYZ> Radius; // 建立滤波器 Radius.setInputCloud(cloud_ptr); Radius.setRadiusSearch(1.2);//半径为 0.8m Radius.setMinNeighborsInRadius (2);//半径内最少需要 2个点 // 执行滤波 Radius.filter (*cloud_filtered_ptr); // 输出滤波后的点云 std::cerr << "Cloud after filtering半径滤波后: " << std::endl; for (size_t i = 0; i < cloud_filtered_ptr->points.size (); ++i) std::cerr << " " << cloud_filtered_ptr->points[i].x << " " << cloud_filtered_ptr->points[i].y << " " << cloud_filtered_ptr->points[i].z << std::endl; // 程序可视化 pcl::visualization::CloudViewer viewer("pcd viewer");// 显示窗口的名字 viewer.showCloud(cloud_filtered_ptr); while (!viewer.wasStopped()) { // Do nothing but wait. } return (0); }