Ubuntu下使用QT Creator 窗口显示点云和图片
参考文章
首先非常感谢这两篇文章[1][2]的帮助,我成功实现使用pcl库显示点云。
这里主要记录自己的学习过程。这里默认pcl已经安装好可以使用。
安装QT
使用官方的安装包
下载.run的安装包(qt-opensource-linux-x64-5.12.9.run)(注意自己看版本)
在run文件下打开终端
sudo chmod a+x qt-opensource-linux-x64-5.12.9.run
./qt-opensource-linux-x64-5.12.9.run
然后记录好自己的安装路径例如:/opt/Qt5.12.9/
”后面的代码统一使用这个路径请根据自己的情况更改。
安装VTK
不同的PCL版本对应相应的VTK库的版本,这里编译VTK的目的是PCL的可视化是基于VTK的,而在Qt中可视化点云,也需要VTK库的插件QVTKWidget。
在VTK的官网上下载对应的版本。官网不好进,我这里也有下载好的。
链接:https://pan.baidu.com/s/132m4Xpg5SXdni9DvN6UntQ
提取码:0000
我用的PCL 1.10下载的是VTK7.1.1
将压缩包解压,进入文件夹VTK-7.1.1
mkdir release
cd release
cmake -DVTK_QT_VERSION:STRING=5 \
-DQT_QMAKE_EXECUTABLE:PATH=/opt/Qt5.12.9/5.12.9/gcc_64/bin/qmake \
-DVTK_Group_Qt:BOOL=ON \
-DCMAKE_PREFIX_PATH:PATH=/opt/Qt5.12.9/5.12.9/gcc_64/lib/cmake \
-DCMAKE_BUILD_TYPE=RELEASE \
-DBUILD_SHARED_LIBS:BOOL=ON ..
make
sudo make install
注意代码中/opt/Qt5.12.9/5.12.9/gcc_64/bin/qmake
和/opt/Qt5.12.9/5.12.9/gcc_64/lib/cmake
改为自己的安装目录
代码中的 make
可以添加添加参数使用多核编译如make -j12
12代表使用12个核心。
将QVTKWidget添加到QtCreator
sudo find / -name libQVTKWidgetPlugin.so
一般会出现两处,一处是自己编译VTK的地方,另外一处在/usr/local/plugins/designer/
。
进入第二处,复制libQVTKWidgetPlugin.so到以下三个地方
/opt/Qt5.12.9/5.12.9/gcc_64/plugins/designer/
/opt/Qt5.12.9/Tools/QtCreator/lib/Qt/plugins/designer/
/usr/lib/x86_64-linux-gnu/qt5/plugins/designer/
可以使用如下命令复制到这三个地方
cd /usr/local/plugins/designer
sudo cp libQVTKWidgetPlugin.so /opt/Qt5.12.9/5.12.9/gcc_64/plugins/designer/
sudo cp libQVTKWidgetPlugin.so /opt/Qt5.12.9/Tools/QtCreator/lib/Qt/plugins/designer/
sudo cp libQVTKWidgetPlugin.so /usr/lib/x86_64-linux-gnu/qt5/plugins/designer/
此时可以进QtCreator中看控件,发现出现下图这个,表明安装成功
使用QVTKWidget显示点云
首先创建一个项目在设计界面拖拽一个到窗口中,如下图所示:
并设置窗口名称为了后面代码使用,保持一致。
然后我们可以添加一个按钮,实现点击按钮显示点云的功能
配置.pro或CMakeLists.txt文件
我的.pro文件配置如下
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test_QT_GUI2
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += c++14
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
INCLUDEPATH += /usr/local/include \
/usr/local/include/opencv \
/usr/local/include/opencv4
LIBS += /usr/local/lib/libopencv_highgui.so \
/usr/local/lib/libopencv_core.so \
/usr/local/lib/libopencv_imgproc.so \
/usr/local/lib/libopencv_imgcodecs.so
INCLUDEPATH += /usr/include/eigen3
INCLUDEPATH += /usr/local/include/vtk-7.1
LIBS += /usr/lib/x86_64-linux-gnu/libvtk*.so
INCLUDEPATH += /usr/include/boost
LIBS += /usr/lib/x86_64-linux-gnu/libboost_*.so
INCLUDEPATH += /usr/include/pcl-1.10
LIBS += /usr/lib/x86_64-linux-gnu/libpcl_*.so
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
其中这段代码需要确认文件路径和版本是否一致
INCLUDEPATH += /usr/local/include \
/usr/local/include/opencv \
/usr/local/include/opencv4
LIBS += /usr/local/lib/libopencv_highgui.so \
/usr/local/lib/libopencv_core.so \
/usr/local/lib/libopencv_imgproc.so \
/usr/local/lib/libopencv_imgcodecs.so
INCLUDEPATH += /usr/include/eigen3
INCLUDEPATH += /usr/local/include/vtk-7.1
LIBS += /usr/lib/x86_64-linux-gnu/libvtk*.so
INCLUDEPATH += /usr/include/boost
LIBS += /usr/lib/x86_64-linux-gnu/libboost_*.so
INCLUDEPATH += /usr/include/pcl-1.10
LIBS += /usr/lib/x86_64-linux-gnu/libpcl_*.so
cmake的我一直没有配好,但你可以用chatgpt将这段qmake代码转为cmake(实测没问题)。
实现代码
mainwindow.h中代码如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vtkRenderWindow.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void slot1();
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
pcl::visualization::PCLVisualizer::Ptr view;
};
#endif // MAINWINDOW_H
mainwindow.cpp中代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
#include "vtkConeSource.h"
#include "vtkConeSource.h"
#include "vtkCommand.h"
#include "vtkCamera.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkTransform.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include <vtkSmartPointer.h>
#include <vtkDoubleArray.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkDataSet.h>
#include <vtkLookupTable.h>
#include <vtkPointData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkArcSource.h>
#include <vtkAppendPolyData.h>
#include <vtkScalarBarActor.h>
#include <vtkKdTree.h>
#include <vtkLODActor.h>
#include <vtkMath.h>
#include <vtkWindowToImageFilter.h>
#include <vtkBMPWriter.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>//pcd 读写类相关的头文件。
#include <pcl/PCLPointCloud2.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <QMessageBox>
#include <QFileDialog> //头文件
using namespace pcl;
using namespace cv;
using namespace pcl::io;
using namespace std;
using pcl::visualization::PointCloudColorHandlerGenericField;
using pcl::visualization::PointCloudColorHandlerCustom;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
view.reset(new pcl::visualization::PCLVisualizer("3d view",false));
ui->guiwidget->SetRenderWindow(view->getRenderWindow());
view->setupInteractor(ui->guiwidget->GetInteractor(),ui->guiwidget->GetRenderWindow());
ui->guiwidget->update();
}
void MainWindow::slot1()
{
// ui->textEdit->setText("hello world!");
// Mat img = imread("/home/icecreamshao/108.bmp");
// imshow("image", img);
// waitKey(0);
// Mat temp;
// cvtColor(img, temp, CV_BGR2RGB);
// QImage Qtemp = QImage((const unsigned char*)(temp.data), temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
// ui->label->setPixmap(QPixmap::fromImage(Qtemp));
// ui->label->resize(Qtemp.size());
// ui->label->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
// show pointcloud
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
pcl::io::loadPCDFile("/home/giraffe/PCL/dataset/B3R/6-model/bunny.pcd",*cloud);
view->addPointCloud(cloud,"cloud");
ui->guiwidget->update();
//这段代码可用于显示图片
// QImage* img=new QImage;
// img->load("/home/giraffe/图片/1.png");
// ui->labimgshow->setPixmap(QPixmap::fromImage(*img));
// // 将 setScaledContents 设置为 true,以使图像自适应 QLabel 的大小
// ui->labimgshow->setScaledContents(true);
}
实现效果
然后自己设置点云和图片的路径就ok了。
最后效果:点击按钮加载点云和图片,如下所示:
左边的图片需要自己在ui界面添Llable用于显示,代码被注释了。
完整代码获取
链接:https://pan.baidu.com/s/1SDhdTPdOykR7xJ0PpMs1mA
提取码:0000
如果有任何问题可以私信我,最后如果这篇文章帮助到了你,请不要吝啬你的点赞!!!