C++ 罗德里格斯成了尤兰格,反之亦然
我正在使用solvePnP,我得到了一个翻译向量。 现在我需要将一些欧拉角与solvePnP的结果进行比较。 我想/需要把欧拉角转换成“罗德里格斯” 来自solvePnP的平移向量等于euler角。 翻译矩阵是唯一与罗德里格斯有关的东西吗? 或者是否存在与3个欧拉角完全不同的特殊罗德里格斯角? 两者之间的数学关系如何?C++ 罗德里格斯成了尤兰格,反之亦然,c++,opencv,rotation,C++,Opencv,Rotation,我正在使用solvePnP,我得到了一个翻译向量。 现在我需要将一些欧拉角与solvePnP的结果进行比较。 我想/需要把欧拉角转换成“罗德里格斯” 来自solvePnP的平移向量等于euler角。 翻译矩阵是唯一与罗德里格斯有关的东西吗? 或者是否存在与3个欧拉角完全不同的特殊罗德里格斯角? 两者之间的数学关系如何? 是否有我找不到的OpenCV函数 首先,忘记平移向量,因为它与旋转无关:平移移动物体,旋转改变它们的方向 罗德里格斯参数也称为。它们由4个数字组成,这意味着你必须围绕单位向量v=
是否有我找不到的OpenCV函数 首先,忘记平移向量,因为它与旋转无关:平移移动物体,旋转改变它们的方向 罗德里格斯参数也称为。它们由4个数字组成,这意味着你必须围绕单位向量v=[x,y,z]描述的轴旋转一个角度“θ”。 从函数引用来看,OpenCV似乎使用罗德里格斯符号的“紧凑”表示法作为向量,包含3个元素
rod2=[a,b,c]
,其中:
- 旋转角度θ是输入向量θ=sqrt(a^2+b^2+c^2)的模
- 旋转轴
是标准化的输入向量:v
v=rod2/theta=[a/theta,b/theta,c/theta]
- OpenCV罗德里格斯矢量可以使用函数转换为矩阵
- 要将Euler转换为矩阵,我建议您查看euclideanspace.com的
- 使用旋转矩阵,将一个矩阵乘以另一个矩阵的转置(逆旋转)。零旋转是单位矩阵
- 使用四元数,将一个数乘以另一个数的复共轭数(最后三个分量求反)
- 零旋转矩阵是恒等式
- 空四元数在第一个分量中有1或-1
除了@dunadar的优秀答案之外:
Rodrigues
将rvec
转换为旋转矩阵R(反之亦然)。可以直接使用R,就像使用由Euler角构造的旋转矩阵一样,通过将点积与正在旋转的(平移)向量相结合:v_rotate=R*v
可以将Rodrigues旋转矩阵转换为Euler角度,但有多种解决方案。原因是欧拉旋转的顺序(俯仰、偏航、横摇)很重要,所以有多种方式来表示罗德里格斯旋转。请参阅:在此处添加更具体的答案以补充其他答案。如果你想要一个方向向量而不是欧拉角,这个过程确实可以通过矩阵乘法来简化,这里有一个快速的解决方案:
// 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) };
}
//输出是OpenGL坐标系中的方向向量:
//+X正好在屏幕上,+Y向上,+Z进入屏幕
静态矢量3到方向矢量GL(const Mat&Rodrigues13X3)无例外
{
垫旋转3x3;
cv::罗德里格斯(罗德里格斯13x3,旋转3x3);
//在CV坐标系中的屏幕外方向,因为我们关心
//关于面向我们的对象-您可以将其更改为任何内容
//OpenCV coordsys:+X显示在屏幕上,+Y显示在屏幕上,
//+Z进入屏幕
Vec3d轴{0,0,-1};
垫方向=旋转3x3*垫(轴,假);
//规格化为单位向量
双dirX=方向。在(0);
双方向=方向。在(1);
双dirZ=方向,在(2)处;
双透镜=sqrt(dirX*dirX+dirY*dirY+dirZ*dirZ);
dirX/=len;
dirY/=len;
dirZ/=len;
//从OpenCV到OpenGL三维坐标系的转换
返回{float(dirX),float(-dirY),float(dirZ)};
}
如果您将其用于头部姿势估计,请确保罗德里格斯1x3旋转在{0,0,0}周围正确形成,否则您可能会得到奇怪的结果。这是实现R->euler(用小数字处理精度问题)的更好参考。你救了我一天!!!theta=sqrt(a^2+b^2+c^2)和v=rod2/theta=[a/theta,b/theta,c/theta]正是我想要的函数。。。谢谢