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 камеры были такими же, как если бы изображение было снято с кинекта.

6

Решение

Надеюсь, это поможет другим, пытающимся преобразовать стандартные параметры камеры-обскуры в 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.

Я использую матрицу перспективной проекции для симуляции датчика кинетики. Для управления внутренними параметрами вы можете использовать следующие функции-члены 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.

3

Эта тема была очень полезна для меня для установки внутренних характеристик камеры в ВТК, особенно для ответа Дериспелла. Для полноты, однако, один случай отсутствует: если фокусное расстояние в направлениях 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 — это псевдоним для импровизированного импорта.

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

0
А ты уже прошел курс программирования? Супер скидка!
Прокачать скилл $$$
×