PCL 最小点数约束的体素滤波(永久免费版)
目录
- 一、概述
- 1.1 原理
- 1.2 实现步骤
- 1.3应用场景
- 二、关键函数
- 2.1 头文件
- 2.2 读取点云
- 2.3 核心代码
- 2.4 可视化
- 三、完整代码
- 四、结果展示
即日起,付费专栏所有内容将以永久免费形式陆续进行发表!!!抄袭狗加油抄
一、概述
- VoxelGrid滤波中可联合使用setLeafSize函数和setMinimumPointsNumberPerVoxel函数实现每个体素内的最小点数的约束。
1.1 原理
最小点数约束的体素滤波是一种计算机图形学技术,主要用于图像处理和三维重建领域。它的核心思想是在像素网格(体素)上应用过滤操作,目的是去除噪声并保留重要的特征,如边缘和形状。通过设置每个体素需要达到的最小邻居点数阈值,这个过程可以消除孤立的噪声点,同时保持结构较为明显的区域。
1.2 实现步骤
具体步骤包括:
- 将输入图像转换为体素网格,每个体素表示一个小区域。
- 对每个体素计算其周围的邻域点数目。
- 如果某个体素的邻域点数低于预设的最小阈值,通常认为它是噪声,会被替换为其周围邻居的平均值或者采用更复杂的统计方法(如高斯滤波)平滑。
- 过程迭代直到收敛或满足预定条件,最终得到的是经过净化后的体素图像。
这种技术常用于医学影像分析、遥感图像处理以及游戏开发中的地形生成等场景。
1.3应用场景
最小点数约束的体素滤波(Minimum Point Number Voxel Filtering,简称MPVF)是一种常用的三维图像处理技术,尤其适用于计算机视觉和医学影像分析领域。它的应用场景包括:
- 3D重建:用于从点云数据中生成更平滑、连续的表面模型,减少噪声并保留关键结构特征。
- 物体检测:在自动驾驶和机器人导航中,用于提取和净化传感器(如激光雷达)收集到的环境中物体的轮廓。
- 医学成像:CT或MRI扫描结果中,去除噪声并增强组织边缘,有助于医生识别肿瘤、骨骼等结构。
- 游戏开发:用于优化3D环境地图,提高渲染效率,以及减少碰撞检测的复杂度。
- 遥感数据处理:对卫星或无人机拍摄的高分辨率图像进行预处理,减少地表细节的模糊影响。
二、关键函数
2.1 头文件
#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>
#include <boost/thread/thread.hpp>
2.2 读取点云
//读取点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud <pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read("bunny.pcd", *cloud);
cout << "Raw point :" << cloud->width * cloud->height << endl;
2.3 核心代码
//体素滤波
pcl::VoxelGrid<pcl::PointXYZ> vg;
vg.setInputCloud(cloud);
//设置最小体素边长
vg.setLeafSize(0.01f, 0.01f, 0.01f);
vg.setMinimumPointsNumberPerVoxel(10); // 设置每一个体素内需要包含的最小点个数
pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);
vg.filter(*filtered);
cout << "Filtered point :" << filtered->width * filtered->height << endl;
2.4 可视化
---------------------------------结果展示----------------------------------
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D PointCloud Viewer"));
// 设置视口1,显示原始点云
int v1;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 左侧窗口
viewer->setBackgroundColor(0.0, 0.0, 0.0, v1); // 黑色背景
viewer->addText("cloud1 PointCloud", 10, 10, "vp1_text", v1); // 标题
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 0, 255, 0); // 绿色
viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", v1);
// 设置视口2,显示体素中心点云
int v2;
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2); // 右侧窗口
viewer->setBackgroundColor(0.0, 0.0, 0.0, v2); // 黑色背景
viewer->addText("cloud2 PointCloud", 10, 10, "vp2_text", v2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> voxel_center_color_handler(filtered, 255, 0, 0); // 红色
viewer->addPointCloud(filtered, voxel_center_color_handler, "2_cloud", v2);
// 设置点的大小
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "2_cloud", v2);
// 添加坐标系
/* viewer->addCoordinateSystem(0.1);
viewer->initCameraParameters();*/
// 可视化循环
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
三、完整代码
#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>
#include <boost/thread/thread.hpp>
using namespace std;
int main(int argc, char** argv)
{
//读取点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud <pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read("bunny.pcd", *cloud);
cout << "Raw point :" << cloud->width * cloud->height << endl;
//体素滤波
pcl::VoxelGrid<pcl::PointXYZ> vg;
vg.setInputCloud(cloud);
//设置最小体素边长
vg.setLeafSize(0.01f, 0.01f, 0.01f);
vg.setMinimumPointsNumberPerVoxel(10); // 设置每一个体素内需要包含的最小点个数
pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);
vg.filter(*filtered);
cout << "Filtered point :" << filtered->width * filtered->height << endl;
// ---------------------------------结果展示----------------------------------
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D PointCloud Viewer"));
// 设置视口1,显示原始点云
int v1;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 左侧窗口
viewer->setBackgroundColor(0.0, 0.0, 0.0, v1); // 黑色背景
viewer->addText("cloud1 PointCloud", 10, 10, "vp1_text", v1); // 标题
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 0, 255, 0); // 绿色
viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", v1);
// 设置视口2,显示体素中心点云
int v2;
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2); // 右侧窗口
viewer->setBackgroundColor(0.0, 0.0, 0.0, v2); // 黑色背景
viewer->addText("cloud2 PointCloud", 10, 10, "vp2_text", v2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> voxel_center_color_handler(filtered, 255, 0, 0); // 红色
viewer->addPointCloud(filtered, voxel_center_color_handler, "2_cloud", v2);
// 设置点的大小
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "2_cloud", v2);
// 添加坐标系
/* viewer->addCoordinateSystem(0.1);
viewer->initCameraParameters();*/
// 可视化循环
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
return 0;
}