我们如何从视图变换矩阵中提取视图向量,视角和焦点?

时间:2014-09-24 09:01:36

标签: opengl camera computer-vision vtk

我有一个传感器(跟踪器),它相对于世界坐标的旋转和相对于世界坐标的位置是已知的。我正在使用VTK相机渲染世界的3D模型。

我已经在世界坐标中注册了模型。

基于跟踪器相对于世界坐标的旋转和位置,跟踪器和世界之间的相对位置是已知的。因此,如果我可以重新调整VTK摄像机的位置,使其与渲染的3D模型处于相对于世界的跟踪器相同的相对位置和方向,我将获得与世界对齐的3D模型。

我的直觉说这可以通过改变VTK摄像机的视图向上矢量,视角,焦点和位置来完成。 trackerMat 是一个vtkMatrix,它包含有关世界坐标中跟踪器的旋转和位置的信息。 相机是vtkCamera,渲染器是vtkRenderer。

record.x,record.y和record.z 是世界坐标中跟踪器的实时位置。 record.a,record.e和record.r 是跟踪器的方位角,仰角和滚动。 基本上这就是我想要做的事情:

vtkSmartPointer<vtkMatrix4> trackerMat = vtkSmartPointer<vtkMatrix4>::New();
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
camera->SetPosition(record.x, record.y, record.z);
camera->SetFocalPoint(f.x, f.y, f.z);
camera->SetViewUp(viewUp.x, viewUp.y, viewUp.z);
camera->SetViewAngle(viewAngle);
renderer->SetActiveCamera(camera);
renderer->GetRenderWindow()->Render();

我尝试将vtkCamera方位角,仰角和滚动设置为与跟踪器相同,但它给出了奇怪的结果

这就是为什么我认为我应该设置焦点,查看向量和视角到vtkCamera而不是角度。 vtkCamera位置可以轻松设置到与跟踪器相同的位置。有没有我可以从 trackerMat 中提取视图向上矢量,焦点和视角?我的renderWindow大小为 1280 * 720

更新 我通过将vtkCamera焦点设置到不同位置并查看viewMatrix如何更改来进行了大量试验:

案例1:

camera->SetPosition(0,0,-5);
camera->SetFocalPoint(0,0,0);
vtkSmartPointer<vtkMatrix4x4> viewMat = vtkSmartPointer<vtkMatrix4x4>::New();
viewMat = camera->GetViewTransformMatrix();

在这种情况下,viewMat是:

-1   0   0  0
 0   1   0  0
 0   0   0  -5
 0   0   0   1

案例2:

camera->SetPosition(0,0,-5);
camera->SetFocalPoint(0,0,3);
vtkSmartPointer<vtkMatrix4x4> viewMat = vtkSmartPointer<vtkMatrix4x4>::New();
viewMat = camera->GetViewTransformMatrix();

在这种情况下,viewMat是:

-1   0   0  0
 0   1   0  0
 0   0   0  -5
 0   0   0   1

因此,当焦点仅在z方向上改变时,viewMat将保持相同。有道理。

案例3:

camera->SetPosition(0,0,-5);
camera->SetFocalPoint(3,3,3);
vtkSmartPointer<vtkMatrix4x4> viewMat = vtkSmartPointer<vtkMatrix4x4>::New();
viewMat = camera->GetViewTransformMatrix();

在这种情况下,viewMat是:

-0.936     0      0.351     1.755
-0.116   0.943   -0.310    -1.551
-0.331  -0.331   -0.883    -4.417
   0       0        0          1

如果我将viewMat行索引为0到3,将列索引为0到3,那么我看到的是 viewMat(0,3),viewMat(1,3)和viewMat(2,3)< / strong>并不总是对应于世界坐标中的vtkCamera位置。

投影方向=指向从摄像机位置到焦点方向的单位矢量。 似乎 -viewMat(2,0), - viewMat(2,1)和-viewMat(2,2)始终对应于投影方向。

如果您将查看向量正交化,使其始终垂直于投影方向:

camera->OrthogonaliseViewUp();

然后可以看出 -viewMat(1,0), - viewMat(1,1)和-viewMat(1,2)始终对应于vtkCamera的viewUp向量。

据我所知,平移向量 viewMat(0,3),viewMat(1,3)和viewMat(2,3),应该以相机坐标为您的世界起源。但在vtk中似乎并非如此。

1 个答案:

答案 0 :(得分:2)

转换矩阵本质上是从原点空间看到的目标空间的基本向量。所以您感兴趣的信息可以在视图矩阵中使用,左上3×3子矩阵是精确的,每行或每列(取决于您想要的映射;在正交矩阵中 - 和上部左3×3的视图应该是正交的,转置是反的,所以行是与列的倒数)。

请注意,在视图转换中没有“焦点”这样的东西,只有方向Right,Up和View。但这正是你所需要的。