代码之家  ›  专栏  ›  技术社区  ›  ita

vtk c++从轮廓滤波器更新轮廓

  •  1
  • ita  · 技术社区  · 7 年前

    我有一个3D。我渲染的vtk模型,并使用 vtkContourFilter

    我想从不同的角度进行投影,但当我在不同的摄像机位置上循环时(我检查了摄像机位置是否确实发生了变化),每次迭代启动的交互式查看器始终显示第一幅图像的轮廓。

    当我输出找到的轮廓点的前几个坐标时(我将其存储为 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循环中,在使用轮廓滤波器之前,但它仍然不会更新。有了这些,我尝试了我能想到的一切,并在网上找到了。

    这是相关代码:

       // 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 回复  |  直到 7 年前
        1
  •  1
  •   ita    7 年前

    刚刚找到答案。

    如详细说明中的警告所述 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+开始,由于这些依赖性,机器独立行为不能自动得到保证。