2017-04-12 1084 views
1

我正在研究涉及Aruco標記和opencv的項目。 我在項目進展中相當遙遠。我可以讀取旋轉矢量,並使用opencv中的rodrigues()將它們轉換爲rodrigues矩陣。旋轉矩陣與歐拉角與opencv

這是一個Rodrigues的矩陣I得到的一個例子:

[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; 
} 

如果我使用rodrigues矩陣,我給出了一個例子,我得到了下面的歐拉角。

[0; 90; -180]

但我想獲得以下內容。

[-180; 0; 90]

當是使用此工具http://danceswithcode.net/engineeringnotes/rotations_in_3d/demo3D/rotations_in_3d_tool.html

可以看到,[0; 90; -180]不匹配rodrigues矩陣,但[-180; 0; 90]。 (我知道這個工具與ZYX座標一起工作的事實)

所以問題是我得到正確的值,但以錯誤的順序。

另一個問題是,情況並非總是如此。 例如rodrigues矩陣:

[1,0,0;

0,-1,0;

0,0,-1]

爲我提供了正確的歐拉角度。

如果有人知道問題的解決方案,或者可以向我提供一個解釋rot2euler函數如何正確工作的解釋。它將受到高度讚賞。

親切的問候

布倫特Convens

+1

兩個不同的euler旋轉可以表示相同的旋轉。使用逆轉換得到3x3矩陣 – hiroki

+0

似乎你是在奇點的情況下據我所知,使用旋轉矩陣來表示90或180度的角度是不方便的(如果它們是正的,負面的),因爲你有奇點的風險,看起來公式是錯誤的...... [看看這篇論文](http://web.mit.edu/2.05/www/Handout/HO 2.PDF) – marcoresk

回答

1

並非專用OpenCV的,但你可以寫這樣的事情:

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的源代碼文件({} OPENCV_INSTALLATION_DIR /apps/interactive-calibration/rotationConverters.cpp)的

這在我看來,OpenCV的是給你YZX

(類似於在上面的代碼,它所呈現的)爲什麼我說我不知道​​,因爲我剛纔看了一下簡歷的源代碼::羅德里格斯和它似乎並沒有稱之爲我上面顯示的這段代碼。 Rodrigues函數將數學編碼到它中(我認爲可以通過取2個旋轉矩陣並乘以它們作爲-R = Ry * Rz * Rx來檢查,然後查看代碼中存在acos(R(2,0)) or asin(R(0,2)或因爲「R」中的一個元素通常是一個cos()或正弦,它將給出一個解決方案,以找出哪個角度被找到。