Ask Your Question
1

aruco markers rvec to quaternion and +-180 degrees flip

asked 2019-03-07 14:47:20 -0600

Maksat gravatar image

I am new to the OpenCV, C++, and general to coding. I somehow managed to get Euler's angles from rvec (with some major help). But I have a 180 degree flip in x (sometimes also z) axis. Also is it possible to get quaternion rotation from rvec or rotation matrix?

would appreciate a detailed answer as I am very new to this.

edit retag flag offensive close merge delete

Comments

1
sjhalayka gravatar imagesjhalayka ( 2019-03-07 15:15:26 -0600 )edit
1

I for one am also interested in an answer to this question.

sjhalayka gravatar imagesjhalayka ( 2019-03-07 20:12:35 -0600 )edit

Don't convert from Euler angles.

Instead convert from the rotation vector rvec or from the rotation matrix R to quaternion.

See: Maths - AxisAngle to Quaternion

Eduardo gravatar imageEduardo ( 2019-03-08 02:53:03 -0600 )edit
1

The pi radians flip on the x axis - could it be related to the camera coordinates u,v with v increasing toward the bottom of the camera image, but your coordinate system has y increasing in the other direction - this represents a pi radians flip around the x axis.

opalmirror gravatar imageopalmirror ( 2019-03-08 14:25:41 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
4

answered 2019-03-08 03:25:42 -0600

Eduardo gravatar image

See Maths - AxisAngle to Quaternion.

The conversion between axis-angle and quaternion is straightforward:

#include <iostream>
#include <Eigen/Geometry>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace Eigen;
using std::cout;
using std::endl;

Matx41d aa2quaternion(const Matx31d& aa)
{
    double angle = norm(aa);
    Matx31d axis(aa(0) / angle, aa(1) / angle, aa(2) / angle);
    double angle_2 = angle / 2;
    //qx, qy, qz, qw
    Matx41d q(axis(0) * sin(angle_2), axis(1) * sin(angle_2), axis(2) * sin(angle_2), cos(angle_2));
    return q;
}

int main()
{
    //Eigen
    Matrix3d R;
    R = AngleAxisd(0.25*M_PI, Vector3d::UnitX())
                   * AngleAxisd(0.5*M_PI,  Vector3d::UnitY())
                   * AngleAxisd(0.33*M_PI, Vector3d::UnitZ());

    cout << "Eigen R:\n" << R << endl;

    AngleAxisd aa;
    aa.fromRotationMatrix(R);
    cout << "Eigen axis-angle:\n" << aa.axis()*aa.angle() << endl;

    Matx33d R_cv;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            R_cv(i,j) = R(i,j);
        }
    }

    Quaterniond q(aa);
    cout << "Eigen quaternion: " << q.x() << ", " << q.y() << ", " << q.z() << "," << q.w() << endl;

    Matx31d aa_cv;
    Rodrigues(R_cv, aa_cv);
    cout << "OpenCV rvec: " << aa_cv.t() << endl;
    Matx41d q_cv = aa2quaternion(aa_cv);
    cout << "OpenCV quaternion: " << q_cv.t() << endl;

    return 0;
}

Output:

Eigen R:
 3.33067e-16 -1.66533e-16            1
    0.968583     -0.24869 -1.66533e-16
     0.24869     0.968583  3.33067e-16
Eigen axis-angle:
 1.3919
1.07967
 1.3919
Eigen quaternion: 0.558724, 0.433391, 0.558724,0.433391
OpenCV rvec: [1.391895819721201, 1.079665068873341, 1.391895819721201]
OpenCV quaternion: [0.5587239674393911, 0.4333907338750867, 0.558723967439391, 0.433390733875087]
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2019-03-07 14:47:20 -0600

Seen: 4,124 times

Last updated: Mar 08 '19