2017-04-12 10 views
1

私はArucoマーカーとopencvを含むプロジェクトに取り組んでいます。 私はプロジェクトの進歩にかなり遠いです。私は回転ベクトルを読んで、それらをopencvのrodrigues()を使ってrodrigues行列に変換することができます。opencvとオイラー角の回転行列

これは私が取得ロドリゲス行列の例である:

[0,1,0。

1,0,0;

0,0、-1]

私は次のコードを使用します。

Mat m33(3, 3, CV_64F); 
Mat measured_eulers(3, 1, CV_64F); 
Rodrigues(rotationVectors, m33); 

measured_eulers = rot2euler(m33); 

Degree_euler = measured_eulers * 180/CV_PI; 

私は、予め定められたrot2eulerを使用して、rodrigues行列をオイラー角に変換します。 そして、受け取ったラジアンを度に変換します。

rot2eulerは次のようになります。

Mat rot2euler(const Mat & rotationMatrix) 
{ 
    Mat euler(3, 1, CV_64F); 

    double m00 = rotationMatrix.at<double>(0, 0); 
    double m02 = rotationMatrix.at<double>(0, 2); 
    double m10 = rotationMatrix.at<double>(1, 0); 
    double m11 = rotationMatrix.at<double>(1, 1); 
    double m12 = rotationMatrix.at<double>(1, 2); 
    double m20 = rotationMatrix.at<double>(2, 0); 
    double m22 = rotationMatrix.at<double>(2, 2); 

    double x, y, z; 

    // Assuming the angles are in radians. 
    if (m10 > 0.998) { // singularity at north pole 
     x = 0; 
     y = CV_PI/2; 
     z = atan2(m02, m22); 
    } 
    else if (m10 < -0.998) { // singularity at south pole 
     x = 0; 
     y = -CV_PI/2; 
     z = atan2(m02, m22); 
    } 
    else 
    { 
     x = atan2(-m12, m11); 
     y = asin(m10); 
     z = atan2(-m20, m00); 
    } 

    euler.at<double>(0) = x; 
    euler.at<double>(1) = y; 
    euler.at<double>(2) = z; 

    return euler; 
} 

ロッドロッドを使用すると、私は例として以下のオイラー角を得ます。

[0; 90; -180]

しかし、私は次のようになると思います。

[-180; 0; 90]

http://danceswithcode.net/engineeringnotes/rotations_in_3d/demo3D/rotations_in_3d_tool.html

このツールを使用しているときに、その[0を見ることができますが、 90; -180]はロッドロッドと一致しないが[-180; 0; 90]があります。 (私は、ツールがZYX座標で動作するという事実を認識しています)

問題は正しい値ですが、間違った順序です。

もう1つの問題は、必ずしもそうではないということです。 例えばロッド(rodrigues)マトリックス:

[1,0,0;

0、-1,0;

0,0、-1]

正確なオイラー角を提供します。

誰かが問題の解決方法を知っている場合、またはrot2euler関数がどのように正確に機能するか説明することができます。それは高く評価されます。

OpenCVのに親切によろしく

ブレントConvensが

+1

2つの異なるオイラー回転が同じ回転を表すことがあります。逆変換を使って3x3の行列を得る – hiroki

+0

特異点があると思われるが、私が知る限り、90度や180度のような角度に回転行列を使うのは便利ではない。あなたが特異点の危険にさらされているので、それは間違っています... [この論文を見てください](http://web.mit.edu/2.05/www/Handout/HO 2.PDF) – marcoresk

答えて

1

固有のものではありませんが、あなたはこのような何か書くことができます:ここで

cosine_for_pitch = math.sqrt(pose_mat[0][0] ** 2 + pose_mat[1][0] ** 2) 
is_singular = cosine_for_pitch < 10**-6 
if not is_singular: 
    yaw = math.atan2(pose_mat[1][0], pose_mat[0][0]) 
    pitch = math.atan2(-pose_mat[2][0], cosine_for_pitch) 
    roll = math.atan2(pose_mat[2][1], pose_mat[2][2]) 
else: 
    yaw = math.atan2(-pose_mat[1][2], pose_mat[1][1]) 
    pitch = math.atan2(-pose_mat[2][0], cosine_for_pitch) 
    roll = 0 

を、あなたはより多くを探ることができます:

https://www.learnopencv.com/rotation-matrix-to-euler-angles/ http://www.staff.city.ac.uk/~sbbh653/publications/euler.pdf

0

私はかなり遅いと思うが、それにもかかわらず私はそれに答えるだろう。 いけないつまり、私は100%確実ではないんだけど、これはOpenCVの3.3

enter image description hereのソースコードからのファイルの1 ({} OPENCV_INSTALLATION_DIR /apps/interactive-calibration/rotationConverters.cpp)で、この上で私を引用します

私が::私はちょうどCVのソースコードを見ているので、私はわからないと述べたのはなぜ

(上記のコードに示されているものと同様)OpenCVのはあなたYZXを与えているように私には思えますロドリゲスと私は上記のコードのこの部分を呼び出すことはありません。ロドリゲス関数には数学的なコードが含まれています(2つの回転行列を-R = Ry * Rz * Rxとして掛け合わせた後、acos(R(2,0)) or asin(R(0,2)または「R」の要素の1つは、通常、cos()または正弦であり、どの角度が見つかっているかについての解を与えるためです。

関連する問題