当前位置: 首页 > article >正文

PCL 点云高斯滤波

目录

一、概述

1.1原理

1.2实现步骤

1.3应用场景

二、代码实现

2.1关键函数

2.1.1 高斯滤波实现

2.1.2 可视化函数

2.2完整代码

三、实现效果


PCL点云算法汇总及实战案例汇总的目录地址链接:

PCL点云算法与项目实战案例汇总(长期更新)


一、概述

        高斯滤波 是一种平滑点云的常用方法,通过在点云上应用高斯核,减少噪声和尖锐边缘,得到更平滑的表面。它可以有效去除小尺度的噪声,保留较大结构的几何形状,因此常用于预处理阶段的点云数据平滑。

1.1原理

        高斯滤波的原理是:根据高斯核函数,对每个点的邻域进行加权平均。离中心点越近的点权重越大,离中心点越远的点权重越小。通过这种方式,可以减小点云的局部波动,实现平滑效果。

        高斯核函数定义如下:

        其中,σ 是标准差,控制平滑的程度。

1.2实现步骤

  1. 读取点云数据。
  2. 设置高斯滤波器的参数,包括搜索半径和标准差。
  3. 应用高斯滤波,生成平滑后的点云。
  4. 可视化原始点云和平滑后的点云。

1.3应用场景

  1. 去噪:去除点云中的高频噪声。
  2. 平滑表面:在进行曲面重建之前,对点云进行平滑处理。
  3. 图像处理:可用于图像中的 3D 场景点云的预处理。

二、代码实现

2.1关键函数

2.1.1 高斯滤波实现

通过设置邻域搜索的半径和高斯核的标准差,应用高斯滤波。

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/surface/mls.h>

// 高斯滤波函数
pcl::PointCloud<pcl::PointXYZ>::Ptr gaussianFilter(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,  // 输入点云
    float search_radius,                        // 搜索半径
    float sigma_smoothing                       // 高斯核标准差
)
{
    // 创建 MLS 滤波对象,并设置参数
    pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ> mls;
    mls.setInputCloud(cloud);  // 设置输入点云
    mls.setSearchRadius(search_radius);  // 设置邻域搜索半径
    mls.setPolynomialFit(true);  // 启用多项式拟合
    mls.setPolynomialOrder(2);  // 多项式阶数
    mls.setSqrGaussParam(sigma_smoothing * sigma_smoothing);  // 设置高斯平滑的参数(标准差)

    // 平滑处理后的点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr smoothed_cloud(new pcl::PointCloud<pcl::PointXYZ>);
    mls.process(*smoothed_cloud);  // 应用平滑处理

    return smoothed_cloud;  // 返回平滑后的点云
}

2.1.2 可视化函数

使用 PCL 可视化库展示原始点云和高斯平滑后的点云。

#include <pcl/visualization/pcl_visualizer.h>

// 可视化原始点云和平滑后的点云
void visualizePointClouds(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,            // 原始点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr smoothed_cloud    // 平滑后的点云
)
{
    // 创建可视化器
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Gaussian Smoothing Viewer"));

    // 创建视口1,显示原始点云
    int vp_1;
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);  // 创建左侧窗口
    viewer->setBackgroundColor(1.0, 1.0, 1.0, vp_1);   // 设置白色背景
    viewer->addText("Raw Point Clouds", 10, 10, "v1_text", vp_1);  // 添加标题

    // 设置原始点云的颜色为红色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0);  // 红色
    viewer->addPointCloud<pcl::PointXYZ>(cloud, cloud_color_handler, "original_cloud", vp_1);  // 添加原始点云

    // 创建视口2,显示平滑后的点云
    int vp_2;
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);  // 创建右侧窗口
    viewer->setBackgroundColor(0.98, 0.98, 0.98, vp_2);  // 设置浅灰色背景
    viewer->addText("Smoothed Point Clouds", 10, 10, "v2_text", vp_2);  // 添加标题

    // 设置平滑后的点云颜色为绿色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> smoothed_cloud_color_handler(smoothed_cloud, 0, 255, 0);  // 绿色
    viewer->addPointCloud<pcl::PointXYZ>(smoothed_cloud, smoothed_cloud_color_handler, "smoothed_cloud", vp_2);  // 添加平滑后的点云

    // 设置点的大小(可选)
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud", vp_1);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "smoothed_cloud", vp_2);

    // 启动可视化循环
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);  // 刷新可视化器
    }
}

2.2完整代码

// C++头文件
#include <iostream>
// PCL头文件
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/surface/mls.h>               // 高斯平滑滤波
#include <pcl/visualization/pcl_visualizer.h>

