文章目录

  • 0.引言
  • 1.CloudCompare界面设计滤波(filter)按钮
  • 2.PassThrough直通滤波器
  • 3.StatisticalOutlierRemoval统计滤波器
  • 4.RadiusOutlierRemoval半径滤波器
  • 5.ConditionRemoval条件滤波器
  • 6.ProjectInliers投影滤波器
  • 7.ModelOutlierRemoval模型滤波器
  • 8.GaussianKernel高斯滤波器

0.引言

  因笔者课题涉及点云处理,需要通过PCL进行点云数据一系列处理分析,查阅现有网络资料,对常用PCL点云滤波器进行代码实现,本文记录滤波器实现过程。

1.CloudCompare界面设计滤波(filter)按钮

  (1)设计.ui文件
  ①设计按钮
  

  ②编译.ui
  

  (2)修改mainwindow.h文件
  

//点云滤波
void doActionPCLPassThrough(); // 直通滤波器  
void doActionPCLStatisticalOutlierRemoval(); // 统计滤波器  
void doActionPCLRadiusOutlierRemoval(); // 半径滤波器  
void doActionPCLConditionRemoval(); // 条件滤波器  
void doActionPCLProjectInliers(); // 投影滤波器  
void doActionPCLModelOutlierRemoval(); // 模型滤波器  
void doActionPCLGaussianKernel(); // 高斯滤波器

  (3)修改mainwindow.cpp文件
  ①添加头文件
  


#include <pcl/filters/passthrough.h>// 直通滤波器
#include <pcl/filters/statistical_outlier_removal.h>// 统计滤波器  
#include <pcl/filters/radius_outlier_removal.h>// 半径滤波器  
#include <pcl/filters/conditional_removal.h>// 条件滤波器  
#include <pcl/filters/project_inliers.h>// 投影滤波器  
#include <pcl/filters/model_outlier_removal.h>// 模型滤波器  
#include <pcl/ModelCoefficients.h>  
#include <pcl/filters/convolution_3d.h>// GaussianKernel高斯滤波器

  ②添加实现代码
  

#include <pcl/filters/passthrough.h>// 直通滤波器
#include <pcl/filters/statistical_outlier_removal.h>// 统计滤波器  
#include <pcl/filters/radius_outlier_removal.h>// 半径滤波器  
#include <pcl/filters/conditional_removal.h>// 条件滤波器  
#include <pcl/filters/project_inliers.h>// 投影滤波器  
#include <pcl/filters/model_outlier_removal.h>// 模型滤波器  
#include <pcl/ModelCoefficients.h>  
#include <pcl/filters/convolution_3d.h>// GaussianKernel高斯滤波器

  ③添加信号槽函数
  

connect(m_UI->actionPassThrough, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLPassThrough);//直通滤波器
connect(m_UI->actionStatisticalOutlierRemoval, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLStatisticalOutlierRemoval);//统计滤波器  
connect(m_UI->actionRadiusOutlierRemoval, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLRadiusOutlierRemoval);//半径滤波器  
connect(m_UI->actionConditionRemoval, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLConditionRemoval);//条件滤波器  
connect(m_UI->actionProjectInliers, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLProjectInliers);//投影滤波器  
connect(m_UI->actionModelOutlierRemoval, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLModelOutlierRemoval);//模型滤波器  
connect(m_UI->actionGaussianKernel, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLGaussianKernel);//GaussianKernel高斯滤波器

  (4)生成
  

2.PassThrough直通滤波器

  (1)实现代码

// 直通滤波器
void MainWindow::doActionPCLPassThrough()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    //float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("搜索半径: "), 0.1, 0, 100, 4);  
    // ----------------------------直通滤波器--------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::PassThrough<pcl::PointXYZ> us;  
    us.setInputCloud(cloud);  
    us.setFilterFieldName("z");//设置滤波所需字段z  
    us.setFilterLimits(-0.1,1);//设置z字段过滤范围  
    us.setFilterLimitsNegative(true);//默认false,保留范围内的点云;true,保存范围外的点云  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("PassThrough"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)滤波结果
  ①滤波前
  

  ②滤波后
  

3.StatisticalOutlierRemoval统计滤波器

  (1)实现代码

// 统计滤波器
void MainWindow::doActionPCLStatisticalOutlierRemoval()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    //float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("搜索半径: "), 0.1, 0, 100, 4);  
    // ----------------------------统计滤波器--------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::StatisticalOutlierRemoval<pcl::PointXYZ> us;  
    us.setInputCloud(cloud);        //设置待滤波点云  
    us.setMeanK(50);        //设置查询点近邻点的个数  
    us.setStddevMulThresh(1.0);                //设置标准差乘数,来计算是否为离群点的阈值  
    //sor.setNegative(true);        //默认false,保存内点;true,保存滤掉的离群点  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("StatisticalOutlierRemoval"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)滤波结果
  ①滤波前
  

  ②滤波后
  

4.RadiusOutlierRemoval半径滤波器

  (1)实现代码

// 半径滤波器
void MainWindow::doActionPCLRadiusOutlierRemoval()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("半径: "), 0.05, 0, 100, 4);  
    // ----------------------------半径滤波器--------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> us;  
    us.setInputCloud(cloud);        //设置待滤波点云  
    us.setRadiusSearch(radius);        //设置查询点的半径范围  
    us.setMinNeighborsInRadius(5);        //设置判断是否为离群点的阈值,即半径内至少包括的点数  
    us.setNegative(true);        //默认false,保存内点;true,保存滤掉的外点  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("RadiusOutlierRemoval"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)滤波结果
  ①滤波前
  

  ②滤波后
  

