2017-11-22 9 views
0

Ich habe ein 3D .vtk Modell, das ich rendere und ich extrahiere die Kontur aus dem resultierenden Bild mit einem vtkContourFilter (mit vtk Version 7.0.0 auf Ubuntu 16.04).vtk C++ update Kontur von Konturfilter

Ich möchte es aus verschiedenen Perspektiven projizieren, aber während ich die verschiedenen Kamerapositionen durchlaufe (ich habe überprüft, dass die Kamerapositionen tatsächlich geändert werden), zeigt der interaktive Viewer, der mit jeder Iteration startet, immer die Kontur vom ersten Bild .

Wenn ich die ersten paar Koordinaten der gefundenen Konturpunkte ausspreche (die ich als vtkPolyData speichere), bemerkte ich auch, dass sich der Inhalt meiner Konturpunkte nicht ändert.

Ich habe einige Online-Vorschläge versucht, die für andere, wie das Hinzufügen gearbeitet:

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

und

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

und

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

Als wilde Vermutung auch ich versucht, das Hinzufügen :

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

innerhalb der for-Schleife vor der Verwendung des ContourFilter, aber es wird immer noch nicht aktualisiert. Damit habe ich alles versucht, was ich mir vorstellen konnte und finde es online.

Dies ist der entsprechende Code:

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

    } 

Antwort

0

gefunden Nur die Antwort.

Wie in der Warnung in der detaillierten Beschreibung der Referenz Webseite vtkWindowToImageFilter Klasse erwähnt (https://www.vtk.org/doc/nightly/html/classvtkWindowToImageFilter.html), vtkWindows der Regel nicht rerender, wenn Sie ihre Modified() Funktion aufrufen. Jetzt werden meine projizierten Ansichten aktualisiert, wie ich es wollte.

Also änderte ich

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

zu

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

hier der Warntext, falls siehe Link oben immer mehr funktioniert:

Warnung: A vtkWindow nicht sich wie andere Teile der VTK-Pipeline verhalten: Die Änderungszeit wird nicht aktualisiert, wenn ein Bild gerendert wird. Dies führt dazu, dass eine naive Verwendung von vtkWindowToImageFilter ein Bild des ersten Bildes erzeugt, das das Fenster gerendert hat, das jedoch bei nachfolgenden Fensteraktualisierungen nie aktualisiert wird. Dieses Verhalten ist unerwartet und im Allgemeinen nicht wünschenswert. Um eine Aktualisierung des Ausgabebilds zu erzwingen, rufen Sie die Modified-Methode von vtkWindowToImageFilter nach dem Rendern im Fenster auf. In VTK-Versionen 4 und höher ist dieser Filter Teil der kanonischen Methode, ein Bild eines Fensters in eine Datei auszugeben (ersetzt die veraltete Methode SaveImageAsPPM für vtkRenderWindows, die in 3.2 und früher existierte). Verbinden Sie diesen Filter mit dem Ausgang des Fensters und filtern Sie die Ausgabe an einen Writer wie vtkPNGWriter. Das Lesen von Alpha-Ebenen hängt von der korrekten Ausführung der GetRGBACharPixelData-Methode des Renderfensters ab, die wiederum von der Konfiguration der Alpha-Ebenen des Fensters abhängt. Ab VTK 4.4+ ist das maschinenunabhängige Verhalten aufgrund dieser Abhängigkeiten nicht automatisch gewährleistet.