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 拍摄的图像相同。

4

3 回答 3

10

希望这将有助于其他尝试将标准针孔相机参数转换为 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 );
于 2016-02-18T18:47:41.230 回答
3

我也在使用 VTK 来模拟来自 kinect 传感器的视图。我正在使用 VTK 6.1.0。我知道这个问题很老,但希望我的回答可以帮助其他人。

问题是我们如何设置投影矩阵来将世界坐标映射到剪辑坐标。有关这方面的更多信息,请参阅此OpenGL 说明。

我使用透视投影矩阵来模拟 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 中完成的旧项目,在该项目中我设置了类似于我描述的透视投影矩阵,抓取 z 缓冲区,然后将这些点重新投影到我从不同相机查看的场景上。(可视化的点云看起来很嘈杂,因为我也模拟了噪声)。

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

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

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

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

于 2017-10-03T16:41:46.730 回答