5.ConditionRemoval条件滤波器

  (1)实现代码

// 条件滤波器
void MainWindow::doActionPCLConditionRemoval()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    //float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("搜索半径: "), 0.1, 0, 100, 4);  
    // ----------------------------条件滤波器--------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    /*创建条件限定下的滤波器*/  
    pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<pcl::PointXYZ>());//创建条件定义对象range_cond  
    //为条件定义对象添加比较算子  
    range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new  
        pcl::FieldComparison<pcl::PointXYZ>("x", pcl::ComparisonOps::GT, -0.1)));//添加在x字段上大于 -0.1 的比较算子  
  
    range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new  
        pcl::FieldComparison<pcl::PointXYZ>("x", pcl::ComparisonOps::LT, 1.0)));//添加在x字段上小于 1.0 的比较算子  
  
    pcl::ConditionalRemoval<pcl::PointXYZ> us;        //创建滤波器对象  
    us.setCondition(range_cond);                //用条件定义对象初始化  
    us.setInputCloud(cloud);                //设置待滤波点云  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("ConditionRemoval"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)滤波结果
  ①滤波前
  

  ②滤波后
  

6.ProjectInliers投影滤波器

  (1)实现代码

// 投影滤波器
void MainWindow::doActionPCLProjectInliers()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("搜索半径: "), 0.1, 0, 100, 4);  
    // ----------------------------投影滤波器--------------------------------------  
    //创建 x+y+z=0 平面  
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());  
    coefficients->values.resize(4);        //设置模型系数的大小  
    coefficients->values[0] = 1.0;        //x系数  
    coefficients->values[1] = 1.0;        //y系数  
    coefficients->values[2] = 1.0;        //z系数  
    coefficients->values[3] = 0.0;        //常数项  
    //投影滤波  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::ProjectInliers<pcl::PointXYZ> us;  
    us.setModelType(pcl::SACMODEL_PLANE);        //设置对象对应的投影模型  
    us.setInputCloud(cloud);                //设置输入点云  
    us.setModelCoefficients(coefficients);//设置模型对应的系数  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("ProjectInliers"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)滤波结果
  ①滤波前
  

  ②滤波后
  

7.ModelOutlierRemoval模型滤波器

  (1)实现代码

// 模型滤波器
void MainWindow::doActionPCLModelOutlierRemoval()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    //float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("搜索半径: "), 0.1, 0, 100, 4);  
    // ----------------------------模型滤波器--------------------------------------  
    //设置模型系数  
    pcl::ModelCoefficients model_coeff;  
    model_coeff.values.resize(4);  
    model_coeff.values[0] = 1.0;  
    model_coeff.values[1] = 1.0;  
    model_coeff.values[2] = 1.0;  
    model_coeff.values[3] = 0.0;  
    ///模型滤波  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::ModelOutlierRemoval<pcl::PointXYZ> us;  
    us.setModelCoefficients(model_coeff);                //为模型对象添加模型系数  
    us.setThreshold(0.1);                //设置判断是否为模型内点的阈值  
    us.setModelType(pcl::SACMODEL_PLANE);                //设置模型类别  
    us.setInputCloud(cloud);                //输入待滤波点云  
    us.setNegative(true);        //默认false,保存内点;true,保存滤掉的外点  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("ModelOutlierRemoval"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)滤波结果
  ①滤波前
  

  ②滤波后
  

8.GaussianKernel高斯滤波器

  (1)实现代码

// 高斯滤波器
void MainWindow::doActionPCLGaussianKernel()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("搜索半径: "), 0.1, 0, 100, 4);  
    // ----------------------------高斯滤波器--------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    //pcl::BilateralFilter<pcl::PointXYZ> us;  
    //-----------基于高斯核函数的卷积滤波实现------------------------  
    pcl::filters::GaussianKernel<pcl::PointXYZ, pcl::PointXYZ> kernel;  
    kernel.setSigma(4);//高斯函数的标准方差,决定函数的宽度  
    kernel.setThresholdRelativeToSigma(4);//设置相对Sigma参数的距离阈值  
    kernel.setThreshold(0.05);//设置距离阈值,若点间距离大于阈值则不予考虑  
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);  
    tree->setInputCloud(cloud);  
    //---------设置Convolution 相关参数---------------------------  
    pcl::filters::Convolution3D<pcl::PointXYZ, pcl::PointXYZ, pcl::filters::GaussianKernel<pcl::PointXYZ, pcl::PointXYZ>> convolution;  
    convolution.setKernel(kernel);//设置卷积核  
    convolution.setInputCloud(cloud);  
    convolution.setNumberOfThreads(8);  
    convolution.setSearchMethod(tree);  
    convolution.setRadiusSearch(radius);  
    convolution.convolve(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("GaussianKernel"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)滤波结果
  ①滤波前
  

  ②滤波后
  

参考资料:
[1] 来吧!我在未来等你!. CloudCompare二次开发之如何配置PCL点云库?; 2023-05-14 [accessed 2023-05-15].
[2] 悠缘之空. PCL函数库摘要——点云滤波; 2021-05-30 [accessed 2023-05-15].
[3] 孙 悟 空. PCL:点云滤波汇总:算法原理 + 代码实现; 2021-03-08 [accessed 2023-05-15].
[4] 学习OpenCV. PCL点云滤波器总结; 2022-03-03 [accessed 2023-05-15].
[5] 学习OpenCV. PCL点云处理_点云滤波(3); 2022-03-03 [accessed 2023-05-15].
[6] 点云侠. PCL 高斯滤波; 2021-02-27 [accessed 2023-05-15].