<PCL Doc 解析> PCL+QT案例

创建 PCL + Qt 项目,我们将使用 Cmake 而不是 Qmake。
我们要编写的程序是一个简单的 PCL 可视化器,它允许更改随机生成的点云颜色。
Github代码地址
组织方式

.
├── build
└── src
    ├── CMakeLists.txt
    ├── main.cpp
    ├── pclviewer.cpp
    ├── pclviewer.h
    ├── pclviewer.ui
    └── pcl_visualizer.pro

构建的第一步是使用参数调用cmake(从build文件夹中)…/src;这将在文件夹中创建所有文件, build而不修改文件夹中的任何内容src;从而保持清洁。

用户界面 (UI)

将 Qt 用于您的项目的目的是您可以轻松构建跨平台 UI。UI 保存在.ui文件中您可以使用gedit或 Qt Creator 打开它,在此示例中,UI 非常简单,它包括:

  • QMainWindow , QWidget:应用程序的窗口(框架)
  • qvtkWidget:包含 PCLVisualizer 的 VTK 小部件
  • QLabel : 在用户界面上显示文本
  • QSlider:用于选择值的滑块(此处为整数值)
  • QLCDNumber : 数字显示,8 段样式

code parse:

main.cpp

#include "pclviewer.h"
#include <QApplication>
#include <QMainWindow>

int main (int argc, char *argv[])
{
  QApplication a (argc, argv);
  PCLViewer w;
  w.show ();

  return a.exec ();
}

这里我们包括类 PCLViewer 的头文件和 QApplication 和 QMainWindow 的头文件。
然后主要功能包括实例化一个 QApplication a来管理 GUI 应用程序的控制流和主要设置。
实例化一个名为wPCLViewer的对象并调用它的方法。show()
最后,我们通过 QApplication a返回程序退出的状态。

pclviewer.h

#pragma once

#include <iostream>

// Qt
#include <QMainWindow>

// Point Cloud Library
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>

// Visualization Toolkit (VTK)
#include <vtkRenderWindow.h>

typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud<PointT> PointCloudT;

这个文件是类 PCLViewer 的头文件;我们包括QMainWindow因为这个类包含 UI 元素,所以我们包括我们将使用的 PCL 头文件和qvtkWidget. 我们还定义了点类型和点云的 typedef,这提高了可读性。

namespace Ui
{
  class PCLViewer;
}

我们在其中声明命名空间Ui和类 PCLViewer。

class PCLViewer : public QMainWindow
{
  Q_OBJECT

这是 PCLViewer 类的定义;宏Q_OBJECT告诉编译器这个对象包含 UI 元素;这意味着该文件将通过Meta-Object Compiler (moc)进行处理。

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

PCLViewer 类的构造函数和析构函数。

public Q_SLOTS:
  void
  randomButtonPressed ();

  void
  RGBsliderReleased ();

  void
  pSliderValueChanged (int value);

  void
  redSliderValueChanged (int value);

  void
  greenSliderValueChanged (int value);

  void
  blueSliderValueChanged (int value);

这些是公共时段;这些功能将与 UI 元素操作相关联。

protected:
  pcl::visualization::PCLVisualizer::Ptr viewer;
  PointCloudT::Ptr cloud;

  unsigned int red;
  unsigned int green;
  unsigned int blue;

此处定义了指向 PCLVisualier 的 boost 共享指针和指向点云的指针。
整数red, green,blue将帮助我们存储滑块的值。

完整的.h代码

#pragma once

#include <iostream>

// Qt
#include <QMainWindow>

// Point Cloud Library
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>

typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud<PointT> PointCloudT;

namespace Ui
{
  class PCLViewer;
}

class PCLViewer : public QMainWindow
{
  Q_OBJECT

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

public Q_SLOTS:
  void
  randomButtonPressed ();

  void
  RGBsliderReleased ();

  void
  pSliderValueChanged (int value);

  void
  redSliderValueChanged (int value);

  void
  greenSliderValueChanged (int value);

  void
  blueSliderValueChanged (int value);

protected:
  void
  refreshView();

  pcl::visualization::PCLVisualizer::Ptr viewer;
  PointCloudT::Ptr cloud;

