【问题标题】:Drawing Euler Angles rotational model on a 2d image在二维图像上绘制欧拉角旋转模型
【发布时间】:2013-08-18 21:45:12
【问题描述】:

我目前正在尝试在 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

【问题讨论】:

  • 您是在寻找正交投影还是透视投影?
  • 正交。我正在寻找一种将欧拉角的 3d 表示放置到 2d 平面上的简单方法。谢谢,我更新了问题

标签: c++ opencv euler-angles


【解决方案1】:

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

如果我理解正确,您想旋转 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 列是第 i 列的投影3D 基础向量 ei{e1..2'} 基础上。

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

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

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

  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}基础上。这里,dot表示点-产品。
  2. 然后 e2" = n cross e1" = ( -1/sqrt(6), -1/sqrt(6), 2/sqrt(6) ) .这里,cross 表示叉积。

2x3 投影矩阵 P 用于由 n = 1/sqrt(3) 定义的 2D 平面 * ( 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'},即 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}。此外,我们可以乘给定 P R 得到一个旋转-投影变换矩阵 em> PR = P * R.

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

【讨论】:

  • 谢谢,我相信这是我开始所需要的。我将很快实现这一点,并用我的实现来更新我的问题。谢谢彼得!
  • 注意:我忘了说我需要缩放一点,这取决于我想要绘制 x、y、z 轴的大小,我还需要翻译它,这也不算什么。只是一些不断的乘法和加法。稍后我会在输入代码时根据我的附加要求更新答案。
  • @jluzwick 欢迎您。翻译将只是添加一个向量(3D2D 来翻译相应的原点(因为它是正交投影,而不是透视投影),具体取决于您要如何处理它)。如果缩放是各向同性的,那么您只需随时乘以一个标量。如果它是各向异性的,那么您必须在初始 3D 向量上使用相应的对角矩阵进行操作(但我认为您并不是要引入各向异性)。这是一个有趣的问题。期待看到它最终的样子。
【解决方案2】:

旋转矩阵会很容易显示,

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

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

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 坐标。

center 应该始终转换为 0,0,0

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 2021-09-17
    • 2021-01-01
    • 1970-01-01
    相关资源
    最近更新 更多