opencv Vec3d to Eigen::Quaternion, euler flipping on results



我正在使用opencv::solvePnP返回相机姿势。我运行 PnP,它返回 rvec 和 tvec 值。(旋转矢量和位置)。

然后,我运行此函数将值转换为相机姿势:

void GetCameraPoseEigen(cv::Vec3d tvecV, cv::Vec3d rvecV, Eigen::Vector3d &Translate, Eigen::Quaterniond &quats)
{
Mat R;
Mat tvec, rvec;
tvec = DoubleMatFromVec3b(tvecV);
rvec = DoubleMatFromVec3b(rvecV);
cv::Rodrigues(rvec, R); // R is 3x3
R = R.t();                 // rotation of inverse
tvec = -R*tvec;           // translation of inverse
Eigen::Matrix3d mat;
cv2eigen(R, mat);
Eigen::Quaterniond EigenQuat(mat);
quats = EigenQuat;

double x_t = tvec.at<double>(0, 0);
double y_t = tvec.at<double>(1, 0);
double z_t = tvec.at<double>(2, 0);
Translate.x() = x_t * 10;
Translate.y() = y_t * 10;
Translate.z() = z_t * 10;   
}

这有效,但在某些旋转角度下,转换后的旋转值会在正值和负值之间随机翻转。然而,源rvecV值没有。我认为这意味着我的转换出了问题。如何从返回的 PnP 返回 cv::Vec3d 中获得稳定的四元数?

编辑:这似乎是四元数翻转,如下所述:

四元数是非常相似的旋转的翻转符号?

基于此,我尝试添加:

if(quat.w() < 0)
{
quat = quat.Inverse();
} 

但我看到了同样的翻转。

quat-quat都表示相同的旋转。您可以通过取一个单位四元数,将其转换为旋转矩阵,然后执行

quat.coeffs() = -quat.coeffs();

并将其转换为旋转矩阵。 如果出于某种原因您总是想要一个正w值,如果w为负,则否定所有系数。

符号应该无关紧要...

。旋转方面,只要 4D 四元数的所有四个场都被翻转。这里还有更多解释: 四元数到欧拉XYZ,如何区分负四元数和正四元数

可以这样想: 两个翻转的角度/轴意味着同样的事情 并注意顺时针到逆时针的过渡,就像在镜像中一样。

可能有惯例使quat.w()quat[0]组件保持正数,并相应地将其他组件更改为相反的组件。假设w = cos(angle/2)然后设置w > 0只是意味着:我希望angle(-pi, pi)范围内。使-270度旋转变为+90度旋转。

quat.Inverse()可能不是你想要的,因为这会在相反的方向上产生旋转。那是-quat != quat.Inverse().

另外:检查两个系统是否具有相同的惯用手性(手性)!测试旋转矩阵行列式是 +1 还是 -1。

(对于图像链接,我没有足够的声誉来嵌入它们)。

相关内容

  • 没有找到相关文章

最新更新