Нарисовать и обновить облака точек PCL в виджете QVTK

Мой вопрос касается библиотеки PointClouds (PCL) и виджета QVTK.

У меня есть виджет QVTK в виджете MainWindow. Метод, который рисует мои облака точек, вызывается каждый раз, когда я загружаю новое облако точек с диска (или камеры 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;

(объявление компонентов представления pointcloud как глобальных переменных)

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 должна быть локальной в методе, чтобы работать. Безуспешно потратил часы и часы на поиск и поиск в Google документации о VTK Visualizer, методах QVTK, объектах и ​​т. Д.]

Я понимаю, что вары и объекты, родственные PCL + VTK + QT, никогда не бывают пустыми или нулевыми (поскольку они глобальны в MainWindow !!) ...

Моя среда - Ubuntu 12.04 LTS с Qt Creator 2.5.2, 64 бита. PCL 1.6, VTK 5.8


person Bull    schedule 19.07.2013    source источник


Ответы (1)


Если я правильно понял вашу реализацию, каждый раз, когда вы хотите обновить облако точек (ПК), вы вызываете CamWindow::on_PointCloudChanged(), и новое pcl::visualization::PCLVisualizer инициализируется, поэтому вы теряете все настройки камеры.

Может это поможет. Объявите визуализатор как глобальную переменную вне любого метода

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

Затем напишите метод инициализации, подобный этому, который вы должны вызвать один раз в начале:

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

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

Теперь вы можете обновлять компьютер с именем cloud0 каждый раз при создании new_pc:

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;
   }
}

Я не компилировал код, поэтому не стесняйтесь редактировать свой ответ, если вы использовали его и обнаружили ошибку. Но это должно быть основной идеей.

person Fei    schedule 22.07.2013