体素滤波器可以达到向下采样同时不破坏点云本身几何结构的功能,但是会移动点的位置。

此外体素滤波器可以去除一定程度的噪音点及离群点。主要功能是用来进行降采样。

(1)它的原理是根据输入的点云,首先计算一个能够刚好包裹住该点云的立方体,然后根据设定的分辨率,将该立方体分割成不同的小立方体。类似于octree里的立方体划分,对于每一个小立方体内的点,计算他们的质心(重心),并用该质心的坐标来近似该立方体内的若干点。

(2)ApproximateVoxelGrid的不同在于这种方法是利用每一个小立方体的中心来近似该立方体内的若干点。相比于 VoxelGrid,计算速度稍快,但也损失了原始点云局部形态的精细度。

原理不多讲,直接上代码:

c++代码如下:

#include <iostream>
#include <pcl/io/pcd_io.h>//输入输出头文件
#include <pcl/point_types.h>//PCD读写类相关的头文件
#include <pcl/filters/voxel_grid.h>//点类型相关头文件
#include <pcl/common/time.h> // 计时,使用 pcl::StopWatch time;的支持头文件
#include <thread>//1 detach脱离当前主线程,自由执行,乱序;2 join()等待模式,执行完再执行下一个3 std::this_thread::get_id()获取当前线程编号4 std::thread::hardware_concurrency()检测CPU有多少个核心
#include <pcl/common/common_headers.h>//可视化相关头文件
#include <pcl/features/normal_3d.h>//创建3d模型所需头文件 属于可视化相关头文件之一
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>//pcl程序中经常用到程序后面带选项,选项解析使用pcl::console::parse_argument()来完成 执行getchar();  防止闪退所需头文件
#include<sstream>// C++标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能
using namespace std;
using namespace pcl::console;int main(int argc, char** argv)
{pcl::StopWatch time; // 计时开始 有时需要计算代码运行的时间,使用PCL里的StopWatch类以及ScopeTime类可以实现这个功能// pcl::PCLPointCloud2::Ptr cloud(new pcl::PCLPointCloud2());//Linux下的编写方式// pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());//输入点云pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>);// Fill in the cloud datapcl::PCDReader reader;//pcd文件读操作// Replace the path below with the path where you saved your filereader.read("D:\\pclcode\\filter\\voxel_grid\\source\\ChinaDragon.pcd", *cloud); // Remember to download the file first!std::stringstream str1;//* 使用stringstream对象简化类型转换 C++标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能   std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height<< " data points (" << pcl::getFieldsList(*cloud) << ")." << endl;str1 << "PointCloud before filtering: " << cloud->width * cloud->height<< " data points (" << pcl::getFieldsList(*cloud) << ")." << endl;// Create the filtering object// 创建一个大小为2cm的pcl::VoxelGrid滤波器// pcl::VoxelGrid<pcl::PCLPointCloud2> sor;pcl::VoxelGrid<pcl::PointXYZI> sor;//创建滤波器对象sor.setInputCloud(cloud); // 给滤波对象设置需要过滤的点云//sor.setLeafSize(0.02f, 0.02f, 0.02f); // 设置滤波时创建的体素大小为2cm立方体sor.setLeafSize(0.06f, 0.06f, 0.06f);sor.filter(*cloud_filtered); // 执行滤波处理,存储输出cloud_filteredstd::stringstream str2;//类型转换实现  安全和自动的类型转换std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height<< " data points (" << pcl::getFieldsList(*cloud_filtered) << ")." << endl;str2 << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height<< " data points (" << pcl::getFieldsList(*cloud_filtered) << ")."<<endl;pcl::PCDWriter writer;//PCD文件写操作writer.write("ChinaDragon.pcd_downsampled.pcd", *cloud_filtered);// writer.write("table_scene_lms400_downsampled.pcd", *cloud_filtered, Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), false);//linux下操作写法std::cout << "运行时间:" << time.getTime() << "ms(毫秒)" << std::endl; //有时需要计算代码运行的时间,使用PCL里的StopWatch类以及ScopeTime类可以实现这个功能std::cout << "运行时间:" << time.getTimeSeconds() << "s(秒)" << std::endl;//有时需要计算代码运行的时间,使用PCL里的StopWatch类以及ScopeTime类可以实现这个功能// 可视化// 创建一个boost共享指针并进行实例化boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("voxel_grid 3D Viewer"));viewer->initCameraParameters(); // 通过设置照相机参数使得从默认的角度和方向观察点云int v1(0);  //创建新的视口viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 4个参数分别是X轴的最小值,最大值,Y轴的最小值,最大值,取值0-1,v1是标识viewer->setBackgroundColor(0, 0, 0, v1); // 设置视窗的背景颜色 黑色// viewer->addText("cloud before voxelgrid filtering", 10, 10, "v1 text", v1); // 添加一个标签区别其他窗口viewer->addText(str1.str(), 10, 10, "v1 text", v1); // 添加一个标签区别其他窗口 str1.str()调用上面的str1pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI>cloud_color(cloud, "intensity");//创建颜色处理对象 PointCloudColorHandlerCustom ,PCL Visualizer 类利用这样的对象显示自定义颜色数据viewer->addPointCloud<pcl::PointXYZI>(cloud, cloud_color, "cloud", v1);// 对第二视口做同样的操作,使得做创建的点云分布于右半窗口,将该视口背景赋值于灰色,以便明显区别,虽然添加同样的点云,给点云自定义颜色着色int v2(0);viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);// 4个参数分别是X轴的最小值,最大值,Y轴的最小值,最大值,取值0-1,v2是标识viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);// 设置视窗的背景颜色// viewer->addText("cloud after voxelgrid filtering", 10, 10, "v2 text", v2);viewer->addText(str2.str(), 10, 10, "v2 text", v2);// 添加一个标签区别其他窗口 str1.str()调用上面的str2  PointCloud after filtering:pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI>cloud_filtered_color(cloud_filtered, "intensity");//创建颜色处理对象 PointCloudColorHandlerCustom ,PCL Visualizer 类利用这样的对象显示自定义颜色数据viewer->addPointCloud<pcl::PointXYZI>(cloud_filtered, cloud_filtered_color, "cloud_filtered", v2);// 为所有视口设置属性viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");//第一个窗口viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_filtered");//第二个窗口//  改变显示点云的尺寸viewer->addCoordinateSystem(1.0); // 从默认的角度和方向观察点云  添加坐标系while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(10000));} // 每次调用spinOnce都给视窗处理事件的时间,允许鼠标、键盘等交互操作getchar(); // 防止闪退return (0);
}

