【问题标题】:vtk c++ update contour from contourfiltervtk c++ 从轮廓过滤器更新轮廓
【发布时间】:2018-05-06 07:23:40
【问题描述】:

我有一个渲染的 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();

   }

【问题讨论】:

    标签: c++ render vtk projection contour


    【解决方案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 方法的正确操作,而该方法又取决于窗口的 alpha 平面的配置。从 VTK 4.4+ 开始,由于这些依赖关系,机器独立行为不会自动得到保证。

    【讨论】:

      猜你喜欢
      • 2018-03-18
      • 1970-01-01
      • 2016-05-13
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      相关资源
      最近更新 更多