欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PCL+ VTK+QT ubuntu16.04配置 实现可视化点云

程序员文章站 2024-01-23 12:17:04
...

**

前言

因为项目需要,需要实现QT中实现点云显示,刚开始接触QT,有很多坑要躺,在坑了呆了4天,终于配置好了PCL1.8 + VTK6.3 + QT5.5 + ubuntu16.04!
网上参考的资料挺多,但都差不多,大部分都是基于windows下的开发,linux系统下的资料较少,刚从坑里出来,想记录下来,以免以后再用。
最初参考两篇博文

https://blog.csdn.net/wokaowokaowokao12345/article/details/51314439
https://blog.csdn.net/zyj8691/article/details/79162101

这两篇都是基于windows环境下的。

**

过程

感觉在坑里特别惨,是因为我之前在电脑里装了ROS,ROS是依赖VTK6.2 、 pcl1.7 、 qt5.5,在装qtcreator-ros-plugin时系统又装上了qt5.9,再加上系统原装的qt4,系统里有3个版本的qt,再加上一开始接触QT,对这些库的依赖并没有什么概念。
其实最核心的还是,VTK和PCL和QtCreator都要基于同一个qt。
安装的顺序时QT-VTK->PCL 因为 VTK依赖QT ,PCL依赖VTK和QT。

QT安装

QT的话应该安装qt5.5版本的,因为qt5.6版本以后,qt将QWebKit模块改成了QWebEngine,在VTK库和PCL库编译的时候都要用到这个模块。所以选择qt5.5安装并配置环境变量。
QT安装步骤和环境变量的配置就不赘述了,网上有很多。
想要在qt中实现可视化点云,就需要QVTKWigdet控件,这个控件是由vtk库编译而来的。网上还有一种方法是直接用代码的形式来解决的,起初尝试过,但失败了就没有再试。接下来就说VTK库的安装。

VTK库的安装

VTK采用源码安装,我用的是vtk6.3,VTK7.1应该也可以(没尝试过,但网上有很多ok的),VTK8.2尝试过(但好像VTK8.2太新了,PCL库报错,也有可能当时用的pcl并不是基于vtk8.2的)。
下载源码后,cd到VTK-6.3.0文件夹后,建立build文件夹。接下来配置cmake,我使用cmake-gui ,
1.选VTK_Group_Qt选项
2.将CMAKE_BUILD_TYPE改为Release
3.VTK_QT_VERSION改为5
按一下Configure按钮后,上面有关QT的路径应该都是上面QT5.5的安装路径。
PCL+ VTK+QT ubuntu16.04配置 实现可视化点云
配置好后,make 编译,VTK编译速度还可以,等一会就可以了
编译好后,sudo make install将库安装。
此时vtk的头文件应该都在/usr/local/include/vtk-6.3
库文件都在/usr/local/lib中。

编译VTK的库最主要的原因还是需要libQVTKWidgetPlugin.so库文件,路径为/home/username/VTK-6.3.0/build/lib。讲这个文件复制到(qt安装路径)/Tools/QtCreator/bin/plugins/designer(需要用sudo cp 命令来复制)
此时打开QT的UI界面,便会出现QVTK的控件。
PCL+ VTK+QT ubuntu16.04配置 实现可视化点云

PCL库的安装

PCL库也需要源码安装,下载pcl库的源码。同样的方法,建build文件夹,同样用cmake-gui配置cmake,检查VTK_DIR是不是安装的vtk库的路径,qt的版本等。
配置好后编译,PCL库编译需要挺长时间的。
同样,PCL的头文件应该都在/usr/local/include/pcl-1.8
库文件都在/usr/local/lib中。

QT工程依赖配置

新建qt工程,在.pro文件中配置依赖
PCL+ VTK+QT ubuntu16.04配置 实现可视化点云
源码如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtWidgets/QMainWindow>
#include <vtkAutoInit.h>
#include <boost/shared_ptr.hpp>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
VTK_MODULE_INIT(vtkRenderingOpenGL); //这个必须要加,不然会报错
VTK_MODULE_INIT(vtkInteractionStyle);

typedef pcl::PointXYZ VPoint;
typedef pcl::PointCloud<VPoint> VPointCloud;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    //point cloud data
    VPointCloud::Ptr cloud;
    pcl::visualization::PCLVisualizer::Ptr viewer;
    //init VTK widget
    void initialvtkWidget();
private slots:

    void onOpen();

};

#endif // MAINWINDOW_H


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <vtkRenderWindow.h>
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initialvtkWidget();
    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(onOpen()));
}

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


void MainWindow::initialvtkWidget()
{
    cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
    viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
    viewer->addPointCloud(cloud, "cloud");

    ui->CloudViewer->SetRenderWindow(viewer->getRenderWindow());
    viewer->setupInteractor(ui->CloudViewer->GetInteractor(),ui->CloudViewer->GetRenderWindow());
    ui->CloudViewer->update();

}



void MainWindow::onOpen()
{
    //open PCD file
    QString fileName = QFileDialog::getOpenFileName();
    if (!fileName.isEmpty())
    {
        std::string file_name = fileName.toStdString();
        //sensor_msgs::PointCloud2 cloud2;
        pcl::PCLPointCloud2 cloud2;
        //pcl::PointCloud<Eigen::MatrixXf> cloud2;
        Eigen::Vector4f origin;
        Eigen::Quaternionf orientation;
        int pcd_version;
        int data_type;
        unsigned int data_idx;
        pcl::PCDReader rd;
        rd.readHeader(file_name, cloud2, origin, orientation, pcd_version, data_type, data_idx);

        if (data_type == 0)
        {
            pcl::io::loadPCDFile(fileName.toStdString(), *cloud);
        }
        else if (data_type == 2)
        {
            pcl::PCDReader reader;
            reader.read<pcl::PointXYZ>(fileName.toStdString(), *cloud);
        }
        viewer->updatePointCloud(cloud, "cloud");
        viewer->resetCamera();
        ui->CloudViewer->update();
    }

}

效果图

PCL+ VTK+QT ubuntu16.04配置 实现可视化点云

END

这只是一个简单的demo,程序都是按照网上来的,最重要的问题解决了,接下来可以愉快的往下写了。哈哈哈哈哈。

如果PCL库、VTK库和qtcreator不是基于同一个qt的话,编译应该是没问题,但就是运行不起来,会出现很多稀奇古怪的问题。

参考了很多博文,跟这个相关的基本都看过,也不一一列了。希望对大家有用!