目录
添加对话框控件
布局ui
mainwindow.h添加头文件
filter_voxel.h设置
#ifndef FILTER_VOXEL_H
#define FILTER_VOXEL_H
#include <QDialog>
namespace Ui {
class Filter_voxel;
}
class Filter_voxel : public QDialog
{
Q_OBJECT
signals:
void sendData(QString data);
public:
explicit Filter_voxel(QWidget *parent = nullptr);
~Filter_voxel();
private slots:
void on_buttonBox_accepted();
private:
Ui::Filter_voxel *ui;
};
#endif // FILTER_VOXEL_H
filter_voxel.cpp设置
#include "filter_voxel.h"
#include "ui_filter_voxel.h"
Filter_voxel::Filter_voxel(QWidget *parent) :
QDialog(parent),
ui(new Ui::Filter_voxel)
{
ui->setupUi(this);
}
Filter_voxel::~Filter_voxel()
{
delete ui;
}
void Filter_voxel::on_buttonBox_accepted()
{
emit sendData(ui->lineEdit->text());
this->close();
}
pcl_function.h添加相关头文件,声明下采样函数
/**********************************pcl格式*****************************/
#include <pcl/common/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/vtk_io.h>
#include <pcl/io/vtk_lib_io.h>
/**********************************pcl显示***************************/
#include <boost/shared_ptr.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/histogram_visualizer.h>
#include <pcl/visualization/pcl_plotter.h>
#include <pcl/visualization/point_cloud_color_handlers.h>
#include <pcl/visualization/point_cloud_handlers.h>
#include <pcl/visualization/point_cloud_geometry_handlers.h>
/**********************************pcl滤波***************************/
#include <pcl/filters/voxel_grid.h> //体素滤波
pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_filter_voxel(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,float leaf_size);
pcl_function.cpp中添加下采样函数,其中代码还少,都贴出来了。
#include "pcl_function.h"
//体素
pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_filter_voxel(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,float leaf_size)
{
pcl::VoxelGrid<pcl::PointXYZ> voxel_grid;
voxel_grid.setLeafSize(leaf_size,leaf_size,leaf_size);
voxel_grid.setInputCloud(cloud);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out (new pcl::PointCloud<pcl::PointXYZ> ()) ;
voxel_grid.filter(*cloud_out);
return cloud_out;
}
Pcl_function::Pcl_function()
{
}
mainwindow.h添加槽函数,实例对话框
private slots:
void pressBtn_voxel();//菜单栏体素按钮
void Voxel_clicked(QString data); //体素滤波
private:
//vtk转pcl要用到
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
//实例对话框
Filter_voxel *dialog_voxel;
点云处理完后还得从pcl转vtk再可视化,把读取点云并可视化中的open_clicked函数中转化与可视化部分代码扒下来封装到updatePointCloud函数中,方便调用。
public:
void updatePointCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud);
mainwindow.cpp构造函数中,添加代码在菜单栏创建滤波—>下采样—>体素滤波
QMenu *filter_menu = menu_bar->addMenu("滤波");
filter_menu->addMenu("下采样")->addAction("体素滤波", this, MainWindow::pressBtn_voxel);
pcl转vtk并可视化代码
void MainWindow::updatePointCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
ui->textBrowser->clear();
// 获取点云中点的数量并将其转换为字符串
int point_num = cloud->size();
QString point_num_str = QString::number(point_num);
// 在textbrowser中显示点云中点的数量
ui->textBrowser->append("点云中点的数量为:" + point_num_str);
// 将点云数据转换为VTK的点数据
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
for (size_t i = 0; i < cloud->size(); ++i) {
pcl::PointXYZ p = cloud->at(i);
points->InsertNextPoint(p.x, p.y, p.z);
}
// 创建VTK的点数据对象
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
// 使用vtkVertexGlyphFilter将每个点变成一个小球体
vtkSmartPointer<vtkVertexGlyphFilter> vertexFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();
vertexFilter->SetInputData(polydata);
vertexFilter->Update();
// 创建VTK的点数据mapper
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(vertexFilter->GetOutputPort());
// 创建VTK的actor
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// 将actor添加到renderer中
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
// 将renderer添加到vtkRenderWindow中
vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
renderWindow->AddRenderer(renderer);
// 将vtkRenderWindow显示在QVTKOpenGLWidget上
ui->qvtkWidget->SetRenderWindow(renderWindow);
ui->qvtkWidget->update();
}
修改后的读取点云的函数,更简洁
void MainWindow::Open_clicked()
{
// 选择.pcd文件
QString filename = QFileDialog::getOpenFileName(this, tr("打开PCD文件"), ".", tr("PCD文件 (*.pcd)"));
if (filename.isEmpty()) {
return;
}
// 从文件读取点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>(filename.toStdString(), *cloud) == -1) {
PCL_ERROR("Could not read .pcd file\n");
return;
}
updatePointCloud(cloud);//调用转化与可视化的函数
pointCloudLoaded = true;
ui->verticalScrollBar->setEnabled(true);
}
将dialog中输入的参数传回到相关函数中
//体素采样
void MainWindow::pressBtn_voxel()//调用新建的qt设计师界面
{
dialog_voxel = new Filter_voxel();
connect(dialog_voxel, &Filter_voxel::sendData, this, &MainWindow::Voxel_clicked);
dialog_voxel->exec();
delete dialog_voxel;
}
void MainWindow::Voxel_clicked(QString data)
{
//将vtk转为pcl,因为要使用pcl库对点云进行处理
vtkPolyData* polydata = vtkPolyData::SafeDownCast(ui->qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActors()->GetLastActor()->GetMapper()->GetInput());
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::vtkPolyDataToPointCloud(polydata, *cloud);
float size = data.toFloat();//这里是获取在设计师界面输入的数值
auto cloud_out = pcl_filter_voxel(cloud, size);//调用下采样的函数对点云进行处理
updatePointCloud(cloud_out);//转到pcl转vtk并可视化的函数
}
如果要添加其他点云处理,过程大同小异。