c++ - vtk c++ 从 contourfilter 更新轮廓

标签 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();

在 for 循环中,在使用 ContourFilter 之前,但它仍然没有更新。为此,我尝试了所有我能想到并在网上找到的东西。

这是相关代码:

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

   }

最佳答案

刚找到答案。

vtkWindowToImageFilter 类引用网页 (https://www.vtk.org/doc/nightly/html/classvtkWindowToImageFilter.html) 的详细描述中的警告中所述,vtkWindows 通常不会重新呈现,除非您调用它们的 修改()函数。现在,我的投影 View 已按我想要的方式更新。

所以我改变了

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

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

Warning: A vtkWindow doesn't behave like other parts of the VTK pipeline: its modification time doesn't get updated when an image is rendered. As a result, naive use of vtkWindowToImageFilter will produce an image of the first image that the window rendered, but which is never updated on subsequent window updates. This behavior is unexpected and in general undesirable. To force an update of the output image, call vtkWindowToImageFilter's Modified method after rendering to the window. In VTK versions 4 and later, this filter is part of the canonical way to output an image of a window to a file (replacing the obsolete SaveImageAsPPM method for vtkRenderWindows that existed in 3.2 and earlier). Connect this filter to the output of the window, and filter's output to a writer such as vtkPNGWriter. Reading back alpha planes is dependent on the correct operation of the render window's GetRGBACharPixelData method, which in turn is dependent on the configuration of the window's alpha planes. As of VTK 4.4+, machine-independent behavior is not automatically assured because of these dependencies.

关于c++ - vtk c++ 从 contourfilter 更新轮廓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47436669/

相关文章:

css - 我如何自定义渲染内容元素

asp.net - 在FireFox中禁用链接按钮后,为什么链接按钮不会显示为灰色?

python - 更改pythonpath的优先级

c++ - 在 QVTKWidget 渲染器中添加和删除 vtkChartXY/vtkContextView

c++ - OpenCV 2 cookbook 的 Contours 示例编译错误

c++ - 队列调用事件循环中的一个插槽由 Qt 以向后顺序处理

c++ - pImpl 习语 - 将私有(private)类实现放在 cpp 中有什么缺点?

php - 如何使用 PHP 下载_呈现_网页?

C++ 流程图/GUI 设计器

c++ - 使用 FFmpeg 通过 RTMP 发送 H.264 编码流