qt+vtk+pcl实现点云体素下采样

目录

添加对话框控件

 布局ui

mainwindow.h添加头文件 

 filter_voxel.h设置

filter_voxel.cpp设置

 pcl_function.h添加相关头文件,声明下采样函数

pcl转vtk并可视化代码

 将dialog中输入的参数传回到相关函数中


 

添加对话框控件

 

 

 布局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并可视化的函数



}

 

 如果要添加其他点云处理,过程大同小异。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值