2013-08-02 8 views
5

I Ansichten eines 3D-Netzes in VTK zu machen versuche, ich tue das folgende:OpenGL/VTK: Einstellung kameraintrinsische Parameter

vtkSmartPointer<vtkRenderWindow> render_win = vtkSmartPointer<vtkRenderWindow>::New(); 
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); 

render_win->AddRenderer(renderer); 
render_win->SetSize(640, 480); 

vtkSmartPointer<vtkCamera> cam = vtkSmartPointer<vtkCamera>::New(); 

cam->SetPosition(50, 50, 50); 
cam->SetFocalPoint(0, 0, 0); 
cam->SetViewUp(0, 1, 0); 
cam->Modified(); 

vtkSmartPointer<vtkActor> actor_view = vtkSmartPointer<vtkActor>::New(); 

actor_view->SetMapper(mapper); 
renderer->SetActiveCamera(cam); 
renderer->AddActor(actor_view); 

render_win->Render(); 

Ich versuche, ein Rendering von einem kalibrierten Kinect zu simulieren, für was ich kenne die intrinsischen Parameter. Wie kann ich die intrinsischen Parameter (Brennweite und Hauptpunkt) auf die vtkCamera einstellen?

Ich möchte dies tun, so dass die 2D-Pixel - 3D-Kamera-Koordinaten gleich wären, als wäre das Bild von einem Kinect genommen.

Antwort

3

Auch ich verwende VTK, um die Ansicht von einem Kinect-Sensor zu simulieren. Ich verwende VTK 6.1.0. Ich weiß, dass diese Frage alt ist, aber hoffentlich hilft meine Antwort jemand anderem.

Die Frage ist, wie können wir eine Projektionsmatrix auf Weltkoordinaten zu Clip-Koordinaten zuordnen. Weitere Informationen hierzu finden Sie unter OpenGL explanation.

Ich verwende eine Perspektive Projection Matrix, um den Kinect-Sensor zu simulieren. Um die intrinsischen Parameter zu kontrollieren, können Sie die folgenden Memberfunktionen von vtkCamera verwenden.

double fov = 60.0, np = 0.5, fp = 10; // the values I use 
cam->SetViewAngle(fov);    // vertical field of view angle 
cam->SetClippingRange(np, fp);  // near and far clipping planes 

Um Ihnen ein Gefühl dafür zu geben, wie das aussehen könnte. Ich habe eine old project, die ich komplett in C++ und OpenGL gemacht habe, in der ich die Perspektive Projection Matrix ähnlich wie ich beschrieben habe, packte den Z-Puffer, und dann projiziert die Punkte auf eine Szene, die ich von einer anderen Kamera angesehen. (Die visualisierte Punktwolke sieht laut aus, weil ich auch Rauschen simuliert habe).

Wenn Sie Ihre eigene benutzerdefinierte Projektionsmatrix brauchen, die nicht die Perspektive Geschmack ist. Ich glaube es ist:

cam->SetUserTransform(transform); // transform is a pointer to type vtkHomogeneousTransform 

Ich habe jedoch nicht die SetUserTransform-Methode verwendet.

8

Ich hoffe, dass dies anderen helfen wird, Standard-Lochkamera-Parameter in eine vtkCamera zu konvertieren: Ich habe einen Text erstellt, der zeigt, wie man die vollständige Konvertierung durchführt. Ich habe überprüft, dass die Weltpunkte im gerenderten Bild an die richtige Stelle projiziert werden. Der Schlüsselcode aus dem Hauptteil wird unten eingefügt.

Kern: https://gist.github.com/decrispell/fc4b69f6bedf07a3425b

// apply the transform to scene objects 
    camera->SetModelTransformMatrix(camera_RT); 

    // the camera can stay at the origin because we are transforming the scene objects 
    camera->SetPosition(0, 0, 0); 
    // look in the +Z direction of the camera coordinate system 
    camera->SetFocalPoint(0, 0, 1); 
    // the camera Y axis points down 
    camera->SetViewUp(0,-1,0); 

    // ensure the relevant range of depths are rendered 
    camera->SetClippingRange(depth_min, depth_max); 

    // convert the principal point to window center (normalized coordinate system) and set it 
    double wcx = -2*(principal_pt.x() - double(nx)/2)/nx; 
    double wcy = 2*(principal_pt.y() - double(ny)/2)/ny; 
    camera->SetWindowCenter(wcx, wcy); 

    // convert the focal length to view angle and set it 
    double view_angle = vnl_math::deg_per_rad * (2.0 * std::atan2(ny/2.0, focal_len)); 
    std::cout << "view_angle = " << view_angle << std::endl; 
    camera->SetViewAngle(view_angle); 
+0

Vielen Dank für diese Antwort!Ich habe eine Woche damit verbracht, die vtk-Kamera dazu zu bringen, dasselbe zu sehen, das ich mit einer Lochkamera sehen würde, und ich bekomme es fast richtig, aber es gab immer einen Unterschied. Die Kamera still zu lassen und die Szene zu bewegen hat gut funktioniert! – martinako

+0

Das funktioniert! Große Wertschätzung! – alanwsx

0

Dieser Thread ist super für mich nützlich für die Kamera-Spezifika in VTK Einstellung, vor allem decrispell Antwort. Allerdings fehlt ein Fall, wenn die Brennweite in x- und y-Richtung nicht gleich ist. Dies kann einfach mithilfe der SetUserTransform-Methode zum Code hinzugefügt werden. Unten ist ein Beispielcode in Python:

cam = self.renderer.GetActiveCamera() 
m = np.eye(4) 
m[0,0] = 1.0*fx/fy 
t = vtk.vtkTransform() 
t.SetMatrix(m.flatten()) 
cam.SetUserTransform(t) 

wobei Fx und Fy die x- und y die Brennweite in Pixel sind, das heißt, die beiden ersten Elemente diagnoal der intrinsischen Kameramatrix. np ist und alias für den numpy-Import.

Hier ist ein Überblick über die vollständige Lösung in Python (ohne Extrinsics zur Vereinfachung). Es platziert eine Kugel an einer bestimmten 3D-Position, rendert die Szene in ein Bild nach der Einstellung der Kamera intrinsics, und zeigt dann einen roten Kreis bei der Projektion der Kugelmitte auf der Bildebene: https://gist.github.com/benoitrosa/ffdb96eae376503dba5ee56f28fa0943

Verwandte Themen