2012-05-28 57 views
11

我想要乘以2個四元數,它們存儲在一個cv :: Mat結構中。我希望函數儘可能高效。我到目前爲止有以下代碼:使用cv進行高效的C++四元數乘法:: Mat

/** Quaternion multiplication 
* 
*/ 
void multiplyQuaternion(const Mat& q1,const Mat& q2, Mat& q) 
{ 
    // First quaternion q1 (x1 y1 z1 r1) 
    const float x1=q1.at<float>(0); 
    const float y1=q1.at<float>(1); 
    const float z1=q1.at<float>(2); 
    const float r1=q1.at<float>(3); 

    // Second quaternion q2 (x2 y2 z2 r2) 
    const float x2=q2.at<float>(0); 
    const float y2=q2.at<float>(1); 
    const float z2=q2.at<float>(2); 
    const float r2=q2.at<float>(3); 


    q.at<float>(0)=x1*r2 + r1*x2 + y1*z2 - z1*y2; // x component 
    q.at<float>(1)=r1*y2 - x1*z2 + y1*r2 + z1*x2; // y component 
    q.at<float>(2)=r1*z2 + x1*y2 - y1*x2 + z1*r2; // z component 
    q.at<float>(3)=r1*r2 - x1*x2 - y1*y2 - z1*z2; // r component 
} 

這是OpenCV最快的方式嗎?使用定點算法會最快嗎?

+3

16次乘法和12次加法 - 對我來說似乎沒有太大的改進空間。使函數聯機!我希望這些「at」調用不是函數調用(即它們應該是內聯的)。 – JohnB

+0

它是Mat類的openCV成員。我認爲這是訪問Mat elment最快的方法,但我不確定。 http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat –

+3

儘可能高效?不要使用動態內存分配和引用計數的矩陣類,因爲它首先像四分量數組那樣微不足道。對於新的'Matx'類,這完全是一個完美的用例,參考你的其他問題之一。 –

回答

4

this教程中介紹了訪問不同像素的不同方法。發現Mat::at功能比直接像素訪問慢大約10%,可能是由於在調試模式下額外檢查。

如果你真的關閉性能,你應該用文中提到的3種不同方法重寫你的方法,然後配置文件找到最適合你的情況。

+0

這看起來不錯,我會看看 –

0

四元經常被用來旋轉3D矢量,所以你可能會考慮檢查一個四元數是一個純粹的載體(即標量或實部是零)。這可能會將你的工作減少到12個乘法,8個加/減和一個符號翻轉。

您還可以對兩個純矢量使用四元數乘法來同時計算它們的點和交叉乘積,因此對這種特殊情況進行測試也是值得的。如果兩個四元數都是純矢量,則只需要進行9次乘法,5次加/減和1次符號翻轉。

+0

事實上,或編寫和使用例程做全運:'vec_rotated = q *( 0,VEC)* q.conj()'在一個函數調用,一些操作進行比較,做兩個完整的四元產品保存(第二PROD總是具有零實部)。如果需要通過同一個四元數旋轉很多矢量 - 尤其是如果它們存儲在矩陣中 - 則將四元數轉換爲3x3旋轉矩陣並將其用於矢量的速度會更快。 – greggo