目录
一、概述
1.1原理
1.2实现步骤
1.3应用场景
二、代码实现
2.1关键函数
2.1.1 GridMinimum 栅格最低点提取
2.1.2 可视化函数
2.2完整代码
三、实现效果
PCL点云算法汇总及实战案例汇总的目录地址链接:
PCL点云算法与项目实战案例汇总(长期更新)
一、概述
PCL GridMinimum 滤波器是用于从点云中提取栅格中最低点的一个操作。它将点云划分为规则的网格单元,并从每个网格中选择最低的点作为输出,常用于简化点云数据、减少噪声,或者在地形数据处理中保留最低的地面点。
1.1原理
GridMinimum 滤波器的原理是将点云划分成多个网格,然后对每个网格内的点进行比较,保留 Z 坐标最小的点(即最低点)。这有助于在处理不规则地形或存在噪声的点云时提取出更有代表性的点。整个过程可分为以下步骤:
- 定义每个栅格的尺寸。
- 在每个栅格中找到 Z 轴方向最低的点。
- 输出保留最低点的点云。
1.2实现步骤
- 加载点云数据。
- 使用 GridMinimum 设置栅格尺寸。
- 滤波并保留栅格中最低的点。
- 可视化滤波前和滤波后的点云。
1.3应用场景
- 地形简化:在处理地形数据时,提取栅格中最低的点以获取地面特征。
- 噪声去除:通过选择最低点来去除可能的悬浮物或噪声点。
- 数据压缩:减少点云数据量,同时保留地面或低层次信息。
二、代码实现
2.1关键函数
2.1.1 GridMinimum 栅格最低点提取
利用 GridMinimum 实现栅格内最低点的提取操作。
#include <pcl/filters/grid_minimum.h>
// 获取栅格最低点
void applyGridMinimumFilter(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& filtered_cloud, float resolution)
{
// 创建GridMinimum滤波器对象
pcl::GridMinimum<pcl::PointXYZ> grid_minimum;
grid_minimum.setInputCloud(cloud); // 设置输入点云
grid_minimum.setResolution(resolution); // 设置栅格的分辨率
grid_minimum.filter(*filtered_cloud); // 执行滤波并获取最低点
}
2.1.2 可视化函数
将滤波前和滤波后的点云显示在同一窗口的两个视口中,方便直观比较效果。
// 可视化点云数据
void visualizePointClouds(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& filtered_cloud)
{
// 创建PCLVisualizer对象
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Grid Minimum Viewer"));
// 设置第一个视口,显示原始点云
int vp_1, vp_2;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);
viewer->setBackgroundColor(1.0, 1.0, 1.0, vp_1);
viewer->addText("Original Point Cloud", 10, 10, "vp1_text", vp_1);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0); // 设置为红色
viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", vp_1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud"); // 设置原始点云大小
// 设置第二个视口,显示滤波后的点云
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);
viewer->setBackgroundColor(0.98, 0.98, 0.98, vp_2);
viewer->addText("Filtered Point Cloud", 10, 10, "vp2_text", vp_2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> filtered_color_handler(filtered_cloud, 0, 255, 0); // 设置为绿色
viewer->addPointCloud(filtered_cloud, filtered_color_handler, "filtered_cloud", vp_2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "filtered_cloud"); // 设置滤波后点云大小
viewer->addCoordinateSystem(1.0);
// 循环显示直到窗口关闭
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
}
2.2完整代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/grid_minimum.h>
#include <pcl/visualization/pcl_visualizer.h>
// 获取栅格最低点
void applyGridMinimumFilter(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& filtered_cloud, float resolution)
{
// 创建GridMinimum滤波器对象并传入分辨率
pcl::GridMinimum<pcl::PointXYZ> grid_minimum(resolution);
grid_minimum.setInputCloud(cloud); // 设置输入点云
grid_minimum.filter(*filtered_cloud); // 执行滤波并获取最低点
}
// 可视化点云数据
void visualizePointClouds(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& filtered_cloud)
{
// 创建PCLVisualizer对象
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Grid Minimum Viewer"));
// 设置第一个视口,显示原始点云
int vp_1, vp_2;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);
viewer->setBackgroundColor(1.0, 1.0, 1.0, vp_1);
viewer->addText("Original Point Cloud", 10, 10, "vp1_text", vp_1);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0); // 设置为红色
viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", vp_1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud"); // 设置原始点云大小
// 设置第二个视口,显示滤波后的点云
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);
viewer->setBackgroundColor(0.98, 0.98, 0.98, vp_2);
viewer->addText("Filtered Point Cloud", 10, 10, "vp2_text", vp_2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> filtered_color_handler(filtered_cloud, 0, 255, 0); // 设置为绿色
viewer->addPointCloud(filtered_cloud, filtered_color_handler, "filtered_cloud", vp_2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "filtered_cloud"); // 设置滤波后点云大小
viewer->addCoordinateSystem(1.0);
// 循环显示直到窗口关闭
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
}
int main(int argc, char** argv)
{
// -----------------------------读取点云数据---------------------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("data.pcd", *cloud) < 0)
{
PCL_ERROR("点云文件不存在");
return -1;
}
// 输出原始点云数据大小
std::cout << "原始点云个数:" << cloud->points.size() << std::endl;
// -----------------------------执行栅格最低点滤波----------------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);
float resolution = 0.1f; // 设置栅格分辨率
applyGridMinimumFilter(cloud, filtered_cloud, resolution);
// 输出滤波后点云数据大小
std::cout << "滤波后点云个数:" << filtered_cloud->points.size() << std::endl;
// -----------------------------可视化结果-----------------------------------
visualizePointClouds(cloud, filtered_cloud);
return 0;
}