
【Qt】基于VTK9.1+VS2019+Qt5.15.2的点云可视化程序开发
由于工作需要和个人爱好,我最近在学习VS+Qt的界面开发和PCL点云库的使用。于是一时兴起准备做一个类似ROS里面自带的Rviz插件的Windows版本。折腾了两天,查阅了很多大佬的博客,但发现信息较为分散还有一些小坑,所以接下来就按照最新的、较为合理的方式来写一个点云可视化的demo。因为我也才接触Qt开发大约一周时间,所以以上内容难免有所错漏,希望评论区的大佬不吝赐教~
目录
3. Qt 5.15.2安装 & Qt-VS插件安装 & VTK 9.1.0编译安装
0. 写在前面
由于工作需要和个人爱好,我最近在学习VS+Qt的界面开发和PCL点云库的使用。于是一时兴起准备做一个类似ROS里面自带的Rviz插件的Windows版本。折腾了两天,查阅了很多大佬的博客,但发现信息较为分散还有一些小坑,所以接下来就按照最新的、较为合理的方式来写一个点云可视化的demo。
1. 开发环境
- Windows 11
- VS 2019
- Qt 5.15.2
- PCL 1.12.1(慎用,建议使用1.13.1及更高版本)
- VTK 9.1.0
2. VS 2019 + PCL 1.12.1 配置
参考@wuchuhang的博客:VS2019+pcl1.12.1配置详解 即可。
注意这里VC++目录和链接器的配置方法,后面有一个VTK的坑需要修改配置。
3. Qt 5.15.2安装 & Qt-VS插件安装 & VTK 9.1.0编译安装
参考@Robot_Yue的博客: Qt PCL学习(一):环境搭建 即可。
这里提供另一种VTK编译安装方法:VTK9.1.0在Windows10+VS2019+Qt 5.15.2环境下编译安装
如果使用PCL-AllInOne方式安装的3rd Party库,VTK中会缺少对Qt的支持库,产生如下报错:
error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl QVTKOpenGLNativeWidget::QVTKOpenGLNativeWidget
查看PCL官方库的Issues中也有类似的问题:LNK2019 unresolved external symbol
按照上面的方法重新编译VTK后,将对应的Debug和Release的头文件和库添加到VC++目录和链接器的配置中。
4. 点云显示demo
所以按照我上面的流程走一遍会发现还有个问题,就是怎么在Qt中添加VTK的Widget。这里就要用到QVTKOpenGLNativeWidget(也不知道谁起的这么魔鬼的名字,至于为什么叫这个名字,大家可以参考@Beyond欣的博客:QVTKWidget、QVTKOpenGLWidget、QVTKOpenGLNativeWidget、QVTKWidget2 区别
而具体的操作方法可以参考@houjinghao的博客:Qt中添加VTK窗口并显示点云
下面是鄙人随便写的一个小Demo。
4.1 UI
写一个非常简单的UI:CSDN NB!
4.2 头文件
#pragma once
#include <QMainWindow>
#include <QDebug>
#include "ui_pcl_test.h"
// 3rd Party Headers
#include <vtkGenericOpenGLRenderWindow.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
typedef pcl::PointXYZI PointT;
typedef pcl::PointCloud<PointT> PointCloudT;
typedef pcl::visualization::PCLVisualizer PCLViewer;
typedef std::shared_ptr<PointCloudT> PointCloudPtr;
class PCL_test : public QMainWindow
{
Q_OBJECT
public:
PCL_test(QWidget *parent = nullptr);
~PCL_test();
private:
Ui::PCL_testClass ui;
// PCL members
PointCloudPtr cloudptr;
PCLViewer::Ptr cloud_viewer;
void loadPCD();
};
4.3 主程序
因为在我这是一个子窗口,自己把代码塞到main函数里就行了。(我懒得改
#include "pcl_test.h"
PCL_test::PCL_test(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
auto renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
renderWindow->AddRenderer(renderer);
cloud_viewer.reset(new pcl::visualization::PCLVisualizer(renderer, renderWindow, "3D viewer", false));
ui.qvtkwidget_cloudviewer->setRenderWindow(cloud_viewer->getRenderWindow());
cloud_viewer->setupInteractor(ui.qvtkwidget_cloudviewer->interactor(), ui.qvtkwidget_cloudviewer->renderWindow());
loadPCD();
}
void PCL_test::loadPCD()
{
// Load point cloud from pcd
this->cloudptr.reset(new PointCloudT);
if (pcl::io::loadPCDFile("E:/Dataset/weilai/pcd_selected/3644.500049090.pcd", *this->cloudptr) == -1)
std::cout << "Open pcd failed!" << std::endl;
// Color PointCloud according to the field
pcl::visualization::PointCloudColorHandlerGenericField<PointT> color_handler(this->cloudptr, "intensity");
cloud_viewer->addPointCloud(this->cloudptr, color_handler);
cloud_viewer->spin();
}
PCL_test::~PCL_test()
{}
4.4 显示效果
目前还在图一乐阶段:
5. 写在最后
因为我也才接触Qt开发大约一周时间,所以以上内容难免有所错漏,希望评论区的大佬不吝赐教~
更多推荐
所有评论(0)