1

我目前正在尝试在 2d 图像(没有 opengl 或 3d 图形窗口)中绘制欧拉角的 3d 表示。图像输出可能类似于下图。

欧拉角

本质上,我正在寻找可以采用旋转矩阵或一组欧拉角然后将它们输出到二维图像上的研究或算法,如上所示。这将在使用 OpenCV 的 C++ 应用程序中实现。它将用于根据对象的状态在 OpenCV 窗口上输出注释信息。

我想我想多了,因为我应该能够从旋转矩阵中分解单位向量,然后提取它们的 x,y 分量并从 (0,0) 在笛卡尔空间中画一条线。我的这种想法正确吗?

编辑:我正在寻找正交投影。您可以假设上面的图像具有正确的相机/视角。

任何帮助,将不胜感激。

谢谢,

编辑:现在可以在我的仓库中找到示例源代码。标题:https ://bitbucket.org/jluzwick/tennisspindetector/src/6261524425e8d80772a58fdda76921edb53b4d18/include/projection_matrix.h?at=master

类定义:https ://bitbucket.org/jluzwick/tennisspindetector/src/6261524425e8d80772a58fdda76921edb53b4d18/src/projection_matrix.cpp?at=master

这不是最好的代码,但它可以工作,并显示了获取已接受答案中描述的投影矩阵所需的步骤。

这里还有一个投影矩阵的 youtube 视频(以及添加的比例和翻译):http ://www.youtube.com/watch?v=mSgTFBFb_68

4

2 回答 2

2

这是我的两分钱。希望能帮助到你。

如果我理解正确,您想旋转3D坐标系,然后将其正交投影到给定的2D平面上(2D平面是相对于原始的、未旋转的3D坐标系定义的)。

“旋转和投影3D坐标系”是“旋转三个3D基矢量并将它们正交投影到2D平面上,使它们成为相对于平面的2D基的2D矢量”。让原始的3D向量没有引物,而得到的2D向量有引物。令{e1, e2, e3} = {e1..3}3D正交基(已给出),{e1', e2'} = {e1..2'}2D正交基(我们必须定义)。本质上,我们需要找到 PR * v = v' 这样的算子PR

虽然我们可以谈论很多关于线性代数、运算符和矩阵表示的内容,但这篇文章太长了。这么说就足够了:

  1. 对于3D旋转和3D->2D投影算子,都有实数矩阵表示(线性变换;2D3D的子空间)。
  2. 这是因此应用的两个变换,即PR * v = P * R * v = v',因此我们需要找到旋转矩阵R和投影矩阵P。显然,在我们使用R旋转v之后,我们可以使用P投影结果向量vR
  3. 你已经有了旋转矩阵R,所以我们认为它是一个给定的3x3矩阵。因此,为简单起见,我们将讨论投影向量vR = R * v
  4. 投影矩阵P是一个2x3矩阵,第i列是第i3D基向量ei{e1..2'}基的投影。

让我们找到P投影矩阵,例如3D向量vR在具有正交基{e1..2'}2D平面上线性变换为2D向量v'

二维平面可以很容易地由垂直于它的向量定义。例如,从 OP 中的数字来看,我们的2D平面(纸的平面)似乎具有法线单位向量n = 1/sqrt(3) * ( 1, 1, 1 )。我们需要在这个n定义的2D平面中找到一个2D基。因为任何两个线性独立的向量位于我们的2D平面将形成这样的基础,这里有无数这样的基础。从问题的几何学出发,为了简单起见,让我们强加两个附加条件:首先,基应该是正交的;其次,应该在视觉上吸引人(尽管这有点主观条件)。很容易看出,通过设置e1' = ( 1, 0 )' = x'轴(水平,从左到右的正方向)和e2' = ( 0, 1 )' = y' -轴(垂直,从下到上的正方向)。

现在让我们在{e1..3} 3D基中找到这个{e1', e2'} 2D基。

  1. 让我们在原始基础中将e1'e2'表示为e1"e2"。注意在我们的例子中e1"没有e3 -component ( z -component),并且使用n dot e1" = 0的事实,我们得到e1' = ( 1, 0 )' -> e1" = ( -1 /sqrt(2), 1/sqrt(2), 0 ){e1..3}基础上。这里,表示点积。
  2. 然后e2" = n交叉e1" = ( -1/sqrt(6), -1/sqrt(6), 2/sqrt(6) )。这里,cross表示叉积。

由n = 1/sqrt(3) * ( 1, 1, 1 )定义的2D平面的2x3投影矩阵P由下式给出:

( -1/sqrt(2)    1/sqrt(2)        0     )
( -1/sqrt(6)   -1/sqrt(6)    2/sqrt(6) )

其中第一、第二和第三列被转换为{e1..3} 3D基础到我们的2D基础{e1..2'},即来自3D基础的e1 = ( 1, 0, 0 )具有坐标( -1/sqrt( 2), -1/sqrt(6) )在我们的2D基础上,依此类推。

为了验证结果,我们可以检查一些明显的情况:

  1. n与我们的2D平面正交,所以应该没有投影。实际上,P * n = P * ( 1, 1, 1 ) = 0
  2. e1e2e3应转换为它们在{e1..2'}中的表示,即P矩阵中的对应列。实际上,P * e1 = P * ( 1, 0 ,0 ) = ( -1/sqrt(2), -1/sqrt(6) )等等。

来解决问题。我们现在为任意选择的2D平面构建了一个从3D2D的投影矩阵P。我们现在可以将之前由旋转矩阵R旋转的任何向量投影到这个平面上。例如,旋转原始基础{R * e1, R * e2, R * e3}。此外,我们可以将给定的PR相乘以获得旋转投影变换矩阵PR = P * R

PS C++ 实现留作家庭作业;)。

于 2013-08-19T15:55:00.810 回答
0

旋转矩阵将很容易显示,

旋转矩阵可以通过使用法线、副法线和切线来构造。

您应该能够按如下方式将它们取出:-

Bi-Normal (y') : matrix[0][0], matrix[0][1], matrix[0][2]
Normal    (z') : matrix[1][0], matrix[1][1], matrix[1][2]
Tangent   (x') : matrix[2][0], matrix[2][1], matrix[2][2]

使用透视变换,您可以添加透视 (x,y) = (x/z, y/z)

要实现类似于所示的正交项目,您需要乘以另一个固定旋转矩阵以移动到“相机”视图(向右然后向上 45°)

然后,您可以将端点 x(1,0,0),y(0,1,0),z(0,0,1) 和 center(0,0,0) 乘以最终矩阵,仅使用x,y 坐标。

中心应始终转换为 0,0,0

然后,您可以缩放这些值以绘制到您的 2D 画布。

于 2013-08-18T23:50:22.183 回答