在2d图像上绘制欧拉角旋转模型

时间:2013-08-18 21:45:12

标签: c++ opencv euler-angles

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

euler angles

基本上我正在寻找可以采用旋转矩阵或一组欧拉角的研究或算法,然后将它们输出到二维图像上,如上所述。这将在使用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 vid(加上比例和翻译):http://www.youtube.com/watch?v=mSgTFBFb_68

2 个答案:

答案 0 :(得分:1)

这是我的两分钱。希望它有所帮助。

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

"旋转和投射 3D 坐标系统"是"旋转三个 3D 基矢量并将它们正交投影到 2D 平面上,使它们成为 2D 矢量相对于 2D 平面的基础"。让原始 3D 矢量未被打开,并生成 2D 矢量。设 {e1,e2,e3} = {e1..3} 3D 标准正交(给出), {e1',e2& #39;} = {e1..2'} 2D 标准正交基础(我们必须定义)。基本上,我们需要找到 PR * v = v' 这样的运算符 PR

虽然我们可以谈论线性代数,运算符和矩阵表示,但它的篇幅太长了。它足以说明:

  1. 对于 3D 旋转和 3D-&gt; 2D 投影算子,都有真实的矩阵表示(线性变换; 2D 是<的子空间< EM> 3D )。
  2. 这是因此应用的两个转换,即 PR * v = P * R * v = v&#39; ,因此我们需要找到旋转矩阵 R 和投影矩阵 P 。显然,在我们使用 R 轮换 v 后,我们可以使用 P 投影结果向量 vR
  3. 您已经有旋转矩阵 R ,因此我们认为它是给定的 3x3 矩阵。因此,为简单起见,我们将讨论投影向量 vR = R * v
  4. 投影矩阵 P 2x3 矩阵, i 第列是 i -th的投影 3D 基础向量 ei {e1..2&#39;} 基础上。
  5. 让我们找到 P 投影矩阵,例如 3D 向量 vR 线性转换为 2D 2D 平面上的矢量 v&#39; ,具有标准正交基础 {e1..2&#39;}

    2D 平面可以通过与其垂直的向量轻松定义。例如,从OP中的数字来看,似乎我们的 2D 平面(纸面)具有正常单位向量 n = 1 / sqrt(3) *(1,1,1)。我们需要在 n 定义的 2D 平面中找到 2D 基础。由于位于我们的 2D 平面中的任何两个线性独立的矢量将形成这样的基础,所以这里是无限数量的这种基础。从问题的几何形状出发,为简单起见,我们强加两个附加条件:第一,基础应该是正交的;第二,应该在视觉上吸引人(虽然,这在某种程度上是一种主观条件)。通过设置 e1&#39;可以很容易地看出,这种基础在引导系统中平凡地形成。 =(1,0)&#39; = x&#39; -axis(水平,从左到右的正方向)和 e2&#39; =(0,1)&#39; = y&#39; -axis(从下到上的垂直,正方向)。

    现在让我们在 {e1..3} 中找到 {e1&#39;,e2&#39;} 2D 基础strong> 3D 基础。

    1. 我们将 e1&#39; e2&#39; 表示为 e1&#34; e2&# 34; 在原始基础上。注意到在我们的情况下 e1&#34; 没有 e3 - 组件( z - 组件),并使用 n dot e1&#34; = 0 ,我们得到 e1&#39; =(1,0)&#39; - &GT; E1&#34; {e1..3} 基础上的=( - 1 / sqrt(2),1 / sqrt(2),0)。在这里, dot 表示点积。
    2. 然后 e2&#34; = n 交叉 e1&#34; =( - 1 / sqrt(6), - 1 / sqrt(6),2 / sqrt(6))。在这里, 交叉 表示交叉产品。
    3. n = 1 / sqrt(3)<定义的 2D 平面的 2x3 投影矩阵 P < / em> *(1,1,1)由:

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

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

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

      1. n 与我们的 2D 平面正交,因此不应该投影。实际上, P * n = P *(1,1,1)= 0
      2. e1 e2 e3 应转换为 {e1..2&#39;} ,即 P 矩阵中的对应列。的确, P * e1 = P *(1,0,0)=( - 1 / sqrt(2), - 1 / sqrt(6))等等。

        最终确定问题。我们现在为任意选择的 2D 平面构建了从 3D 2D 的投影矩阵 P 。我们现在可以将先前通过旋转矩阵 R 旋转的任何矢量投影到此平面上。例如,旋转原始基础 {R * e1,R * e2,R * e3} 。此外,我们可以乘以给定的 P R 来获得旋转投影变换矩阵 PR = P * R

        P.S。 C ++实现留作家庭作业;)。

答案 1 :(得分: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)和中心(0,0,0)乘以最终矩阵,仅使用x,y坐标。

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

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