2012-05-28 20 views
11

का उपयोग करके मैं 2 quaternions गुणा करना चाहता हूं, जो सीवी :: मैट संरचना में संग्रहीत हैं। मैं चाहता हूं कि समारोह जितना संभव हो उतना कुशल हो। मैं निम्नलिखित कोड अब तक है:कुशल सी ++ quaternion गुणा सीवी :: मैट

/** 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 जोड़ - मुझे सुधार के लिए बहुत अधिक जगह नहीं लगती है। फ़ंक्शन इनलाइन बनाएं! मुझे आशा है कि ये "पर" कॉल फ़ंक्शन कॉल नहीं हैं (यानी, उन्हें इनलाइन होना चाहिए)। – JohnB

+0

यह मैट क्लास का ओपनसीवी सदस्य है। मुझे लगता है कि यह मैट elment acces करने के लिए सबसे तेज़ तरीका है, लेकिन मुझे यकीन नहीं है। http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#mat –

+3

जितना संभव हो उतना कुशल? मैट्रिक्स क्लास का उपयोग न करें जो पहले स्थान पर चार-घटक सरणी के रूप में कुछ के रूप में गतिशील स्मृति आवंटन और संदर्भ गिनती करता है। यह आपके अन्य प्रश्नों में से एक के संदर्भ में, नए 'मैटक्स' वर्ग के लिए बिल्कुल सही उपयोग केस है। –

उत्तर

4

अलग पिक्सल का उपयोग करने की this ट्यूटोरियल अलग अलग तरीकों में शामिल किया गया है। Mat::at फ़ंक्शन सीधे पिक्सेल एक्सेस की तुलना में लगभग 10% धीमा पाया गया था, संभवतः डीबग मोड में अतिरिक्त चेक के कारण।

तुम सच में प्रदर्शन के लिए बंद कर रहे हैं, तो आप 3 अलग टेक्स्ट में उल्लिखित तरीकों के साथ अपने विधि को फिर से लिखने चाहिए और फिर एक जो अपनी स्थिति में सबसे अच्छा है खोजने के लिए प्रोफ़ाइल।

+0

यह अच्छा लग रहा है, मेरे पास –

2

हुई -had- एक हाथ वेक्टर चल बिन्दु चौका वहाँ बाहर गुणा मैं अब नहीं मिल रहा। मैं इस SIMD पुस्तकालय मिल सकता है:

Bullet 3D Game Multiphysics Library

0

Quaternions अक्सर ताकि आप जाँच है कि एक चार का समुदाय एक शुद्ध वेक्टर है पर विचार हो सकता 3 डी वैक्टर को घुमाने के लिए उपयोग किया जाता है (अर्थात, अदिश या वास्तविक हिस्सा शून्य है)। यह आपके काम को 12 गुणा, 8 जोड़/घटाव और एक साइन फ्लिप में काट सकता है।

तुम भी एक साथ उनके डॉट और पार उत्पादों गणना करने के लिए दो शुद्ध वैक्टर पर चौका गुणा उपयोग कर सकते हैं, तो यह विशेष मामले के लिए परीक्षण भी इसके लायक हो सकता है। यदि दोनों quaternions शुद्ध वैक्टर हैं, तो आपको केवल 9 गुणा, 5 जोड़/घटाव और एक साइन फ्लिप की आवश्यकता है।

+0

वास्तव में, या लिखने और नियमित रूप से उपयोग करने के लिए एक पूरे दिन का उपयोग करेगा: 'vec_rotated = q * (0, vec) * q.conj() 'एक फ़ंक्शन कॉल में, कुछ पूर्ण क्वाटरनियन उत्पादों (दूसरे प्रोड में हमेशा शून्य वास्तविक भाग) की तुलना में कुछ ऑपरेशन सहेजे जाते हैं। यदि आपको एक ही quaternion द्वारा बहुत सारे वैक्टर घुमाने की आवश्यकता है - विशेष रूप से यदि वे एक मैट्रिक्स में संग्रहीत हैं - तो quaternion को 3x3 रोटेशन मैट्रिक्स में परिवर्तित करना और वैक्टरों पर इसका उपयोग करना तेज़ है। – greggo

संबंधित मुद्दे