  unsigned int red;
  unsigned int green;
  unsigned int blue;

private:
  Ui::PCLViewer *ui;
};

下面分析 pclviewer.cpp

part1

#include "pclviewer.h"
#include "ui_pclviewer.h"

PCLViewer::PCLViewer (QWidget *parent) :
  QMainWindow (parent),
  ui (new Ui::PCLViewer)
{
  ui->setupUi (this);
  this->setWindowTitle ("PCL viewer");

  // Setup the cloud pointer
  cloud.reset (new PointCloudT);
  // The number of points in the cloud
  cloud->points.resize (200);

我们包括类头和 UI 对象的头;请注意,此文件由 moc 生成,其路径取决于您调用 cmake 的位置!

之后是构造函数实现;我们设置 ui 和窗口标题名称。| 然后我们在一个新分配的点云指针处初始化类的云指针成员。| 云的大小已调整为能够容纳 200 个点。

// The default color
  red   = 128;
  green = 128;
  blue  = 128;

  // 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);

    point.r = red;
    point.g = green;
    point.b = blue;
  }

red green,blue受保护的成员被初始化为其默认值。
Point Cloud充满了随机点(在一个立方体中),并相应地赋予red greenblue值对应结果颜色。

// Set up the QVTK window
  viewer.reset (new pcl::visualization::PCLVisualizer ("viewer", false));
  ui->qvtkWidget->SetRenderWindow (viewer->getRenderWindow ());
  viewer->setupInteractor (ui->qvtkWidget->GetInteractor (), ui->qvtkWidget->GetRenderWindow ());
  ui->qvtkWidget->update ();

在这里,我们创建了一个 PCL Visualizer 名称viewer,并且我们还指定我们不希望创建交互器。
我们不希望创建一个交互器,因为我们qvtkWidget已经是一个交互器并且它是我们想要使用的交互器。
所以下一步是配置我们新创建的 PCL Visualiser 交互器以使用qvtkWidget.
每次修改 PCL 可视化工具时都应该调用的update()方法;qvtkWidget如果您不调用它,您不知道在用户尝试平移/旋转/缩放之前是否会更新可视化工具。

// Connect "random" button and the function
  connect (ui->pushButton_random,  SIGNAL (clicked ()), this, SLOT (randomButtonPressed ()));

  // Connect R,G,B sliders and their functions
  connect (ui->horizontalSlider_R, SIGNAL (valueChanged (int)), this, SLOT (redSliderValueChanged (int)));
  connect (ui->horizontalSlider_G, SIGNAL (valueChanged (int)), this, SLOT (greenSliderValueChanged (int)));
  connect (ui->horizontalSlider_B, SIGNAL (valueChanged (int)), this, SLOT (blueSliderValueChanged (int)));
  connect (ui->horizontalSlider_R, SIGNAL (sliderReleased ()), this, SLOT (RGBsliderReleased ()));
  connect (ui->horizontalSlider_G, SIGNAL (sliderReleased ()), this, SLOT (RGBsliderReleased ()));
  connect (ui->horizontalSlider_B, SIGNAL (sliderReleased ()), this, SLOT (RGBsliderReleased ()));

  // Connect point size slider
  connect (ui->horizontalSlider_p, SIGNAL (valueChanged (int)), this, SLOT (pSliderValueChanged (int)));

在这里,我们连接槽和信号,这将 UI 操作与功能联系起来。以下是我们所链接内容的摘要:

  • pushButton_random:
    • 如果按下按钮呼叫randomButtonPressed ()
  • horizontalSlider_R:
    • 如果滑块值更改redSliderValueChanged(int),则以新值作为参数调用
      如果滑块被释放调用RGBsliderReleased()
  • horizontalSlider_G:
    • 如果滑块值更改redSliderValueChanged(int),则以新值作为参数调用
      如果滑块被释放调用RGBsliderReleased()
  • horizontalSlider_B:
    • 如果滑块值更改redSliderValueChanged(int),则以新值作为参数调用
      如果滑块被释放调用RGBsliderReleased()
  viewer->addPointCloud (cloud, "cloud");
  pSliderValueChanged (2);
  viewer->resetCamera ();
  ui->qvtkWidget->update ();
}

这是我们构造函数的最后一部分;我们将点云添加到可视化器中,
调用方法pSliderValueChanged将点大小更改为 2。
我们最终在 PCL Visualizer 中重置了相机,而不是避免用户必须缩小并更新 qvtkwidget 以确保显示修改。

void
PCLViewer::randomButtonPressed ()
{
  printf ("Random button was pressed\n");

  // Set the new color
  for (auto& point: *cloud)
  {
    point.r = 255 *(1024 * rand () / (RAND_MAX + 1.0f));
    point.g = 255 *(1024 * rand () / (RAND_MAX + 1.0f));
    point.b = 255 *(1024 * rand () / (RAND_MAX + 1.0f));
  }

  viewer->updatePointCloud (cloud, "cloud");
  ui->qvtkWidget->update ();
}

这是按下“随机”按钮时调用的公共槽函数成员。
for循环遍历点云并将点云颜色更改为随机数(0 到 255 之间)。
然后点云被更新,因此qtvtkwidget也是如此。

void
PCLViewer::RGBsliderReleased ()
{
  // Set the new color
  for (auto& point: *cloud)
  {
    point.r = red;
    point.g = green;
    point.b = blue;
  }
  viewer->updatePointCloud (cloud, "cloud");
  ui->qvtkWidget->update ();
}

这是每当释放红色、绿色或蓝色滑块时调用的公共槽函数成员
for循环遍历点云并将点云颜色更改为,red和green成员blue值。
然后点云被更新,因此qtvtkwidget也是如此。

void
PCLViewer::redSliderValueChanged (int value)
{
  red = value;
  printf ("redSliderValueChanged: [%d|%d|%d]\n", red, green, blue);
}

