将OpenCV的旋转和平移向量转换为XYZ旋转和XYZ位置

18
有一些谷歌搜索结果和stackoverflow帖子似乎回答了这个问题,但简单事实是我无法理解它们。无论我读多少遍,我都无法理解四元数、欧拉角、罗德里格斯变换以及所有这些内容。
有人能向我解释就像我12岁一样,如何从OpenCV的solvePnP()方法返回的旋转和平移向量转换为可以插入3D图形应用程序的xyz位置和xyz旋转值吗?
这是为一个c ++增强现实应用程序。我已经完成了OpenCV部分的跟踪标记板和发送旋转和平移向量到图形程序,但我不知道如何使用这些信息来定位我的3D对象。
我真的想理解这背后的数学,并感激任何耐心解释这里的理论。但我也会接受一个指针,让我可以复制/粘贴代码并在另一天学习该理论。事实上,像这样看到具体的代码并向后工作来学习这样的东西,我好像学得更快。
编辑: 就像这个... 显然应该引导我走向正确的方向,但对于我所知道的所有东西而言,它可能是时间机器的计划。我想到我可能要求补习高中数学,但这不可能是第一次。
编辑: 这里有一个从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>

这个问题应该移动到http://math.stackexchange.com/。 - karlphillip
13
看这个问题,karlphillip,如果我在 math.stackexchange 上问这个问题,我会得到一堆我不理解的回答。 我唯一能理解的希望是看到如何用代码实现它。 然后我可以理解数学部分。 这只是我的大脑运作方式。 - John
3个回答

19

起初,我对OpenCV使用的格式一无所知。因此需要先进行一些研究。看着solvePnP的文档, 它似乎返回了一个矩阵。(在文档的早期版本中提到的Rodrigues2函数现在似乎被称为Rodrigues.)

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

所以你的输入是角度轴表示法。你可以将其解释为关于xyz轴的同时旋转。因此,如果你所说的“XYZ旋转”是指同时旋转,那么你已经到达了目的地。然而,如果你的意思是先绕x轴旋转,然后再绕y轴旋转,最后再绕z轴旋转的一些组合方式,那么你处于一个奇怪的设置中,可能应该确保你正在使用正确的API。
如果您想要欧拉角,那么称它们为“XYZ旋转”有些误导性。维基百科文章三维旋转公式列出了各种格式以及如何在它们之间进行转换。特别是,它提供了从轴和角度到矩阵再到欧拉角的转换公式。请确保使用正确的表示法来匹配您的图形输出设备。或者,如果您有选择,尝试直接使用旋转矩阵表示法,因为这应该是最容易理解和使用的。

这太棒了...感谢你所做的研究。我确实想要同时旋转,尽管我从未知道它被称为这个名字...但我不明白我如何“已经到达那里”。我将发布从solvePnP()方法返回的数据作为我的原始问题的编辑,以证明我还没有到达XYZ旋转和XYZ位置。 - John
@John,我看到三个数字,没有任何理由说明它们不能描述同时旋转。所有数字都在[-π, π]范围内,向量的范数也是如此。你在哪里发现错误?你的图形应用程序是什么? - MvG
@MvG... 好的,这很有趣。我曾认为这些数字经常超出弧度范围,但仔细观察输出的数据,我发现大于 pi 或小于负 pi 的数字具有负指数。也许我把这一切都想得太复杂了。不过,你关于同时旋转的解释真的很有帮助。我离不再对这个东西感到恐惧更近了 :-) - John
首先提到的文档链接已经失效了,我无法在网上找到任何类似文档的内容。最接近的是这个链接 - Divij Sehgal
@DivijSehgal:我更新了OpenCV文档的链接。 - MvG

2
  1. 将您的3D向量扩展为齐次坐标(4D)。这意味着一个具有组件(X,Y,Z,1)的4D向量。

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

  3. 使用变换矩阵乘以您的坐标向量。

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

它提供了一个在2D坐标中提出的示例,我相信您已经了解了足够的思路来扩展到3D。


非常感谢你...你让我的大脑受伤了,但我认为我可能(只是)能够理解你说的一些内容 :) - John

2
我的猜测是OpenCv已经返回了XYZ旋转。用左手(左手定则)握拳,竖起拇指(z轴),伸出食指直前(x轴),然后将中指向右伸展(y轴)。
任何特定的方向向量可以由最多三个旋转给出。重要的是要意识到你可以得到等效的旋转。例如,围绕z轴旋转,使你的食指指向右边。一个等效的旋转将是Y、X,然后再次是Y,而不涉及Z轴。
然而,当你使用完整的旋转矩阵(3x3)时,你不必担心这些约定,因为它们都在矩阵中合并在一起。这就是你链接的论文所讨论的内容,而不是时间旅行,这很幸运,因为大多数数学专业的人都能够进行时间旅行,从而毁灭人类。
然而,旋转向量通常是指物体必须绕哪个空间向量旋转。

你给手指分配方向的方式很不寻常。通常情况下,拇指=x,食指=y,中指=z,就像你所引用的文章中所描述的那样。但这并不影响你帖子的本质。 - MvG
我知道...我来自航空航天背景,Z总是指向天空的高度,但我的游戏朋友不同意。 - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接