vtk c ++从contourfilter更新轮廓

时间:2017-11-22 14:03:43

标签: c++ render vtk projection contour

我有一个3D渲染的.vtk模型,我使用vtkContourFilter从结果图像中提取轮廓(在Ubuntu 16.04上使用vtk 7.0.0版本)。

我想从不同的角度进行投影,但是当我遍历不同的摄像机位置时(我检查了摄像机位置确实已经改变),每次迭代启动的交互式查看器始终显示第一张图像的轮廓。

当我输出找到的轮廓点的前几个坐标(我存储为vtkPolyData)时,我也注意到我的轮廓点集中的内容没有变化。

我尝试了一些适用于其他人的在线建议,例如添加:

ContFilter->Modified();
ContFilter->Update();

polyData->Modified(); // This is the 3D vtkPolyData that I project

ContFilter->SetValue(0, 10);
ContFilter->SetValue(0, 255);

作为一个疯狂的猜测,我也尝试添加:

polyData->Modified();

// Remove old links
renderWindow->RemoveRenderer(renderer);
mapper->RemoveAllInputs();


// Set new links
renderer->SetActiveCamera(camera);
renderWindow->AddRenderer(renderer);
renderer->Modified();
renderer->ResetCameraClippingRange();

renderWindow->Modified();

mapper->SetInputData(polyData);
renderWindow->Render();
在使用ContourFilter之前,在for循环中

,但它仍然没有更新。有了这个,我尝试了我能想到的一切并在网上找到。

这是相关代码:

   // Prepare the rendering environment to project the 3D model to an image from different perspectives
   vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
   mapper->SetInputData(polyData);
   mapper->ScalarVisibilityOff();

   vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
   actor->SetMapper(mapper);
   actor->GetProperty()->SetInterpolationToFlat();

   vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
   renderer->SetBackground(1,1,1);
   renderer->AddActor(actor);

   vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
   vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
   renderWindow->SetOffScreenRendering(1);
   vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
   vtkSmartPointer<vtkContourFilter> ContFilter = vtkSmartPointer<vtkContourFilter>::New();
   vtkSmartPointer<vtkPolyData> contour = vtkSmartPointer<vtkPolyData>::New();

   // Loop over the camera positions. At each iteration render/project, 
   // extract the contour and finally render the 3D model and the found 
   // contour
   double * iPoint;
   double * camPos;
   double * contourStart;
   int nContours;
   for(int i=0; i<positions->GetNumberOfPoints(); i++){
      // Print the camera position
      iPoint = positions->GetPoint(i);
      std::cout << iPoint[0] << " " << iPoint[1] << " " << iPoint[2] << std::endl;

      //Move camera
      camera->SetPosition(iPoint[0], iPoint[1], iPoint[2]);
      camera->SetFocalPoint(focalPointOrig[0], focalPointOrig[1], focalPointOrig[2]);
      camera->SetViewAngle(viewAngle);
      camera->Modified();
      camera->SetRoll(90);

      // Does this help to update the view?
      polyData->Modified();

      // Remove old links and set them again
      renderWindow->RemoveRenderer(renderer);
      mapper->RemoveAllInputs();
      renderer->SetActiveCamera(camera);
      renderWindow->AddRenderer(renderer);
      renderer->Modified();
      renderer->ResetCameraClippingRange();
      renderWindow->Modified();

      // Render/project the data
      mapper->SetInputData(polyData);
      renderWindow->Render();

      // Print camera position for debugging
      camera->GetPosition(camPos);
      std::cout << camPos[0] << " " << camPos[1] << " " << camPos[2] << std::endl;

      // Get the image and apply a contourfilter
      windowToImageFilter->SetInput(renderWindow);
      windowToImageFilter->Update();
      ContFilter->SetInputConnection(windowToImageFilter->GetOutputPort());

      // Saw someone do this as a workaround for updating the view
      ContFilter->SetValue(0, 10);
      ContFilter->SetValue(0, 255);

      // Does this help to update the view?
      ContFilter->Modified();

      //Get the contour from the contourfilter
      ContFilter->Update();
      contour = ContFilter->GetOutput();

      // Print the first points coordinates to see if they changed
      contourStart = contour->GetPoint(1);
      std::cout << contourStart[0] << " " << contourStart[1] << " " << std::endl;

      // Print the number of contours to see if it may be stored as an additional contour
      nContours = ContFilter->GetNumberOfContours();
      std::cout << nContours << std::endl;


      // Render the 3D model and the found contour
      actor->GetProperty()->SetColor(0.9,0.9,0.8);

      // Create a mapper and actor of the silhouette
      vtkSmartPointer<vtkPolyDataMapper> mapper_contour = vtkSmartPointer<vtkPolyDataMapper>::New();
      mapper_contour->SetInputData(contour);

      // Try this again here
      polyData->Modified();

      vtkSmartPointer<vtkActor> actor_contour = vtkSmartPointer<vtkActor>::New();
      actor_contour->SetMapper(mapper_contour);
      actor_contour->GetProperty()->SetLineWidth(2.);

      // 2 renderers and a render window
      vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
      renderer1->AddActor(actor);
      vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();
      renderer2->AddActor(actor_contour);

      // Set the 3D model renderer to the same perspective but don't change the camera perspective of the contour
      renderer1->SetActiveCamera(camera);

      // Setup the window
      vtkSmartPointer<vtkRenderWindow> renderwindow = vtkSmartPointer<vtkRenderWindow>::New();
      renderwindow->SetSize(1600, 800);
      renderwindow->AddRenderer(renderer1);
      renderer1->SetViewport(0., 0., 0.5, 1.);
      renderwindow->AddRenderer(renderer2);
      renderer2->SetViewport(0.5, 0., 1., 1.);

      // Setup the interactor
      vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
      vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
      iren->SetRenderWindow( renderwindow);
      iren->SetInteractorStyle(style);

      // Display the coordinate system axes
      vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
      vtkSmartPointer<vtkOrientationMarkerWidget> widget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
      widget->SetOutlineColor( 0.9300, 0.5700, 0.1300 );
      widget->SetOrientationMarker( axes );
      widget->SetInteractor( iren );
      widget->SetViewport( 0.0, 0.0, 0.4, 0.4 );
      widget->SetEnabled( 1 );
      widget->InteractiveOn();

      // Render the 3D model and the found contour
      renderwindow->Render();
      iren->Start();

   }

