OpenGL/VTK: настройка внутренних параметров камеры

Я пытаюсь визуализировать виды 3D-сетки в VTK, я делаю следующее:

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.


person Aly    schedule 02.08.2013    source источник


Ответы (3)


Надеюсь, это поможет другим, пытающимся преобразовать стандартные параметры камеры-обскуры в vtkCamera: я создал суть, показывающую, как выполнить полное преобразование. Я убедился, что проект world указывает правильное место на визуализированном изображении. Код ключа из сути вставлен ниже.

суть: 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 );
person decrispell    schedule 18.02.2016
comment
Спасибо за этот ответ! Я потратил неделю, пытаясь заставить камеру vtk видеть то же самое, что я ожидал увидеть с помощью камеры-обскуры, и я почти правильно понял, но всегда была какая-то разница. Неподвижная камера и перемещение сцены работали хорошо! - person martinako; 14.12.2016

Я тоже использую VTK для имитации вида с сенсора kinect. Я использую ВТК 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.

person Lucas Chavez    schedule 23.09.2014

Этот поток был очень полезен для меня для настройки встроенных функций камеры в VTK, особенно для ответа decrispell. Однако для полноты пропущен один случай: если фокусные расстояния в направлениях x и y не равны. Это можно легко добавить в код с помощью метода SetUserTransform. Ниже приведен пример кода на питоне:

 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.

Вот суть, показывающая полное решение на питоне (для простоты без экстрима). Он размещает сферу в заданной 3D-позиции, визуализирует сцену в изображение после настройки встроенных функций камеры, а затем отображает красный круг в проекции центра сферы на плоскость изображения: https://gist.github.com/benoitrosa/ffdb96eae376503dba5ee56f28fa0943

person Ben    schedule 03.10.2017