CloudCompare二次开发之如何通过PCL进行点云滤波?

这篇具有很好参考价值的文章主要介绍了CloudCompare二次开发之如何通过PCL进行点云滤波?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0.引言

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

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

  (1)设计.ui文件
  ①设计按钮
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  ②编译.ui
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  (2)修改mainwindow.h文件
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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

  (3)修改mainwindow.cpp文件
  ①添加头文件
  CloudCompare二次开发之如何通过PCL进行点云滤波?

#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高斯滤波器

  ②添加实现代码
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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

  ③添加信号槽函数
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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)生成
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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)滤波结果
  ①滤波前
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  ②滤波后
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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)滤波结果
  ①滤波前
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  ②滤波后
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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)滤波结果
  ①滤波前
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  ②滤波后
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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)滤波结果
  ①滤波前
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  ②滤波后
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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)滤波结果
  ①滤波前
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  ②滤波后
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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)滤波结果
  ①滤波前
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  ②滤波后
  CloudCompare二次开发之如何通过PCL进行点云滤波?

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)滤波结果
  ①滤波前
  CloudCompare二次开发之如何通过PCL进行点云滤波?

  ②滤波后
  CloudCompare二次开发之如何通过PCL进行点云滤波?

参考资料:
[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].文章来源地址https://www.toymoban.com/news/detail-449519.html

到了这里,关于CloudCompare二次开发之如何通过PCL进行点云滤波?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PCL 改进点云双边滤波算法

    我们先来回顾一下之前该算法的计算过程,在二维图像领域中,双边滤波算法是通过考虑中心像素点到邻域像素点的距离(一边)以及像素亮度差值所确定的权重(另一边)来修正当前采样中心点的位置,从而达到平滑滤波效果。同时也会有选择性的剔除部分与当前采样点“差异”

    2024年02月07日
    浏览(42)
  • 使用PCL滤波器实现点云裁剪

    点云裁剪是根据提取划分或者说标注出来的点云区域(ROI区域),对点云进行区域分离(点云裁剪和点云分割还是有区别的,所以这里用分离而不是分割)。根据已知的ROI区域,对点云进行裁剪。要么留下点云ROI区域,要么去除。 ROI区域一般都是一个矩形,即(x,y,width,

    2024年02月15日
    浏览(43)
  • PCL点云处理之CSF布料模拟滤波(五十九)

    PCL中并没有找到现成的CSF滤波代码,需要我们自己下载并编译,在使用时添加到头文件中调用,才能最终实现CSF编程使用。下面是具体的编译过程: (实际上就是作者给了源代码和CMAKElists的构建文件,我们使用CMake软件转换得到链接库,用于我们自己的代码中) https://githu

    2023年04月17日
    浏览(52)
  • CloudCompare 二次开发(20)——二次曲面拟合

    本文由CSDN点云侠原创,原文链接。爬虫网站自重。   由CloudCompare——点云二次曲面拟合一文知:CloudCompare软件中的已经集成了二次曲面拟合功能,但是计算出来的拟合参数是不正确的。因此,本文在原有算法的基础上进行修改,使输出的参数结果正确。 mainwindow.cpp 文件

    2024年02月06日
    浏览(49)
  • PCL点云处理之多种体素滤波方法大汇总(一百六十四)

    对PCL中的基于八叉树体素滤波方法,以及在此基础上,自己进一步实现的新滤波方法,进行一个汇总,列出各自的效果和,具体的实现代码 PCL中自带的滤波方法,也是最常用的滤波方法,应该是体素中的点云重心取代原始点,但使用时要注意体素不可过小,

    2024年02月05日
    浏览(51)
  • CloudCompare 二次开发(26)——RANSAC分割多个平面

      使用CloudCompare与PCL编程实现的RANSAC分割多个平面。具体计算原理见:PCL RANSAC分割多个平面。 1、 mainwindow.h 文件 public 中添加: 2、 mainwindow.cpp 文件 void MainWindow::connectActions() 函数中添加:

    2024年01月25日
    浏览(44)
  • PCL 使用LCCP算法进行点云分割

      LCCP是Locally Convex Connected Patches的缩写,算法大致可以分成两个部分: 基于超体聚类的过分割。 在超体聚类的基础上再聚类。 /

    2024年02月12日
    浏览(50)
  • 使用PCL库中PPF+ICP进行点云目标识别

    在使用过程中踩到的坑:    (1):PointCloudPPFSignature::Ptr cloud_model_ppf(new PointCloudPPFSignature());     PPFEstimationPointNormal, PointNormal, PPFSignature ppf_estimator;     ppf_estimator.setInputCloud(cloud_model_input);     ppf_estimator.setInputNormals(cloud_model_input);     ppf_estimator.compute(*cloud_model_ppf); 运行到

    2024年02月15日
    浏览(70)
  • CloudCompare 二次开发(6)——插件中拖拽添加Qt窗口(区域生长算法为例)

    本文由CSDN点云侠原创,原文链接。爬虫网站自重。   手动拖拽的方式搭建Qt对话框界面的制作流程,以PCL中的点云区域生长算法为例进行制作。 1、将 ....pluginsexample 路径下的 ExamplePlugin 复制一份并修改名字为 CCPointCloudProcess 。 2、创建窗口UI文件 使用任意Qt工程新建对话

    2023年04月11日
    浏览(56)
  • VisualStudio如何配置PCL点云库?

      因笔者课题涉及点云处理,需要通过PCL进行点云数据分析处理,查阅现有网络资料,实现了VisualStudio2015(x86)配置PCL1.8.1点云库,本文记录实现配置的过程。    (1)下载PCL   下载地址: https://github.com/PointCloudLibrary/pcl/releases/tag/pcl-1.8.1   笔者的VS软件为32位的VS2015,

    2024年02月06日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包