第一篇里面我们通过串口连接得到雷达数据并且解析成pcd文件,并且保存了坐标点;还差最后一步显示在QVTKWidget中实时刷新,这次把它补上;
Qt+pcl+vtk环境搭建:
在我看来是最复杂的编译环境部署了,光是勉强装上就花掉了我近一周的时间,基本什么坑都踩过了,但是还是有很多问题,这里就不一一赘述了,大家可以按照这位前辈的博客,基本上是我看过最详细的;
【PCL】基于C++与QT的PCL环境配置(保姆级教程)_qt pcl_Cheng先生啊的博客-CSDN博客
添加QVTKWidget组件:
搭建好之后需要添加DLL与Lib至QT:
找到下面两个文件:
C:\PCL1.8.1\3rdParty\VTK\plugins\designer\QVTKWidgetPlugin.dll
C:\PCL1.8.1\3rdParty\vtk-v8.0.0\build\lib\Release\QVTKWidgetPlugin.lib
(注意辨别,这是我的PCL安装路径)
粘贴至:
C:\Qt\Qt5.12.12\5.12.12\msvc2015_64\plugins\designer与
C:\Qt\Qt5.12.12\Tools\QtCreator\bin\plugins\designer路径下
(注意辨别,这是我的QT安装路径)
粘贴过去之后在UI界面能够看到这个组件,可以选择直接拖拽到UI界面当中;(不清楚是什么原因我在粘贴过去之后,在QtCreat中没有看到这个组件),所以我是用代码创建的:
代码如下:
首先包含需要用到的头文件
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h> //pcd 读写类相关的头文件。
#include <pcl/point_types.h> //PCL中支持的点类型头文件。
#include "QVTKWidget.h"
#include "vtkRenderWindow.h"
随后创建QVTKwidget对象,并初始化:
QVTKWidget *qvtkwidget; //头文件声明
//初始化
qvtkwidget = new QVTKWidget(this);
qvtkwidget->setFixedSize(521,311);
qvtkwidget->move(10,43);
点云显示函数:
void PointCloudShow(); //显示点云,头文件声明
//VTK组件中显示点云
void MainWindow::PointCloudShow()
{
cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
viewer->initCameraParameters();
viewer->createViewPortCamera(0);//设置相机视角
viewer->setCameraPosition(0,0,-15,0,0,0,1,0,0,0);//初始视角
qvtkwidget->SetRenderWindow(viewer->getRenderWindow());
viewer->setupInteractor(qvtkwidget->GetInteractor(), qvtkwidget->GetRenderWindow());
qvtkwidget->update();
}
到这一步还会有一个报错:
Generic Warning: In E:\vtk 8.0.0\vtk-v8.0.0\Rendering\Core\vtkPolyDataMapper.cxx, line 28
Error: no override found for 'vtkPolyDataMapper'.
Warning: In E:\vtk 8.0.0\vtk-v8.0.0\Rendering\Core\vtkInteractorStyleSwitchBase.cxx, line 43
vtkInteractorStyleSwitchBase (00000162F784D580): Warning: Link to vtkInteractionStyle for default style selection.
Generic Warning: In E:\vtk 8.0.0\vtk-v8.0.0\Rendering\Core\vtkPolyDataMapper.cxx, line 28
Error: no override found for 'vtkPolyDataMapper'.
这是由于QVTKWidget没有初始化,还需要在头文件添加这四行代码:
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
到这里还未添加点云,所以显示效果如下:
至此添加了QVTKWidget组件至UI界面;
QVTKWidget组件点云实时刷新:
显示组件跟显示文件已经准备好,现在只需要把它们连接起来就大功告成了;
在这可以使用qt特有的信号与槽机制,雷达读取的数据刷新就发送信号,监听这个信号来刷新数据即可;
信号,槽函数:
private slots:
void sloUpdataPCL(); //点云刷新槽函数,头文件声明
signals:
void emitSignals(); //信号,只需要声明
//点云刷新槽函数
void MainWindow::sloUpdataPCL()
{
viewer->removeAllPointClouds(0);//清空点云数据
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 0, 255, 0); //设置点云颜色
std::string filepath ="learn_1.pcd"; //文件路径
pcl::io::loadPCDFile(filepath, *cloud); //加载点云文件
viewer->addPointCloud(cloud , cloud_color , "cloud"); //添加点云
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud"); //设置点云大小
qvtkwidget->update();
}
发送信号的位置放在保存雷达串口解析数据的位置,保存成功就发送信号:
if(-1 == pcl::io::savePCDFile("learn_1.pcd", *cloud, binary_mode)){
std::cout<<"save pcd file failed."<<std::endl;
}else{
emitSignals();//刷新vtk信号
}
信号与槽连接:
connect(this,&MainWindow::emitSignals,this,&MainWindow::sloUpdataPCL);//连接信号,实时刷新数据;
到这串口读取单线激光雷达数据并在QVtkWidget组件中实时刷新全部实现,效果图就不放了,有问题或建议欢迎提出,大家一起学习讨论;