2012-06-13 16 views
13

में फ़ंक्शंस में मैट I opencv के लिए नया हूं और मुझे कोडिंग में सबसे सरल संचालन में से एक के साथ संदेह है: कार्यों को मान पास करना।Matrices यानी सरल पासिंग यानी। cv :: OpenCV2.4

यहाँ मैं क्या करना चाहते हैं

,

  1. कहते हैं के साथ मुख्य समारोह में एक cv:Mat प्रारंभ, 0 से 50
  2. करने के लिए मानों एक समारोह foo() लिए एक तर्क के रूप में इस मैट्रिक्स दर्रा है जो बदले में बस मैट्रिक्स में प्रत्येक तत्व के मानों को प्रिंट करता है। बस।

अब मैंने कई स्थानों पर पढ़ा है कि जब ये मैट्रिक्स पास हो जाते हैं, तो यह केवल वह शीर्षलेख होता है जो वास्तविक डेटा नहीं होता है। तो फिर भी मैं इस मैट्रिक्स के मूल्यों को बुलाए गए फ़ंक्शन में कैसे पढ़ सकता हूं जैसे कि संपूर्ण मैट्रिक्स पारित किया गया था?

+0

इन जगह कहां हैं? क्या आप उन्हें संदर्भ साझा कर सकते हैं? – karlphillip

+0

http://opencv.willowgarage.com/documentation/cpp/memory_management.html –

उत्तर

31

को समझने के लिए पर आप C++ constructors पर एक नज़र लेने के लिए, और अधिक विशेष copy constructor जरूरत है क्या हो रहा है।

जब आप किसी अन्य cv::Mat से एक cv::Mat बनाने के लिए, के रूप में:

cv::Mat a = cv::imread("huge.png", 1); 
cv::Mat b = a; 

प्रतिलिपि निर्माता (एक समारोह है जो) cv::Mat की वस्तु की प्रतिलिपि प्रदर्शन करने के लिए कहा जाता है। प्रतिलिपि प्रक्रिया में क्या होता है, इसके बारे में बात करने से पहले, आपको यह समझना होगा कि cv::Mat छवियों को संग्रहीत करने के लिए उपयोग किया जाता है, बड़ी छवियां स्मृति में सैकड़ों मेगाबाइट्स पर कब्जा कर सकती हैं। तो क्या प्रतिलिपि निर्माता cv::Mat की ऊपर के उदाहरण में करता b में a का संपूर्ण शीर्ष लेख (ऊंचाई, चौड़ाई, गहराई की जानकारी और अन्य) की प्रतिलिपि है, लेकिन इसके बजाय a के पूरे डेटा/पिक्सल (सैकड़ों हो सकता है जो कॉपी करने की एमबी का), यह सिर्फ a के मूल डेटा पर पॉइंटर्स का उपयोग करता है।

दूसरे शब्दों में, संपूर्ण छवि डेटा की प्रतिलिपि नहीं एक अनुकूलन/प्रदर्शन निर्णय है।

void do_something(cv::Mat src) 
{ 
    // changing src pixels will be the same as changing orig pixels 
} 

int main() 
{ 
    cv::Mat orig = cv::imread("huge.png", 1); 
    do_something(orig); 
    return 0; 
} 

आप कार्यों के लिए मानकों को पारित करने के लिए कैसे का अध्ययन किया है, तो आप जानते हैं कि बुला do_something(a); होगा pass the parameter by value:

अब, यह कोड एक समारोह कॉल और cv::Mat एक पैरामीटर के रूप गुजरता है कि विचार करें। इसका अर्थ यह है कि यह orig की सामग्री को src में कॉपी करने का प्रयास करेगा, हालांकि, यह प्रक्रिया cv::Mat की कॉपी कन्स्ट्रक्टर को सक्रिय करती है जो डेटा की हार्ड कॉपी नहीं बनायेगी जैसा मैंने अभी समझाया है।

इस समस्या का समाधान? आप do_something() लिख रहे हैं और तुम सिर्फ orig की एक वास्तविक प्रतिलिपि बनाना चाहते हैं, बस एक नई cv::Mat बना सकते हैं और फोन विधि copyTo():

void do_something(cv::Mat src) 
{ 
    cv::Mat real_copy = src.copyTo(); 
    // operating on the data of real_copy will not affect orig 
} 

लेकिन याद रखें, यदि src है ~ 100 एमबी copyTo() बुला वास्तविक प्रतिलिपि बनाने के लिए एक और ~ 100 एमबी मेमोरी पर कब्जा कर लेगा, जिसका मतलब है कि एक ही समारोह में आपका प्रोग्राम कॉल करें 100 एमबी से 200 एमबी तक।अपने सिस्टम को डिजाइन करते समय इसे ध्यान में रखें। सौभाग्य।

+4

उत्कृष्ट। जैसे आप मेरे दिमाग को पढ़ते हैं और मेरे पास सही प्रश्न का उत्तर देते हैं। महोदय आपका बहुत बहुत धन्यवाद। बहुत सराहना की। –

+1

कूल, आधिकारिक उत्तर के रूप में इसे चुनने के लिए बस इसके पास स्थित चेकबॉक्स पर क्लिक करें। – karlphillip

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