CmakeLists文件

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)project(voxel_grid)find_package(PCL 1.2 REQUIRED)include_directories(${PCL_INCLUDE_DIRS})link_directories(${PCL_LIBRARY_DIRS})add_definitions(${PCL_DEFINITIONS})add_executable (voxel_grid voxel_grid.cpp)target_link_libraries (voxel_grid ${PCL_LIBRARIES})

具体的执行效果不展示了,代码里的点云文件换成自己想要滤波的点云文件就可以了。

换了一个点云文件的执行效果,由于场景较大,需要将体素大小设置的大一点

#include <iostream>#include <pcl/io/pcd_io.h>//输入输出头文件#include <pcl/point_types.h>//PCD读写类相关的头文件#include <pcl/filters/voxel_grid.h>//点类型相关头文件#include <pcl/common/time.h> // 计时,使用 pcl::StopWatch time;的支持头文件#include <thread>//1 detach脱离当前主线程,自由执行,乱序;2 join()等待模式,执行完再执行下一个3 std::this_thread::get_id()获取当前线程编4 std::thread::hardware_concurrency()检测CPU有多少个核心#include <pcl/common/common_headers.h>//可视化相关头文件#include <pcl/features/normal_3d.h>//创建3d模型所需头文件 属于可视化相关头文件之一#include <pcl/visualization/pcl_visualizer.h>#include <pcl/console/parse.h>//pcl程序中经常用到程序后面带选项,选项解析使用pcl::console::parse_argument()来完成 执行getchar();  防止闪退所需头文件#include<sstream>// C++标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能using namespace std;using namespace pcl::console;int main(int argc, char** argv){pcl::StopWatch time; // 计时开始 有时需要计算代码运行的时间,使用PCL里的StopWatch类以及ScopeTime类可以实现这个功能// pcl::PCLPointCloud2::Ptr cloud(new pcl::PCLPointCloud2());//Linux下的编写方式// pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());//输入点云pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>);// Fill in the cloud datapcl::PCDReader reader;//pcd文件读操作// Replace the path below with the path where you saved your filereader.read("D:\\pclcode\\filter\\voxel_grid\\source\\scan_003.pcd", *cloud); // Remember to download the file first!std::stringstream str1;//* 使用stringstream对象简化类型转换 C++标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能  std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height<< " data points (" << pcl::getFieldsList(*cloud) << ")." << endl;str1 << "PointCloud before filtering: " << cloud->width * cloud->height<< " data points (" << pcl::getFieldsList(*cloud) << ")." << endl;// Create the filtering object// 创建一个大小为9cm的pcl::VoxelGrid滤波器// pcl::VoxelGrid<pcl::PCLPointCloud2> sor;pcl::VoxelGrid<pcl::PointXYZI> sor;//创建滤波器对象sor.setInputCloud(cloud); // 给滤波对象设置需要过滤的点云//sor.setLeafSize(0.01f, 0.01f, 0.01f); // 设置滤波时创建的体素大小为1cm立方体sor.setLeafSize(0.9f,0.9f,0.9f);// 设置滤波时创建的体素大小为9cm立方体sor.filter(*cloud_filtered); // 执行滤波处理,存储输出cloud_filteredstd::stringstream str2;//类型转换实现  安全和自动的类型转换std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height<< " data points (" << pcl::getFieldsList(*cloud_filtered) << ")." << endl;str2 << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height<< " data points (" << pcl::getFieldsList(*cloud_filtered) << ")."<<endl;pcl::PCDWriter writer;//PCD文件写操作writer.write("scan_003_downsampled.pcd", *cloud_filtered);// writer.write("table_scene_lms400_downsampled.pcd", *cloud_filtered, Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), false);//linux下操作写法std::cout << "运行时间:" << time.getTime() << "ms(毫秒)" << std::endl; //有时需要计算代码运行的时间,使用PCL里的StopWatch类以及ScopeTime类可以实现这个功能std::cout << "运行时间:" << time.getTimeSeconds() << "s(秒)" << std::endl;//有时需要计算代码运行的时间,使用PCL里的StopWatch类以及ScopeTime类可以实现这个功能// 可视化// 创建一个boost共享指针并进行实例化boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("voxel_grid 3D Viewer"));viewer->initCameraParameters(); // 通过设置照相机参数使得从默认的角度和方向观察点云int v1(0);  //创建新的视口viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 4个参数分别是X轴的最小值,最大值,Y轴的最小值,最大值,取值0-1,v1是标识viewer->setBackgroundColor(0, 0, 0, v1); // 设置视窗的背景颜色 黑色// viewer->addText("cloud before voxelgrid filtering", 10, 10, "v1 text", v1); // 添加一个标签区别其他窗口viewer->addText(str1.str(), 10, 10, "v1 text", v1); // 添加一个标签区别其他窗口 str1.str()调用上面的str1pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI>cloud_color(cloud, "intensity");//创建颜色处理对象 PointCloudColorHandlerCustom ,PCL Visualizer 类利用这样的对象显示自定义颜色数据viewer->addPointCloud<pcl::PointXYZI>(cloud, cloud_color, "cloud", v1);// 对第二视口做同样的操作,使得做创建的点云分布于右半窗口,将该视口背景赋值于灰色,以便明显区别,虽然添加同样的点云,给点云自定义颜色着色int v2(0);viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);// 4个参数分别是X轴的最小值,最大值,Y轴的最小值,最大值,取值0-1,v1是标识viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);// 设置视窗的背景颜色// viewer->addText("cloud after voxelgrid filtering", 10, 10, "v2 text", v2);viewer->addText(str2.str(), 10, 10, "v2 text", v2);// 添加一个标签区别其他窗口 str1.str()调用上面的str2  PointCloud after filtering:pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI>cloud_filtered_color(cloud_filtered, "intensity");//创建颜色处理对象 PointCloudColorHandlerCustom ,PCL Visualizer 类利用这样的对象显示自定义颜色数据viewer->addPointCloud<pcl::PointXYZI>(cloud_filtered, cloud_filtered_color, "cloud_filtered", v2);// 为所有视口设置属性viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");//第一个窗口viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_filtered");//第二个窗口//  改变显示点云的尺寸viewer->addCoordinateSystem(1.0); // 从默认的角度和方向观察点云  添加坐标系while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(10000));} // 每次调用spinOnce都给视窗处理事件的时间,允许鼠标、键盘等交互操作getchar(); // 防止闪退return (0);}//PointCloud before filtering : 2057209 data points(x y z intensity).//PointCloud after filtering : 63939 data points(x y z intensity).//运行时间 : 378ms(毫秒)//运行时间 : 0.379s(秒)

