2013-08-02 5 views
5

Je suis en train de rendre des vues d'un maillage 3D VTK, je fais ce qui suit:OpenGL/VTK: caméra le réglage des paramètres intrinsèques

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

Je suis en train de simuler un rendu à partir d'un Kinect calibré, pour dont je connais les paramètres intrinsèques. Comment puis-je définir les paramètres intrinsèques (distance focale et point de principe) à la vtkCamera.

Je souhaite faire ceci de sorte que la coordonnée de la caméra 2D 3d-pixel soit la même que si l'image était prise d'une kinect.

Répondre

3

Moi aussi j'utilise VTK pour simuler la vue d'un capteur de kinect. J'utilise VTK 6.1.0. Je sais que cette question est ancienne, mais j'espère que ma réponse pourrait aider quelqu'un d'autre.

La question est de savoir comment pouvons-nous définir une matrice de projection pour mapper les coordonnées du monde à des coordonnées clip. Pour plus d'informations, voir ceci OpenGL explanation.

J'utilise une matrice de projection en perspective pour simuler le capteur de kinect. Pour contrôler les paramètres intrinsèques, vous pouvez utiliser les fonctions membres suivantes de vtkCamera.

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 

Afin de vous donner une idée de ce à quoi cela peut ressembler. J'ai un old project que j'ai fait complètement en C++ et OpenGL dans lequel j'ai défini la matrice de projection en perspective de la façon dont je l'ai décrite, j'ai saisi le z-buffer, puis j'ai reprojected les points sur une scène que j'ai vue depuis une autre caméra. (Le nuage de points visualisé semble bruyant car j'ai aussi simulé du bruit).

Si vous avez besoin de votre propre matrice de projection personnalisée qui n'est pas la saveur Perspective. Je crois que c'est:

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

Cependant, je n'ai pas utilisé la méthode SetUserTransform.

8

Espérons que cela aidera d'autres personnes à essayer de convertir les paramètres sténopé standard de caméra en vtkCamera: J'ai créé un aperçu montrant comment faire la conversion complète. J'ai vérifié que le projet du monde pointe vers l'emplacement correct dans l'image rendue. Le code clé de l'essentiel est collé ci-dessous.

essentiel: 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

Merci pour cette réponse!J'ai passé une semaine à essayer de faire la caméra vtk pour voir la même chose que je m'attendrais à voir avec un appareil sténopé et j'ai presque le corriger, mais il y avait toujours une différence. Laisser l'appareil photo immobile et déplacer la scène a bien fonctionné! – martinako

+0

Cela fonctionne! Bonne appréciation! – alanwsx

0

Ce fil a été super utile pour moi pour le réglage de la caméra dans intrinsics VTK, la réponse particulièrement decrispell. Pour être complet, cependant, un cas manque: si la distance focale dans les directions x et y n'est pas égale. Cela peut facilement être ajouté au code en utilisant la méthode SetUserTransform. Voici un exemple de code de 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) 

où fx et fy sont les x et y la distance focale en pixels, à savoir les deux premiers éléments de diagnoal de la matrice de la caméra intrinsèque. np est et alias pour l'importation numpy.

Voici un aperçu montrant la solution complète en python (sans extrinsèques pour plus de simplicité). Il place une sphère à une position 3D donnée, restitue la scène dans une image après avoir réglé les intrinsèques de la caméra, puis affiche un cercle rouge sur la projection du centre de la sphère sur le plan image: https://gist.github.com/benoitrosa/ffdb96eae376503dba5ee56f28fa0943

Questions connexes