《QT+PCL 第三章》结合CGAL实现点云上采样

《QT+PCL 第三章》结合CGAL实现点云上采样,第1张

CGAL+PCL 实现点云上采样
  • 前言

  • 一、效果展示


  • 二、核心代码


  • 三、QT设置


  • 四、结语

前言

本节主要将CGAL中上采用功能添加到QT软件中。



参考链接:CGAL实现点云上采样


一、效果展示


二、核心代码

1、点云增采用代码

std::vector<PointVectorPair>cgal_unsampling(std::vector<PointVectorPair> points,double sharpness_angle,double edge_sensitivity,
                                          double neighbor_radius, int number_of_output_points )
{
    //std::vector out_points;
    CGAL::edge_aware_upsample_point_set<Concurrency_tag>(
        points,std::back_inserter(points),
        CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>()).
        normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>()).
        sharpness_angle(sharpness_angle).
        edge_sensitivity(edge_sensitivity).
        neighbor_radius(neighbor_radius).
        number_of_output_points(number_of_output_points));
    return points;
}

参数设置:

2、pcl点云与CGAL点云相互转化

		//pcl->CGAL
        std::vector<PointVectorPair> cgal_cloud;
        for(int i=0;i<cloud_with_normals->size();i++)
        {
           double px=cloud_with_normals->points[i].x;
           double py=cloud_with_normals->points[i].y;
           double pz=cloud_with_normals->points[i].z;
           double nx=cloud_with_normals->points[i].normal_x;
           double ny=cloud_with_normals->points[i].normal_y;
           double nz=cloud_with_normals->points[i].normal_z;
           cgal_cloud.push_back(PointVectorPair(CGAL_Point(px,py,pz),Vector(nx,ny,nz)));
        }

		//CGAL-pcl
		for(int i=0;i<cgal_cloud.size();i++)
        {
            pcl::PointXYZ p;
           	CGAL_Point p_temp=cgal_cloud[i].first;
            p.x=p_temp.hx();
            p.y=p_temp.hy();
            p.z=p_temp.hz();
            cloud.push_back(p);
        }
		

三、QT设置

1、ui设置与相关文件设置
新建Filter_upsamping.ui,会自动生成filter_upsampling.h与filter_upsampling.cpp
1)ui设置
2).h文件设置
3).cpp文件设置

1)ui设置与布局

2).h文件

#ifndef FILTER_UNSAMPLING_H
#define FILTER_UNSAMPLING_H

#include 

namespace Ui {
class Filter_unsampling;
}

class Filter_unsampling : public QDialog
{
    Q_OBJECT
signals:
    void sendData(QString data1,QString data2,QString data3,QString data4);

public:
    explicit Filter_unsampling(QWidget *parent = nullptr);
    ~Filter_unsampling();

private slots:
    void on_buttonBox_accepted();

private:
    Ui::Filter_unsampling *ui;
};

#endif // FILTER_UNSAMPLING_H

3).cpp文件

#include "filter_unsampling.h"
#include "ui_filter_unsampling.h"

Filter_unsampling::Filter_unsampling(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Filter_unsampling)
{
    ui->setupUi(this);
}

Filter_unsampling::~Filter_unsampling()
{
    delete ui;
}

void Filter_unsampling::on_buttonBox_accepted()
{
    emit sendData(ui->lineEdit->text(),ui->lineEdit_2->text(),ui->lineEdit_3->text(),ui->lineEdit_4->text());

    this->close();
}

2、CGAL_function设置
类似于pcl_function,创建CGAL_function.h与.cpp文件,实现CGAL中相关算法。



1)cgal_function.h文件
2)cgal_function.cpp文件

1).h文件
#ifndef CGAL_FUNCTION_H
#define CGAL_FUNCTION_H


#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 CGAL_Point;
typedef Kernel::Vector_3 Vector;
typedef std::pair<CGAL_Point, Vector> PointVectorPair;
typedef CGAL::Parallel_if_available_tag Concurrency_tag;


std::vector<PointVectorPair>cgal_unsampling(std::vector<PointVectorPair> points,double sharpness_angle,double edge_sensitivity,
                                          double neighbor_radius, int number_of_output_points );

#endif // CGAL_FUNCTION_H

2).cpp文件

#include "cgal_function.h"

