首页 文章

OpenGL / VTK:设置相机内部参数

提问于
浏览
6

我试图在VTK中渲染3D网格的视图,我正在做以下事情:

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

我试图从校准的Kinect模拟渲染,我知道其中的内在参数 . 如何设置vtkCamera的内部参数(焦距和原理点) .

我希望这样做,以便2d像素-3d相机坐标与从kinect拍摄的图像相同 .

3 回答

  • 3

    希望这将有助于其他人尝试将标准针孔相机参数转换为vtkCamera:我创建了一个显示如何进行完全转换的要点 . 我验证了世界将项目指向渲染图像中的正确位置 . 要点的关键代码粘贴在下面 .

    要点: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 );
    
  • 10

    我也使用VTK来模拟kinect传感器的视图 . 我正在使用VTK 6.1.0 . 我知道这个问题已经过时了,但希望我的回答可以帮助别人 .

    问题是我们如何设置投影矩阵以将世界坐标映射到剪辑坐标 . 有关详细信息,请参阅OpenGL explanation.

    我使用透视投影矩阵来模拟kinect传感器 . 要控制内部参数,可以使用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
    

    为了让您了解可能是什么样子 . 我有一个完全在C和OpenGL中完成的old project,我在其中设置了与我描述的类似的透视投影矩阵, grab 了z缓冲区,然后将这些点重新投影到我从另一台摄像机查看的场景上 . (可视化的点 Cloud 看起来很吵,因为我也模拟了噪音) .

    如果您需要自己的自定义投影矩阵,而不是透视风格 . 我相信它是:

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

    但是,我没有使用SetUserTransform方法 .

  • 0

    这个线程对于我在VTK中设置相机内在函数非常有用,尤其是decrispell的答案 . 然而,为了完整,缺少一个案例:如果x和y方向上的焦距不相等 . 这可以通过使用SetUserTransform方法轻松添加到代码中 . 下面是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)
    

    其中fx和fy是像素中的x和y焦距,即本征相机矩阵的两个第一诊断元素 . np是numpy导入的别名 .

    这是一个在python中显示完整解决方案的要点(为简单起见,没有extrinsics) . 它将球体放置在给定的3D位置,在设置相机内在函数后将场景渲染为图像,然后在图像平面上的球体中心投影处显示红色圆圈:https://gist.github.com/benoitrosa/ffdb96eae376503dba5ee56f28fa0943

相关问题