【问题标题】:Converting OpenCV rotation and translation vectors to XYZ rotation and XYZ position将 OpenCV 旋转和平移向量转换为 XYZ 旋转和 XYZ 位置
【发布时间】:2012-11-29 04:26:57
【问题描述】:

似乎有 Google 结果和 stackoverflow 帖子可以回答这个问题,但简单的事实是我无法理解它们。无论我读了多少书,我都无法理解四元数、欧拉角和罗德里格斯变换等等。

有人愿意像我 12 岁那样向我解释如何从 OpenCV 的 solvePnP() 方法返回的旋转和平移向量中获取我可以插入 3d 图形应用程序的 xyz 位置和 xyz 旋转值吗?

这是用于 C++ 中的增强现实应用程序。我已经启动并运行了 OpenCV 部分,跟踪标记板并将旋转和平移矢量发送到图形程序,但我不知道如何使用这些信息来设置我的 3d 对象。

我真的很想了解这背后的数学原理,并会感谢您耐心地解释这里的理论。但我也会接受指向一些代码的指针,我可以在另一天复制/粘贴并学习理论。事实上,通过查看具体代码并回归理论,我似乎可以更快地学习这样的东西。

编辑: 就像this... 显然应该为我指明正确的方向,但据我所知,它也可能是时间机器的计划。我突然想到我可能会要求补习高中数学,但这不可能是第一次。

编辑: 这是从solvePnP()返回的旋转向量和平移向量的示例...转换为XML以用于图形应用程序。请注意,我看到的每一个都包含三行一列。

<Tvec type_id="opencv-matrix">
  <rows>3</rows>
  <cols>1</cols>
  <dt>f</dt>
  <data>
    -2.50094433e+01 -6.59909010e+00 1.07882790e+02
  </data>
</Tvec>
<Rvec type_id="opencv-matrix">
  <rows>3</rows>
  <cols>1</cols>
  <dt>f</dt>
  <data>
    -1.92100227e+00 -2.11300254e-01 2.80715879e-02
  </data>
</Rvec>

【问题讨论】:

  • 这个问题应该移到math.stackexchange.com
  • 看这里,karlphillip,如果我在 math.stackexchange 中问这个问题,我会得到充满我不明白的东西的回答。我理解这一点的唯一希望是看看如何在代码中做到这一点。然后我可以理解数学位。这就是我被分配的大脑的工作方式。

标签: c++ opencv rotation rotational-matrices


【解决方案1】:

最初我对 OpenCV 使用什么格式一无所知。所以先研究一下。看着the documentation for solvePnP,它似乎返回了一个矩阵。 (文档appears 中旧版本中提到的Rodrigues2 函数现在被称为Rodrigues。)

那里的描述表明您可以期望一个具有单行或单列的矩阵。该向量的方向表示旋转轴,而向量的长度(或“范数”)表示角度。

所以你的输入是angle-axis representation。您可以将其解释为关于 xyz 轴的simultaneous rotation。因此,如果“XYZ 旋转”是指同时旋转,那么您已经在那里了。但是,如果您的意思是某种组合,它首先围绕 x 轴旋转,then 围绕 y 轴旋转,然后 then 关于 z 轴,您处于一个奇怪的设置中,可能应该确保您使用的是正确的 API。

如果你追求的是Euler angles,那么称它们为“XYZ 旋转”有点误导。维基百科文章Rotation formalisms in three dimensions 列出了各种格式,以及如何在它们之间进行转换。特别是,它确实提供了从轴和角度转换为矩阵,然后从那里转换为欧拉角的公式。

确保您使用正确的表示来匹配您的图形输出机器。或者,如果您有选择,请尝试直接使用 rotation marix 表示,因为它应该最容易理解和使用。

【讨论】:

  • 这太棒了...感谢您所做的研究。我肯定在同时轮换之后,虽然我从来不知道它被称为......但我不明白我是如何“已经在那里”的。我将从 solvePnP() 方法返回的数据作为对我原始问题的编辑发布,以证明我还没有达到 XYZ 旋转和 XYZ 位置。
  • @John,我看到三个数字,完全没有理由让它们描述同时旋转。所有数字都在 [-π, π] 范围内,向量的范数也是如此。您究竟在哪里检测到错误?你的图形应用程序是什么?
  • @MvG... 好吧,这很有趣。我认为这些数字通常在弧度范围之外很好,但更仔细地观察被吐出的数据,我发现高于 pi 或低于负 pi 的数字具有负指数。也许我让这一切变得比实际更困难。不过,您对同时旋转的解释确实很有帮助。我更接近于不被这些东西吓到:-)
  • 最初提到的文档链接不再将我带到任何地方。而且我在网络上的任何地方都找不到类似文档的东西。我找到的最接近的是this link
  • @DivijSehgal:我更新了 OpenCV 文档的链接。
【解决方案2】:
  1. 将 3D 矢量扩展到齐次坐标 (4D)。这意味着一个具有分量 (X, Y, Z, 1) 的 4D 向量

  2. 根据您的旋转和平移参数创建一个 4x4 变换矩阵。它被称为仿射变换。关于旋转矩阵的文章,您走在了正确的轨道上。

  3. 将坐标向量与变换矩阵相乘。

查看此维基百科部分:http://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations

它有一个在 2d 坐标中构成的示例,我相信你已经足够了解这个想法,可以扩展到 3d。

【讨论】:

  • 非常感谢……你让我的大脑受伤了,但我想我可能(只是)能够理解你所说的一些内容 :)
【解决方案3】:

我的猜测是 OpenCv 已经返回 XYZ 旋转。拿起你的左手 (left hand rule) 并握紧拳头。竖起拇指(z 轴),将食指伸直向前(x 轴),然后将中指向右伸(y 轴)。

任何特定的方向向量最多可以通过三个旋转来给出。重要的是要意识到您可以获得等效的旋转。例如,围绕 z 轴旋转,使您的索引指向您的右侧。等效旋转是 Y,X,然后是 Y,而不涉及 Z 轴。

但是,当您使用完整的旋转矩阵 (3x3) 时,您不必担心这些约定,因为它们都在矩阵中合并在一起。这是您链接的论文的内容,而不是时间旅行,这是幸运的,因为大多数数学专业的学生都可以进行时间旅行,从而毁灭人类。

然而,旋转矢量通常是指您的对象必须围绕空间中的哪个矢量旋转。

【讨论】:

  • 你对手指的方向分配是——不常见的。通常你有 thumb=x、index=y 和 middle=z。如您引用的文章中所述。但这并不影响您帖子的本质。
  • 我知道...我来自航天背景,Z 总是指向天空的高度,但我的电子游戏朋友不同意。
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 2016-04-07
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 2013-05-23
  • 2013-12-06
  • 1970-01-01
相关资源
最近更新 更多