// 高斯滤波函数
pcl::PointCloud<pcl::PointXYZ>::Ptr gaussianFilter(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,  // 输入点云
    float search_radius,                        // 搜索半径
    float sigma_smoothing                       // 高斯核标准差
)
{
    // 创建 MLS 滤波对象,并设置参数
    pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ> mls;
    mls.setInputCloud(cloud);  // 设置输入点云
    mls.setSearchRadius(search_radius);  // 设置邻域搜索半径
    mls.setPolynomialFit(true);  // 启用多项式拟合
    mls.setPolynomialOrder(2);  // 多项式阶数
    mls.setSqrGaussParam(sigma_smoothing * sigma_smoothing);  // 设置高斯平滑的参数(标准差)

    // 平滑处理后的点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr smoothed_cloud(new pcl::PointCloud<pcl::PointXYZ>);
    mls.process(*smoothed_cloud);  // 应用平滑处理

    return smoothed_cloud;  // 返回平滑后的点云
}

// 可视化原始点云和平滑后的点云
void visualizePointClouds(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,            // 原始点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr smoothed_cloud    // 平滑后的点云
)
{
    // 创建可视化器
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Gaussian Smoothing Viewer"));

    // 创建视口1,显示原始点云
    int vp_1;
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);  // 创建左侧窗口
    viewer->setBackgroundColor(1.0, 1.0, 1.0, vp_1);   // 设置白色背景
    viewer->addText("Raw Point Clouds", 10, 10, "v1_text", vp_1);  // 添加标题

    // 设置原始点云的颜色为红色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0);  // 红色
    viewer->addPointCloud<pcl::PointXYZ>(cloud, cloud_color_handler, "original_cloud", vp_1);  // 添加原始点云

    // 创建视口2,显示平滑后的点云
    int vp_2;
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);  // 创建右侧窗口
    viewer->setBackgroundColor(0.98, 0.98, 0.98, vp_2);  // 设置浅灰色背景
    viewer->addText("Smoothed Point Clouds", 10, 10, "v2_text", vp_2);  // 添加标题

    // 设置平滑后的点云颜色为绿色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> smoothed_cloud_color_handler(smoothed_cloud, 0, 255, 0);  // 绿色
    viewer->addPointCloud<pcl::PointXYZ>(smoothed_cloud, smoothed_cloud_color_handler, "smoothed_cloud", vp_2);  // 添加平滑后的点云

    // 设置点的大小(可选)
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud", vp_1);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "smoothed_cloud", vp_2);

    // 启动可视化循环
    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("ro_bunny.pcd", *cloud) < 0)
    {
        PCL_ERROR("Could not read file\n");
        return (-1);  // 返回错误
    }

    // -------------------------------高斯滤波---------------------------------
    float search_radius = 0.01;   // 设置搜索半径
    float sigma_smoothing = 0.01;  // 设置高斯核标准差
    pcl::PointCloud<pcl::PointXYZ>::Ptr smoothed_cloud = gaussianFilter(cloud, search_radius, sigma_smoothing);  // 应用高斯滤波

    // ------------------------------可视化原始点云和平滑后的点云---------------------------------
    visualizePointClouds(cloud, smoothed_cloud);  // 调用可视化函数

    return 0;
}

三、实现效果


http://www.kler.cn/news/330374.html

相关文章:

  • netty之基础aio,bio,nio
  • dcatadmin 自定义登录页面
  • webpack 和 vite 区别
  • 十一不停歇-学习ROS2第一天 (10.2 10:45)
  • Arduino UNO R3自学笔记18 之 Arduino的外部中断、定时中断介绍及应用
  • C++_23_STL容器
  • TCP --- 确认应答机制以及三次握手四次挥手
  • 【JavaScript】数组函数汇总
  • 【AI大模型-文心-思维树解读-仓颉精通之路-7】
  • 四,MyBatis-Plus 当中的主键策略和分页插件的(详细实操使用)
  • C初阶(六)--- static 来喽
  • IDEA:Properties in parent definition are prohibited
  • 系统架构设计师-英文翻译题(2022年下半年)
  • Android build子系统(01)Ninja构建系统解读
  • Python字符串string方法大全及使用方法[2]以及FastApi关闭接口文档、隐藏部分接口、关闭schemes的实现
  • 考研日语 - 高频核心 2200 词(七)
  • PostgreSQL 中的公用表表达式(CTE)学习指南
  • Vxe UI vue vxe-table vxe-text-ellipsis 如何实现单元格多行文本超出、多行文本溢出省略
  • 0基础学前端 day10--css预处理
  • 如何查询 Elasticsearch 的版本