std::vector<PointVectorPair>cgal_unsampling(std::vector<PointVectorPair> points,double sharpness_angle,double edge_sensitivity,
                                          double neighbor_radius, int number_of_output_points )
{
    //std::vector out_points;
    CGAL::edge_aware_upsample_point_set<Concurrency_tag>(
        points,std::back_inserter(points),
        CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>()).
        normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>()).
        sharpness_angle(sharpness_angle).
        edge_sensitivity(edge_sensitivity).
        neighbor_radius(neighbor_radius).
        number_of_output_points(number_of_output_points));
    return points;
}

3、mainwindow设置
1).h文件:添加相关头文件,槽函数声明;
2).cpp文件:添加action、connect action到槽函数、槽函数实现

1).h文件

#include //头文件

private slots://槽函数

    void pressBtn_unsampling();//上采样

    void Unsampling_clicked(QString data1,QString data2,QString data3,QString data4);
    
private:

	Filter_unsampling *dialog_unsampling;

2).cpp文件

//构造函数
{
//创建action,并添加到目录

//connect action to slot function
connect(UpSample_action,SIGNAL(triggered()),this,SLOT(pressBtn_unsampling()));
 
}
//槽函数实现
void MainWindow::pressBtn_unsampling()
{
    dialog_unsampling=new Filter_unsampling();

    connect(dialog_unsampling,SIGNAL(sendData(QString,QString,QString,QString)),this,
            SLOT(Unsampling_clicked(QString,QString,QString,QString)));

    if(dialog_unsampling->exec()==QDialog::Accepted){}

    delete dialog_unsampling;
}

//上采样
void MainWindow::Unsampling_clicked(QString data1,QString data2,QString data3,QString data4)
{

    if(cloud.empty())
    {
        QMessageBox::warning(this, "Warning","无点云输入!");

        return;
    }
    else
    {
        if(data1.isEmpty()||data2.isEmpty()||data3.isEmpty()||data4.isEmpty())
        {
            QMessageBox::warning(this, "Warning","参数格式输入错误!");

            return;
        }
        //up采样滤波
        double  sharpness_angle =data1.toDouble();
        double  edge_sensitivity =data2.toDouble();
        double  neighbor_radius =data3.toDouble();
        int  number_of_output_points  =data4.toInt();


        //计算法线
        auto normals=pcl_feature_normals_k(cloud.makeShared(),10);
        auto cloud_with_normals=pcl_base_cloudwithnormals(cloud.makeShared(),normals);


        //转换为cgal格式
        std::vector<PointVectorPair> cgal_cloud;
        for(int i=0;i<cloud_with_normals->size();i++)
        {

           double px=cloud_with_normals->points[i].x;
           double py=cloud_with_normals->points[i].y;
           double pz=cloud_with_normals->points[i].z;
           double nx=cloud_with_normals->points[i].normal_x;
           double ny=cloud_with_normals->points[i].normal_y;
           double nz=cloud_with_normals->points[i].normal_z;
           cgal_cloud.push_back(PointVectorPair(CGAL_Point(px,py,pz),Vector(nx,ny,nz)));
        }

        cgal_cloud=cgal_unsampling(cgal_cloud,sharpness_angle, edge_sensitivity,neighbor_radius,  number_of_output_points*cgal_cloud.size());

        cloud.clear();

        for(int i=0;i<cgal_cloud.size();i++)
        {
            pcl::PointXYZ p;
            CGAL_Point p_temp=cgal_cloud[i].first;

            p.x=p_temp.hx();
            p.y=p_temp.hy();
            p.z=p_temp.hz();

            cloud.push_back(p);
        }


        ui->textBrowser->clear();
        QString PointSize = QString("%1").arg(cloud.size());
        ui->textBrowser->insertPlainText("点云数量: "+PointSize);
        ui->textBrowser->setFont(QFont( "Arial" , 9 ,QFont::Normal ));

        viewer->removeAllPointClouds();
        viewer->removeAllShapes();
        viewer->addPointCloud(cloud.makeShared() ,cloud_name[0]);
        viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, point_size, cloud_name[0]);
        viewer->resetCamera();
        ui->qvtkWidget->update();
    }

}

四、结语

qmake、构建一下,至此,QT中添加CGAL的点云上采样功能至此结束。



CGAL中还有很多优秀的点云、网格的处理算法,以后会陆陆续续加入进来。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/568263.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存