CmakeLists文件:和上面使用的是一样的

PCL voxelgrid实现相关推荐

  1. [pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset. Integer indices would ov

    1. 报错日志: Python-pcl 点云下采样时报错如下: [pcl::VoxelGrid::applyFilter] Leaf size is too small for the input d ...

  2. pcl——VoxelGrid滤波器

    点云入门第六章--入门使用VoxelGrid滤波器对点云进行下采样: 原理: pcl的VoxelGrid在输入点云数据上创建一个3D 体素网格(将体素网格视为空间中的一组微小的 空间三维立方体的集合) ...

  3. PCL之体素网格滤波器--VoxelGrid

    作用:使用体素化网格方法实现下采样,可在保持点云形状特征的情况下减少点云的数量:在提高配准.曲面重建.形状识别等算法的速度. 原理:PCL实现的VoxelGrid类通过输入的点云数据创建一个三维体素栅 ...

  4. 【PCL】VoxelGrid滤波器下采样

    VoxelGrid滤波器是用体素化网格方法实现下采样的一种常用滤波方法,这里重点学习. 下采样是在保持点云形状的同时减少点云中点的数量:VoxelGrid是通过创建三维体素栅格,用每个体素中所有点的重 ...

  5. io获取 pcl_点云数据可视化之PCL滤波学习

    PCL滤波概述 在获取点云数据时 ,由于设备精度,操作者经验环境因素带来的影响,以及电磁波的衍射特性,被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中将不可避免的出现一些噪声.在点云处理流 ...

  6. PCL:超详细的基于法向量和曲率的区域生长算法原理以及源码解读

    ---------原理介绍: (1)首先计算出来各点的曲率值,将曲率值按照从小到大的顺序进行排序. (2)设置一空的种子点序列和一个空的聚类数组. (3)选取曲率最小的点放入上述种子点序列中. (4) ...

  7. PCL:点云中的超体素数据

    -----------------------体素数据---------------------体素化网格 体素(Voxel)是体积元素(Volume pixel)的简称,是数据位于三维空间内规则网格 ...

  8. PCL从0到1|点云滤波之直通滤波与体素法滤波

    3D视觉工坊的第51篇文章 今天呢,想和大家聊一聊点云滤波处理的相关模块. 我对点云模块了解得也不算深入,此处单纯地想和大家分享一下这几天我所学习到的点云滤波知识,如有不到之处,还请后台留言多多指正. ...

  9. PCL谢谢笔记 体素栅格滤波(下采样)

    1.体素滤波 PCL实现的VoxelGrid类通过输入的点云数据创建一个三维体素栅格(可把体素栅格想象为微小的空间三维立方体的集合),然后在每个体素(即,三维立方体)内,用体素中所有点的重心来近似显示 ...

最新文章

  1. 一、网页端文件流的传输
  2. 程序员敲诈老板,或面临 37 年监禁
  3. 【Kubernetes】离线业务:Job与CronJob
  4. C#窗体中的textBox怎么设置为密码框
  5. MOSS Content Types 概述
  6. 如何在UI设计中制作完美阴影
  7. 服务发现技术是如何演进出来的?
  8. 扒一扒,互联网大厂内部都用什么软件沟通?
  9. 毕业论文的6中降重方法
  10. 问题求解RK3288调ALC5640芯片遇到的问题,前部分硬件问题,后部分如见驱动问题。
  11. Inno Setup 6.0.3+ 简体中文语言包
  12. 鸟哥的linux私房菜 第五章
  13. 二进制中 等比数列求和公式
  14. discuz wooyun-2010-080723
  15. CodeForces-1040B Shashlik Cooking(贪心)
  16. 最近几年我买的一些技术书的随书光盘CD
  17. Linux 下 MQ 的安装
  18. java:多态详解,以及对象的向上和向下转型
  19. 基因表达分析(上)- 差异表达分析
  20. python弹幕好坏词分析_用python分析一波哔哩哔哩弹幕

热门文章

  1. 中移M5311模块MQTT协议连接阿里云物联网平台(干货)
  2. java 事务补偿机制_重试补偿机制完善
  3. SHU 第十届程序设计联赛(夏季赛) 解题报告
  4. 双曲图嵌入Low-Dimensional Hyperbolic Knowledge Graph Embeddings
  5. Blockchain Assisted Decentralized Federated Learning 阅读笔记 TPDS’2022
  6. 极简yolov5转torchscript
  7. 全球语言标准码(ISO-639)
  8. 三星平板 N8000刷机升级安卓版本到7.1过程记录
  9. Experience - 6个月心得
  10. 如何用 Python 和 API 收集与分析网络数据?