1 个答案:

答案 0 :(得分:1)

刚刚找到答案。

正如vtkWindowToImageFilter课程参考网页(https://www.vtk.org/doc/nightly/html/classvtkWindowToImageFilter.html)详细说明中的警告所述,vtkWindows通常不会重新渲染,除非您调用其Modified()函数。现在我的预测视图会像我想要的那样更新。

所以我改变了

// Get the image and apply a contourfilter
windowToImageFilter->SetInput(renderWindow);
windowToImageFilter->Update();

// Get the image and apply a contourfilter
windowToImageFilter->Modified();
windowToImageFilter->SetInput(renderWindow);
windowToImageFilter->Update();

如果上面的链接停止工作,请在此处查看警告文字:

  

警告:       vtkWindow的行为与VTK管道的其他部分不同:在渲染图像时,其修改时间不会更新。因此,天真地使用vtkWindowToImageFilter将生成窗口呈现的第一个图像的图像,但在后续窗口更新时永远不会更新。这种行为是出乎意料的,通常是不可取的       要强制更新输出图像,请在渲染到窗口后调用vtkWindowToImageFilter的Modified方法。       在VTK版本4及更高版本中,此过滤器是将窗口图像输出到文件的规范方式的一部分(替换3.2及更早版本中存在的vtkRenderWindows的过时的SaveImageAsPPM方法)。将此过滤器连接到窗口的输出,并将过滤器的输出连接到编写器,例如vtkPNGWriter。       回读alpha平面取决于渲染窗口的GetRGBACharPixelData方法的正确操作,而GetRGBACharPixelData方法又取决于窗口alpha平面的配置。从VTK 4.4+开始,由于这些依赖性,不能自动确保与机器无关的行为。