void
PCLViewer::greenSliderValueChanged (int value)
{
  green = value;
  printf ("greenSliderValueChanged: [%d|%d|%d]\n", red, green, blue);
}

void
PCLViewer::blueSliderValueChanged (int value)
{
  blue = value;
  printf("blueSliderValueChanged: [%d|%d|%d]\n", red, green, blue);
}

这些是每当更改红色、绿色或蓝色滑块值时调用的公共槽函数成员
这些函数只是将成员值相应地更改为滑块值。
这里点云没有更新;因此,在您释放滑块之前,您不会在可视化工具中看到任何变化。

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

析构函数。

完整pclviewer.cpp

#include "pclviewer.h"
#include "ui_pclviewer.h"

#if VTK_MAJOR_VERSION > 8
#include <vtkGenericOpenGLRenderWindow.h>
#endif

PCLViewer::PCLViewer (QWidget *parent) : QMainWindow (parent), ui (new Ui::PCLViewer)
{
  ui->setupUi (this);
  this->setWindowTitle ("PCL viewer");

  // Setup the cloud pointer
  cloud.reset (new PointCloudT);
  // The number of points in the cloud
  cloud->resize (200);

  // The default color
  red   = 128;
  green = 128;
  blue  = 128;

  // 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);

    point.r = red;
    point.g = green;
    point.b = blue;
  }

  // Set up the QVTK window  
#if VTK_MAJOR_VERSION > 8
  auto renderer = vtkSmartPointer<vtkRenderer>::New();
  auto renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  viewer.reset(new pcl::visualization::PCLVisualizer(renderer, renderWindow, "viewer", false));
  ui->qvtkWidget->setRenderWindow(viewer->getRenderWindow());
  viewer->setupInteractor(ui->qvtkWidget->interactor(), ui->qvtkWidget->renderWindow());
#else
  viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
  ui->qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
  viewer->setupInteractor(ui->qvtkWidget->GetInteractor(), ui->qvtkWidget->GetRenderWindow());
#endif

  // Connect "random" button and the function
  connect (ui->pushButton_random,  SIGNAL (clicked ()), this, SLOT (randomButtonPressed ()));

  // Connect R,G,B sliders and their functions
  connect (ui->horizontalSlider_R, SIGNAL (valueChanged (int)), this, SLOT (redSliderValueChanged (int)));
  connect (ui->horizontalSlider_G, SIGNAL (valueChanged (int)), this, SLOT (greenSliderValueChanged (int)));
  connect (ui->horizontalSlider_B, SIGNAL (valueChanged (int)), this, SLOT (blueSliderValueChanged (int)));
  connect (ui->horizontalSlider_R, SIGNAL (sliderReleased ()), this, SLOT (RGBsliderReleased ()));
  connect (ui->horizontalSlider_G, SIGNAL (sliderReleased ()), this, SLOT (RGBsliderReleased ()));
  connect (ui->horizontalSlider_B, SIGNAL (sliderReleased ()), this, SLOT (RGBsliderReleased ()));

  // Connect point size slider
  connect (ui->horizontalSlider_p, SIGNAL (valueChanged (int)), this, SLOT (pSliderValueChanged (int)));

  viewer->addPointCloud (cloud, "cloud");
  pSliderValueChanged (2);
  viewer->resetCamera ();
  
  refreshView();
}

void
PCLViewer::randomButtonPressed ()
{
  printf ("Random button was pressed\n");

  // Set the new color
  for (auto& point: *cloud)
  {
    point.r = 255 *(1024 * rand () / (RAND_MAX + 1.0f));
    point.g = 255 *(1024 * rand () / (RAND_MAX + 1.0f));
    point.b = 255 *(1024 * rand () / (RAND_MAX + 1.0f));
  }

  viewer->updatePointCloud (cloud, "cloud");
  refreshView();
}

void
PCLViewer::RGBsliderReleased ()
{
  // Set the new color
  for (auto& point: *cloud)
  {
    point.r = red;
    point.g = green;
    point.b = blue;
  }
  viewer->updatePointCloud (cloud, "cloud");
  refreshView();
}

void
PCLViewer::pSliderValueChanged (int value)
{
  viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, value, "cloud");
  refreshView();
}

void
PCLViewer::refreshView()
{
#if VTK_MAJOR_VERSION > 8
  ui->qvtkWidget->renderWindow()->Render();
#else
  ui->qvtkWidget->update();
#endif
}

void
PCLViewer::redSliderValueChanged (int value)
{
  red = value;
  printf ("redSliderValueChanged: [%d|%d|%d]\n", red, green, blue);
}

void
PCLViewer::greenSliderValueChanged (int value)
{
  green = value;
  printf ("greenSliderValueChanged: [%d|%d|%d]\n", red, green, blue);
}

void
PCLViewer::blueSliderValueChanged (int value)
{
  blue = value;
  printf("blueSliderValueChanged: [%d|%d|%d]\n", red, green, blue);
}

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

UI 界面

由qt designer 打开

三

在这里插入图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值