0. 前言
- 上一篇博客中介绍了基于 librviz 多线程可视化点云(进阶)
- 有时我们保存了单帧或者多帧点云后会调用 PCL 点云库进行一些处理,这篇博客介绍了如何在 QT 中使用 VTK 可视化点云。
- 效果图如下,直接上 Github 链接:ros2_qt_template
1. 无新的系统环境
- PCL-1.13.1,VTK-7.1。
- 在通过源码编译安装 PCL 的同时,已经自动安装了 VTK,所以这里无需额外编译安装!
- 这里我的 QT 设计界面如下,可以看到我的组件列表这里没有其他博客提到的 QVTKWidget,因为我是从 PCL 官方教程的 ui 文件复制来的,直接可以使用!
2. 源码解读
-
CMakeLists.txt 需要导入 OpenGL、VTK、PCL,在上一个教程的基础上添加如下:
find_package(Qt5 COMPONENTS OpenGL Widgets REQUIRED) find_package(VTK 7.1 REQUIRED) # Import PCL find_package(PCL 1.13.1 REQUIRED) if(PCL_FOUND) message( STATUS "PCL_FOUND: " ${PCL_FOUND}) message( STATUS "PCL_INCLUDE_DIRS: " ${PCL_INCLUDE_DIRS}) message( STATUS "PCL_LIBRARY_DIRS: " ${PCL_LIBRARY_DIRS}) include_directories(${PCL_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS}) else() message(err: PCL not found) endif() ament_target_dependencies( ${PROJECT_NAME} rclcpp rviz_common rviz_default_plugins rviz_rendering Boost VTK PCL) # 添加依赖的 ROS2 库 target_link_libraries(${PROJECT_NAME} Qt5::Widgets ${VTK_LIBRARIES} ${PCL_LIBRARIES} )
- 实现了
PCLView
这个类,包含头文件QVTKWidget.h
,它继承自QVTKWidget
,再怎么继承,祖辈还是QWidget
,这样我们就可以用到很多爷爷类的特性了,类的声明如下:
#ifndef PCLView_H
#define PCLView_H
#include <QWidget>
#include <QVTKWidget.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
class PCLView : public QVTKWidget
{
Q_OBJECT
public:
PCLView(QWidget *parent = nullptr);
void refreshView(); // 刷新显示
pcl::visualization::PCLVisualizer::Ptr _viewer; // 显示窗口
protected:
private:
pcl::PointCloud<pcl::PointXYZ>::Ptr _cloud; // 点云变量
};
#endif // PCLView_H
- 初始化函数的逻辑也很清晰:
- 初始化显示窗口
- 生成/读取点云
- 显示点云
- 设置窗口
- 刷新窗口
#include "pclView.h"
PCLView::PCLView(QWidget *parent)
: QVTKWidget(parent)
{
// 初始化显示窗口
_viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
_viewer->setBackgroundColor(0, 0, 0);
// _viewer->addCoordinateSystem(1.0);
_viewer->initCameraParameters();
_viewer->setCameraPosition(0, 0, 0, 0, -1, 0);
// 读取点云文件
_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
_cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
_cloud->resize (200);
// Fill the cloud with some points
for (auto& point: *_cloud)
{
point.x = 1024 * rand () / (RAND_MAX + 1.0f);
point.y = 1024 * rand () / (RAND_MAX + 1.0f);
point.z = 1024 * rand () / (RAND_MAX + 1.0f);
}
// 显示点云
_viewer->addPointCloud<pcl::PointXYZ>(_cloud, "cloud");
_viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud");
this->SetRenderWindow(_viewer->getRenderWindow());
_viewer->setupInteractor(this->GetInteractor(), this->GetRenderWindow());
refreshView();
}
void PCLView::refreshView()
{
#if VTK_MAJOR_VERSION > 8
this->renderWindow()->Render();
#else
this->update();
#endif
}
-
为了让 rviz 和 vtk 窗口并排显示,我在
mainwindow.cpp
中进行了一些布局,并排显示的模块都可以参考下面这个布局,百试不爽:lidarView = new LidarView(); QVBoxLayout * lidar_layout = new QVBoxLayout; lidar_layout->setSpacing(0); lidar_layout->setMargin(0); lidar_layout->addWidget(lidarView->_render_panel.get()); ui->wdgtLidarView->setLayout(lidar_layout); pclView = new PCLView(); QVBoxLayout * pcl_layout = new QVBoxLayout; pcl_layout->setSpacing(0); pcl_layout->setMargin(0); pcl_layout->addWidget(pclView); ui->qvtkWidget->setLayout(pcl_layout);
- 在最终实现的 VTK 窗口继承了 PCL 显示窗口相同的功能,一些快捷键如下:
快捷键 | 功能 |
---|---|
左键拖动 | 旋转视角 |
右键拖动 | 平移视角 |
滚轮滚动 | 缩放视图 |
+ | 放大 |
- | 缩小点的大小 |
Shift + + | 增大点的大小 |
鼠标位置 + f | 放大鼠标位置 |
o | 切换放大缩小到上次滚轮缩放的大小 |
g | 显示坐标轴 |
r | 重置摄像机视角到默认位置 |
评论(2)
您还未登录,请登录后发表或查看评论