2012-05-28 12 views
11

私は品種に格納されている2つの四元、::マット構造を乗算します。私はその機能を可能な限り効率的にしたい。私は、これまでに次のコードを持っている:効率的なC++四元数の乗算::マット

/** 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の持つ最速の方法ですか?固定小数点演算を使用すると最速でしょうか?異なる画素にアクセスするためのthisチュートリアル異なる方法で

+3

16回の乗算と12回の加算 - 私には改善の余地があるようには思えません。機能をインラインにする!私はこれらの "at"コールが関数呼び出しではない(つまりインラインである)ことを願っています。 – JohnB

+0

これは、MatクラスのopenCVメンバーです。私はそれがMat elmentにアクセスする最も速い方法だと思うが、わからない。 http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat –

+3

できるだけ効率的ですか?動的なメモリ割り当てと、何かのための参照カウントを行う行列クラスを、最初は4要素配列と同じように使用しないでください。それはまさにあなたの他の質問の1つに関連して、新しい 'Matx'クラスの完璧なユースケースです。 –

答えて

4

が覆われています。 Mat::at機能は、直接ピクセルアクセスと比較して約10%遅いことが判明しました。おそらく、デバッグモードで余分なチェックが行われたためです。

あなたは、パフォーマンスのためにオフ実際にある場合は、本文中で言及した3種類の方法であなたの方法を書き換えた後、あなたの状況で最高のものを見つけるのは、プロファイル必要があります。

+0

これは素敵ですね、私は一見をします –

2

そこに私が今見つけることができません乗算四元ARMベクタ浮動小数点がありまし-had-。私は、このSIMDライブラリーを見つけることができる:あなたは1つのクォータニオンは、純粋なベクトルであることを確認し検討するかもしれないので

Bullet 3D Game Multiphysics Library

0

四元数は、多くの場合、3次元ベクトルを回転させるために使用されている(すなわち、スカラまたは実数部がゼロです)。これにより、12回の乗算、8回の加算/減算、1回の符号反転が可能になります。

また、また、それ価値があるかもしれませんので、この特別な場合のためにテストし、同時に彼らのドットとクロス積を計算するために2つの純粋なベクトルに四元数の乗算を使用することができます。両方のクォータニオンが純粋なベクトルの場合、9回の乗算、5回の加算/減算、1回の符号フリップが必要です。

+0

実際には、全体の操作を行うルーチンを記述してください: 'vec_rotated = q * 0、vec)* q.conj() 'を呼び出すと、2つのフル四元数のプロダクトを実行する場合(2つ目のプロダクトは常にゼロの実数部を持つ)と比べていくつかの演算が節約されます。同じクォータニオンで多くのベクトルを回転させる必要がある場合、特に行列に格納する場合は、クォータニオンを3x3回転行列に変換してベクトルに使用する方が高速です。 – greggo

関連する問題