【问题标题】:OpenGL/VTK: setting camera intrinsic parametersOpenGL/VTK:设置相机内在参数
【发布时间】:2013-08-03 21:24:01
【问题描述】:

我正在尝试在 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 拍摄的图像相同。

【问题讨论】:

    标签: c++ opengl graphics vtk camera-calibration


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回答!我花了一周的时间试图让 vtk 相机看到我希望用针孔相机看到的一样,我几乎得到了正确的结果,但总是有一些不同。让相机静止并移动场景效果很好!
    【解决方案2】:

    我也在使用 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
    

    为了让您了解它的外观。我有一个old project,我完全在 C++ 和 OpenGL 中完成了它,我在其中设置了类似于我描述的透视投影矩阵,抓取 z 缓冲区,然后将这些点重新投影到我从不同相机查看的场景上. (可视化的点云看起来很嘈杂,因为我也模拟了噪声)。

    如果您需要不是透视风格的自定义投影矩阵。我相信是:

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

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

    【讨论】:

      【解决方案3】:

      这个线程对我在 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 中显示完整解决方案的要点(为简单起见,没有外在)。它在给定的 3D 位置放置一个球体,在设置相机内部函数后将场景渲染为图像,然后在球体中心在图像平面上的投影处显示一个红色圆圈:https://gist.github.com/benoitrosa/ffdb96eae376503dba5ee56f28fa0943

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-12
        • 2012-05-29
        • 1970-01-01
        • 1970-01-01
        • 2012-07-10
        • 2018-10-30
        • 1970-01-01
        相关资源
        最近更新 更多