C++ 罗德里格斯到欧拉角,反之亦然
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12933284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rodrigues into Eulerangles and vice versa
提问by user1651460
I am useing solvePnP and i am getting a translation vector. Now i need to compare some euler angles with those results from solvePnP. And i want/need to transfer the euler angles into "rodrigues";
我正在使用 solvePnP 并且我得到了一个翻译向量。现在我需要将一些欧拉角与来自 solvePnP 的结果进行比较。我想/需要将欧拉角转换为“罗德里格斯”;
Is the translation vector from solvePnP equal to euler angles. Is the translation matrix the only thing what has to do with Rodrigues? or are there special rodrigues angles which are totaly different to the 3 euler angles? How is the math between both? Is there an OpenCV function which i couldn't find?
来自solvePnP 的平移向量是否等于欧拉角。翻译矩阵是唯一与 Rodrigues 有关的东西吗?或者是否有与 3 个欧拉角完全不同的特殊罗德里格角?两者之间的数学如何?是否有我找不到的 OpenCV 函数?
回答by dunadar
First, forget about translationvector, because it is not related with rotation: translation moves things around, rotation changes their orientation.
首先,忘记平移向量,因为它与旋转无关:平移移动物体,旋转改变它们的方向。
Rodrigues parameters are also called axis-angle rotation. They are formed by 4 numbers [theta, x, y, z]
, which means that you have to rotate an angle "theta" around the axis described by unit vector v=[x, y, z]
.
Looking at cv::Rodriguesfunction reference, it seems that OpenCV uses a "compact" representation of Rodrigues notation as vector with 3 elements rod2=[a, b, c]
, where:
罗德里格斯参数也称为轴角旋转。它们由 4 个数字组成[theta, x, y, z]
,这意味着您必须围绕单位向量描述的轴旋转角度“theta” v=[x, y, z]
。查看cv::Rodrigues函数参考,似乎 OpenCV 使用 Rodrigues 符号的“紧凑”表示作为具有 3 个元素的向量rod2=[a, b, c]
,其中:
- Angle to rotate
theta
is the module of input vectortheta = sqrt(a^2 + b^2 + c^2)
- Rotation axis
v
is the normalized input vector:v = rod2/theta = [a/theta, b/theta, c/theta]
- 旋转的角度
theta
是输入向量的模theta = sqrt(a^2 + b^2 + c^2)
- 旋转轴
v
是归一化的输入向量:v = rod2/theta = [a/theta, b/theta, c/theta]
So, Rodrigues vector from solvePnP is not even slightly related with Euler anglesnotation, which represent three consecutive rotations around a combination of X, Y and Z axes.
因此,来自solvePnP 的罗德里格斯向量与欧拉角表示法甚至没有一点关系,欧拉角表示围绕X、Y 和Z 轴的组合进行三个连续旋转。
How to compare both rotations? This is a good question. Both Euler- and Rodrigues- representations have singularities and other problems. For instance, if you compare two Euler terns, or two Rodrigues parameters, they can look completely different but actually represent almost the same rotation. If you just need to check if both rotations are the same (or approx.), you can follow the next approach:
如何比较两种旋转?这是一个很好的问题。Euler 和 Rodrigues 表示都有奇点和其他问题。例如,如果您比较两个 Euler terns 或两个 Rodrigues 参数,它们可能看起来完全不同,但实际上代表几乎相同的旋转。如果您只需要检查两个旋转是否相同(或近似),您可以按照下一个方法:
- Transform both rotations to matrix notation (quaternions are also valid)
- OpenCV Rodrigues vector can be transformed to matrix using cv::Rodriguesfunction
- For transforming Euler to matrix, I suggest you to take a look to conversions sectionof euclideanspace.com
- "Subtract" one rotation from the other, that is concatenating one with the inverse of the other
- Using rotation matrices, multiply one by the transpose (inverse rotation) of the other one. Null rotation is the identity matrix.
- Using quaternions, multiply one by the complex conjugate of the other (negate the three last components).
- Check if the result is close to a null rotation:
- Null rotation matrix is the identity.
- Null quaternion has a 1 or a -1 in the first component
- 将两个旋转转换为矩阵表示法(四元数也有效)
- 可以使用cv::Rodrigues函数将 OpenCV Rodrigues 向量转换为矩阵
- 要将欧拉转换为矩阵,我建议您查看euclideanspace.com 的转换部分
- 从另一个“减去”一个旋转,即将一个旋转与另一个旋转连接
- 使用旋转矩阵,将一个矩阵乘以另一个矩阵的转置(逆旋转)。零旋转是单位矩阵。
- 使用四元数,将一个乘以另一个的复共轭(否定最后三个分量)。
- 检查结果是否接近空旋转:
- 空旋转矩阵是身份。
- 空四元数在第一个分量中具有 1 或 -1
回答by Fraser Harris
Adding to @dunadar's excellent answer:
添加到@dunadar 的优秀答案中:
Rodrigues
converts rvec
into the rotation matrix R (and vice versa). You can directly use R in the same way you would use a rotation matrix constructed from Euler angles by taking the dot product with the (translation) vector you are rotating: v_rotate = R*v
Rodrigues
转换rvec
为旋转矩阵 R(反之亦然)。您可以像使用由欧拉角构造的旋转矩阵一样直接使用 R,方法是将点积与您正在旋转的(平移)向量进行计算:v_rotate = R*v
You canconvert from a Rodrigues rotation matrix into Euler angles, but there are multiple solutions. The reason is that the order of your Euler rotations (pitch, yaw, roll) matters, so there is more than one way to represent a Rodrigues rotation. See: http://www.staff.city.ac.uk/~sbbh653/publications/euler.pdf
您可以将 Rodrigues 旋转矩阵转换为 Euler 角,但有多种解决方案。原因是欧拉旋转的顺序(俯仰、偏航、滚动)很重要,因此有不止一种方法可以表示罗德里格斯旋转。请参阅:http: //www.staff.city.ac.uk/~sbbh653/publications/euler.pdf
回答by Jorma Rebane
Adding a more concrete answer to supplement the other answers here. If you desire a direction vector instead of Euler angles, the process can indeed be simplified with a matrix multiplication, here's a quick solution:
添加更具体的答案以补充此处的其他答案。如果你想要一个方向向量而不是欧拉角,这个过程确实可以通过矩阵乘法来简化,这是一个快速的解决方案:
// 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) };
}
If you are using this for head pose estimation, ensure the Rodrigues 1x3 rotation is formed properly around {0,0,0} or you might get odd results.
如果您将其用于头部姿势估计,请确保 Rodrigues 1x3 旋转在 {0,0,0} 附近正确形成,否则您可能会得到奇怪的结果。