我有一个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();
}
答案 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+开始,由于这些依赖性,不能自动确保与机器无关的行为。