前言
一、效果展示
二、核心代码
std::vector<PointVectorPair>cgal_unsampling(std::vector<PointVectorPair> points,double sharpness_angle,double edge_sensitivity,
double neighbor_radius, int number_of_output_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;
}
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)));
}
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 <QDialog>
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
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 <CGAL/Simple_cartesian.h>
#include <CGAL/edge_aware_upsample_point_set.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/IO/write_points.h>
#include <string>
#include <vector>
#include <fstream>
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
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 )
{
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 <cgal_function.h>
private slots:
void pressBtn_unsampling();
void Unsampling_clicked(QString data1,QString data2,QString data3,QString data4);
private:
Filter_unsampling *dialog_unsampling;
2).cpp文件
{
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;
}
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);
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中还有很多优秀的点云、网格的处理算法,以后会陆陆续续加入进来。 |
|