罗德里格斯到欧拉角,反之亦然

Posted

技术标签:

【中文标题】罗德里格斯到欧拉角,反之亦然【英文标题】:Rodrigues into Eulerangles and vice versa 【发布时间】:2012-10-07 15:35:56 【问题描述】:

我正在使用solvePnP,我得到了一个平移向量。 现在我需要将一些欧拉角与solvePnP的结果进行比较。 我想/需要将欧拉角转换为“罗德里格斯”;

solvePnP 的平移向量是否等于欧拉角。 翻译矩阵是唯一与罗德里格斯有关的东西吗? 还是有与 3 个欧拉角完全不同的特殊罗德里格斯角? 两者之间的数学如何? 有没有我找不到的 OpenCV 函数?

【问题讨论】:

【参考方案1】:

首先,忘记translation向量,因为它与rotation无关:平移移动物体,旋转改变它们的方向。

Rodrigues 参数也称为axis-angle rotation。它们由 4 个数字 [theta, x, y, z] 组成,这意味着您必须围绕单位矢量 v=[x, y, z] 描述的轴旋转一个角度“theta”。 查看cv::Rodrigues 函数参考,似乎OpenCV 使用罗德里格斯符号的“紧凑”表示作为具有3 个元素rod2=[a, b, c] 的向量,其中:

旋转角度theta是输入向量theta = sqrt(a^2 + b^2 + c^2)的模 旋转轴v是归一化的输入向量:v = rod2/theta = [a/theta, b/theta, c/theta]

因此,solvePnP 中的 Rodrigues 向量与 Euler angles 表示法没有一点关系,Euler angles表示围绕 X、Y 和 Z 轴组合的三个连续旋转。

如何比较两个旋转?这是一个很好的问题。 Euler 和 Rodrigues 表示都有奇点和其他问题。例如,如果您比较两个欧拉燕鸥或两个罗德里格斯参数,它们可能看起来完全不同,但实际上表示几乎相同的旋转。 如果您只需要检查两个旋转是否相同(或近似),您可以按照下一个方法:

    将两个旋转都转换为矩阵表示法(四元数也有效) OpenCV Rodrigues 向量可以使用cv::Rodrigues 函数转换为矩阵 欧拉转矩阵,建议你去euclideanspace.com的conversions section看看 “减去”一个旋转从另一个旋转,即将一个旋转与另一个旋转连接 使用旋转矩阵,将一个矩阵乘以另一个矩阵的转置(反向旋转)。空旋转是单位矩阵。 使用四元数,将一个乘以另一个的复共轭(取反最后三个分量)。 检查结果是否接近零旋转: 空旋转矩阵是恒等式。 空四元数在第一个组件中包含 1 或 -1

【讨论】:

你拯救了我的一天!!! theta = sqrt(a^2 + b^2 + c^2) 和 v = rod2/theta = [a/theta, b/theta, c/theta] 正是我正在寻找的函数......谢谢跨度> 【参考方案2】:

添加到@dunadar 的出色答案:

Rodriguesrvec 转换为旋转矩阵 R(反之亦然)。您可以直接使用 R,就像使用由欧拉角构造的旋转矩阵一样,通过将点积与您正在旋转的(平移)向量进行运算:v_rotate = R*v

可以将 Rodrigues 旋转矩阵转换为欧拉角,但有多种解决方案。原因是欧拉旋转的顺序(俯仰、偏航、滚动)很重要,因此有不止一种方法可以表示罗德里格斯旋转。见:http://www.staff.city.ac.uk/~sbbh653/publications/euler.pdf

【讨论】:

这是实现 R->euler 的更好参考(处理小数字的精度问题)。 d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2012/07/…【参考方案3】:

添加更具体的答案以补充此处的其他答案。如果你想要一个方向向量而不是欧拉角,这个过程确实可以通过矩阵乘法来简化,这里有一个快速的解决方案:

// The output is a direction vector in OpenGL coordinate system:
// +X is Right on the screen, +Y is Up, +Z is INTO the screen
static Vector3 ToDirectionVectorGL(const Mat& rodrigues1x3) noexcept

    Mat rotation3x3;
    cv::Rodrigues(rodrigues1x3, rotation3x3);

    // direction OUT of the screen in CV coordinate system, because we care
    // about objects facing towards us - you can change this to anything
    // OpenCV coordsys: +X is Right on the screen, +Y is Down on the screen,
    //                  +Z is INTO the screen
    Vec3d axis 0, 0, -1 ; 
    Mat direction = rotation3x3 * Mat(axis, false);

    // normalize to a unit vector
    double dirX = direction.at<double>(0);
    double dirY = direction.at<double>(1);
    double dirZ = direction.at<double>(2);
    double len = sqrt(dirX*dirX + dirY*dirY + dirZ*dirZ);
    dirX /= len;
    dirY /= len;
    dirZ /= len;
    // Convert from OpenCV to OpenGL 3D coordinate system
    return  float(dirX), float(-dirY), float(dirZ) ;

如果您将其用于头部姿势估计,请确保在 0,0,0 周围正确形成 Rodrigues 1x3 旋转,否则您可能会得到奇怪的结果。

【讨论】:

以上是关于罗德里格斯到欧拉角,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章

欧拉角到四元数然后四元数到欧拉角

我的OpenGL学习进阶之旅关于欧拉角旋转顺序旋转矩阵四元数等知识的整理

我的OpenGL学习进阶之旅关于欧拉角旋转顺序旋转矩阵四元数等知识的整理

3D图形:矩阵、欧拉角、四元数与方位的故事

VR-四元素、欧拉角转换条件

旋转矩阵到欧拉角