1

我的问题涉及 PointClouds 库 (PCL) 和 QVTK 小部件。

我在 MainWindow 小部件中有一个 QVTK 小部件。每次我从磁盘(或 ToF 相机)加载新的点云时,都会调用绘制点云的方法:

void CamWindow::on_PointCloudChanged()
{
      //pclPointCloud is declared as "pcl::PointCloud<pcl::PointXYZ>::Ptr pclPointCloud;". When that variable is updated, this method is called.
      //pclVisorName is global std::string, with "visor" as content
      //pclPointCloudName is global std::string, with "MyPointCloud" as content
      pcl::visualization::PCLVisualizer localPclVisor = pcl::visualization::PCLVisualizer(pclVisorName,false);
      localPclVisor.addPointCloud<pcl::PointXYZ>(pclPointCloud,pclPointCloudName);
      //localPclVisor.setBackgroundColor(1,1,0);
      vtkSmartPointer<vtkRenderWindow> localRenderWindow = localPclVisor.getRenderWindow();
      ui->QvtkPointCloud->SetRenderWindow(localRenderWindow);
      ui->QvtkPointCloud->update();

    existPclPointCloud = true;
}

这可行,但每次调用此方法时,都会重置相机位置、视点和其他内容。我只想更改点云来查看,而不重置位置、颜色等。我该如何实现呢?

我试过这样的事情:

std::string                         pclPointCloudName;
pcl::PointCloud<pcl::PointXYZ>::Ptr pclPointCloud;
pcl::visualization::PCLVisualizer   pclVisor;
std::string                         pclVisorName;
vtkSmartPointer<vtkRenderWindow>    renderWindow;

(将点云表示组件声明为全局变量)

void CamWindow::on_PointCloudChanged()
{
      //pclPointCloud is declared as "pcl::PointCloud<pcl::PointXYZ>::Ptr pclPointCloud;". When that variable is updated, this method is called.
      //pclVisorName is global std::string, with "visor" as content
      //pclPointCloudName is global std::string, with "MyPointCloud" as content
    if (existPclPointCloud)
    {
        localPclVisor.updatePointCloud<pcl::PointXYZ>(pclPointCloud,pclPointCloudName);
    }
    else
    {
      pcl::visualization::PCLVisualizer pclVisor = pcl::visualization::PCLVisualizer(pclVisorName,false);
      pclVisor.addPointCloud<pcl::PointXYZ>(pclPointCloud,pclPointCloudName);
      vtkSmartPointer<vtkRenderWindow> renderWindow = pclVisor.getRenderWindow();
      ui->QvtkPointCloud->SetRenderWindow(renderWindow);        
    }
     ui->QvtkPointCloud->update();

    existPclPointCloud = true;
}

但这不起作用...将 QVTK 和 PCL 组件声明为全局变量(在 MainWindow 小部件中)使该程序在 QVTK 小部件中不显示任何内容!为什么?

[我也尝试了几种变体,但似乎每个 PCL+VTK+QT 变量都必须是本地方法才能工作。花费数小时寻找和谷歌搜索有关 VTK Visualizer、QVTK 方法、对象等的文档,但没有运气]

我知道与 PCL+VTK+QT 相关的变量和对象永远不会为空或 null(因为它们在 MainWindow 中是全局的!!)...

我的环境是 Ubuntu 12.04 LTS,带有 Qt Creator 2.5.2,64 位。PCL 1.6,VTK 5.8

4

1 回答 1

1

如果我理解你的实现是正确的,每次你想更新你的点云(pc)时,你都会调用CamWindow::on_PointCloudChanged()并初始化一个新pcl::visualization::PCLVisualizer的,这就是你丢失所有相机设置的原因。

也许这会有所帮助。在任何方法之外将可视化器声明为全局变量

pcl::visualization::PCLVisualizer pclVisor ("visor", false);

然后写一个类似这样的init方法,你必须在开始时调用一次:

void CamWindow::init() {
   vtkSmartPointer<vtkRenderWindow> renderWindow = pclVisor.getRenderWindow();
   this->SetRenderWindow(renderWindow);

   this->show();
   this->update();
}

现在您可以在cloud0每次new_pc创建 a 时更新名为 的电脑:

void CamWindow::on_PointCloudChanged(pcl::PointCloud<pcl::PointXYZ>::Ptr new_pc) {
   if (!pc->empty()) {

      // in case there is no pc called `cloud0` - create one,
      // otherwise just update it
      if (!pclVisor.updatePointCloud<pcl::PointXYZ>(new_pc, "cloud0")) {
         pclVisor.addPointCloud<pcl::PointXYZ>(new_pc, "cloud0");
      } else {
         pclVisor.updatePointCloud<pcl::PointXYZ>(new_pc, "cloud0");
      } 

      this->update();
   } else {
      std::cerr << "There is nothing to add to the visualizer!" << std::endl;
   }
}

我还没有编译代码,所以请随时编辑我的答案,以防您使用它并发现任何错误。但这应该是基本思想。

于 2013-07-22T11:34:13.557 回答