Qt PCL学习(二):点云读取与保存

注意事项

0. 效果演示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1. pcl_open_save.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

// 添加下行代码(根据自己安装目录进行修改)
include(D:/PCL1.12.1/pcl1.12.1.pri)

2. mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QColorDialog>
#include <QMessageBox>
#include <QFileDialog>
#include <QTime>
#include <QDir>
#include <QFile>
#include <QtMath>
#include <QWindow>
#include <QAction>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QIcon>
#include <QMenuBar>
#include <QMenu>
#include <QToolBar>
#include <QStatusBar>
#include <QFont>
#include <QString>
#include <QTextBrowser>

#include <QVTKOpenGLNativeWidget.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkRenderWindow.h>
#include <vtkAutoInit.h>

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/visualization/pcl_visualizer.h>

typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud<PointT> PointCloudT;
typedef pcl::visualization::PCLVisualizer PCLViewer;
typedef std::shared_ptr<PointCloudT> PointCloudPtr;

VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)

QT_BEGIN_NAMESPACE
namespace Ui {
    class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow {
   
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void open_clicked();
    void save_clicked();

private:
    Ui::MainWindow *ui;

    PointCloudPtr cloudptr;
    PCLViewer::Ptr cloud_viewer;
};
#endif // MAINWINDOW_H

3. mainwindow.cpp

#pragma execution_character_set("utf-8")

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
   
    ui->setupUi(this);
    // 设置窗口标题和 logo
    this->setWindowTitle("CloudOne");
    this->setWindowIcon(QIcon(":/resourse/icon.ico"));

    // 初始化点云数据 cloudptr
    cloudptr.reset(new PointCloudT);

    // 创建菜单栏
    QMenuBar *menu_bar = new QMenuBar(this);
    this->setMenuBar(menu_bar);
    menu_bar->setStyleSheet("font-size : 16px");

    // 1、File 下拉列表
    QMenu *file_menu = new QMenu("File", menu_bar);

    QAction *open_action = new QAction("Open File");
    QAction *save_action = new QAction("Save File");
    QAction *exit_action = new QAction("Exit");
    // 添加动作到文件菜单
    file_menu->addAction(open_action);
    file_menu->addAction(save_action);
    file_menu->addSeparator();  // 添加菜单分隔符将 exit 单独隔离开
    file_menu->addAction(exit_action);
    // 把 File 添加到菜单栏
    menu_bar->addMenu(file_menu);

    // 信号与槽函数链接
    connect(open_action, SIGNAL(triggered()), this, SLOT(open_clicked()));  // 打开文件
    connect(save_action, SIGNAL(triggered()), this, SLOT(save_clicked()));  // 保存文件
    connect(exit_action, SIGNAL(triggered()), this, SLOT(close()));         // 退出
}

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

void MainWindow::open_clicked() {
   
    // this:代表当前对话框的父对象;tr("open file"):作为对话框的标题显示在标题栏中,使用 tr 函数表示这是一个需要翻译的文本
    // "":代表对话框的初始目录,这里为空表示没有指定初始目录
    // tr("pcb files(*.pcd *.ply *.txt) ;;All files (*.*)"):过滤器,决定在对话框中只能选择指定类型的文件
    QString fileName = QFileDialog::getOpenFileName(this, tr("open  file"), "", tr("point cloud files(*.pcd *.ply) ;; All files (*.*)"));

    if (fileName.isEmpty()) {
   
        return;
    }
    if (fileName.endsWith("ply")) {
   
        qDebug() << fileName;
        if (pcl::io::loadPLYFile(fileName.toStdString(), *cloudptr) == -1) {
   
            qDebug() << "Couldn't read .ply file \n";
            return ;
        }
    } else if (fileName.endsWith("pcd")) {
   
        qDebug() << fileName;
        if (pcl::io::loadPCDFile(fileName.toStdString(), *cloudptr) == -1) {
   
            qDebug() << "Couldn't read .pcd file \n";
            return;
        }
    } else {
   
        QMessageBox::warning(this, "Warning", "Wrong format!");
    }

    // 创建 PCLViewer 对象并设置窗口标题
    cloud_viewer.reset(new PCLViewer("Viewer"));
    cloud_viewer->setShowFPS(true);

    // 将 cloud_viewer 的渲染窗口嵌入到 QWidget 中
    auto viewerWinId = QWindow::fromWinId((WId)cloud_viewer->getRenderWindow()->GetGenericWindowId());
    QWidget *widget = QWidget::createWindowContainer(viewerWinId, nullptr);

    // 创建 QVBoxLayout 对象并将 QWidget 添加到其中
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(widget);
    centralWidget()->setLayout(mainLayout);

    // 设置颜色处理器,将点云数据添加到 cloud_viewer 中
    const std::string axis = "z";
    pcl::visualization::PointCloudColorHandlerGenericField<PointT> color_handler(cloudptr, axis);
    cloud_viewer->addPointCloud(cloudptr, color_handler, "cloud");
    cloud_viewer->addPointCloud(cloudptr, "cloud");
}

void MainWindow::save_clicked() {
   
    int return_status;
    QString filename = QFileDialog::getSaveFileName(this, tr("Open point cloud"), "", tr("Point cloud data (*.pcd *.ply)"));

    if (cloudptr->empty()) {
   
        return;
    } else {
   
        if (filename.isEmpty()) {
   
            return;
        }
        if (filename.endsWith(".pcd", Qt::CaseInsensitive)) {
   
            return_status = pcl::io::savePCDFileBinary(filename.toStdString(), *cloudptr);
        } else if (filename.endsWith(".ply", Qt::CaseInsensitive)) {
   
            return_status = pcl::io::savePLYFileBinary(filename.toStdString(), *cloudptr);
        } else {
   
            filename.append(".ply");
            return_status = pcl::io::savePLYFileBinary(filename.toStdString(), *cloudptr);
        }
        if (return_status != 0) {
   
            PCL_ERROR("Error writing point cloud %s\n", filename.toStdString().c_str());
            return;
        }
    }
}

相关推荐

  1. Python中的文件读取保存

    2024-02-09 17:10:03       15 阅读
  2. ubuntu 编译使用 liblas 读取

    2024-02-09 17:10:03       39 阅读
  3. Python对csv格式文件的保存读取

    2024-02-09 17:10:03       12 阅读
  4. python&Pandas:数据读取写入

    2024-02-09 17:10:03       38 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-09 17:10:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-09 17:10:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-09 17:10:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-09 17:10:03       18 阅读

热门阅读

  1. 假期day4,链表增加与删除(2024/2/5)

    2024-02-09 17:10:03       24 阅读
  2. Kylin下Qt找不到打印机解决方案

    2024-02-09 17:10:03       23 阅读
  3. C++ 设计模式之观察者模式

    2024-02-09 17:10:03       28 阅读
  4. 浅谈欧拉函数

    2024-02-09 17:10:03       27 阅读