2012-08-27 23 views
18

के साथ एक ओपनसीवी मैट शुरू करें मेरे आवेदन में, मैं कुछ मूल्य वाले ओपनसीवी मैट ए (2-आयाम) बनाना चाहता हूं और फिर इनपुट के रूप में ए का उपयोग करके इसे अन्य ओपनसीवी फ़ंक्शन पर भेजना चाहता हूं।एक 2 डी सरणी

वर्तमान में, मैं कोशिश कर रहा हूँ:

// float data[2][5] = {{1,2,3,4,5},{7,8,9,10,11}}; 
// OR 
float data[10] = {1,2,3,4,5,7,8,9,10,11}; 

// and then 
// A = Mat(1, 5, CV_32FC1, &data, 2); // init from float 1D - array 
// OR 
    A = Mat(2, 5, CV_32FC1, &data, 2); 

-1 डी सरणी के मामले में, मूल्य गुजर ठीक है। लेकिन यह 2 डी सरणी के लिए काम नहीं करता है, जो कि एक आम मामला है। ओपनसीवी में मैं इसे कैसे हल कर सकता हूं ??

उत्तर

23

orginally, मैं OpenCV ऑनलाइन गाइड से स्मरक प्रयोग किया है:

Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP) 

लेकिन मैं समझ में नहीं आया कि क्या दस्तावेज़ द्वारा "size_t कदम = AUTO_STEP" का अर्थ है। और इसका मतलब है कि मैं 'कदम' तर्क है जिसके साथ OpenCV स्वचालित रूप से AUTO_STEP

चुनता होगा

मैं कोशिश की है ommit सकता है और यह काम करता है:

A = Mat(2, 5, CV_32FC1, &data); 
2 डी चटाई के लिए

सरणी

16

से प्रारंभ करते हुए अपने उत्तर आपकी स्थिति के लिए सही है, यह जानना अच्छा है कि step और AUTO_STEP माध्य

आमतौर पर, छवियों को स्मृति के निरंतर ब्लॉक में संग्रहीत किया जाता है। प्रत्येक पंक्ति में पिछले एक के बाद इस प्रकार है, तो आप के साथ सूचक द्वारा डेटा का उपयोग कर सकते हैं एक सरल

data = dataPtr[currentCol + width * currentRow]; 

कहाँ चौड़ाई बाइट में पंक्ति चौड़ाई (पिक्सेल में नहीं है!)

है लेकिन यह हमेशा नहीं है मामला - कभी-कभी आप एक सबमिट्रिक्स तक पहुंचते हैं, और डेटा प्रत्येक पंक्ति पर निरंतर होता है, लेकिन अगली पंक्ति पर जाने के लिए आपको बाइट्स का अनुक्रम कूदना होगा।

यह वह जगह है जहां चरण (चरण के रूप में भी जाना जाता है) आता है। यह दो लगातार पंक्तियों के बीच बाइट्स में दूरी का प्रतिनिधित्व करता है। निरंतर matrices में, इसका मान sizeof(pixel)*rowWidth है, लेकिन इसमें विशेष स्थितियों में कस्टम मान हो सकते हैं। जब आप मट कन्स्ट्रक्टर को AUTO_STEP पास करते हैं, तो यह जानता है कि डेटा निरंतर है और उपर्युक्त सूत्र के साथ चरण की गणना करता है। तो अब, पिक्सेल मान पढ़ने के लिए अधिक सही दृष्टिकोण

data = dataPtr[currentCol + step * currentRow]; 

जो सभी प्रकार की छवियों के लिए काम कर रहा है।

अंतिम, लेकिन कम से कम, कि कदम मत भूलना पिक्सलबाइट्स में मापा जाता है, नहीं है। तो अगर आप आरजीबी छवि uchar एक 3 चैनल है, कदम 3*number of pixels हो जाएगा, और यदि आप एक 3 चैनल पूर्णांक छवि है, step = 3(channels)*(4=sizeof(int))*(number rows)

5

data के बाद से 2 डी सरणी है - data के सभी, &data, *data, data[0], &data[0], और &data[0][0] सरणी के आधार पर इंगित करें।के बाद से डेटा void* के रूप में OpenCV द्वारा accepted है और OpenCV से डेटा का उपयोग line में के रूप में है इसके बाद के संस्करण प्रतिनिधित्व का कोई भी सही ढंग से

A = Mat(2, 5, CV_32FC1, X); 

में X के स्थान पर Mat का निर्माण करने के लिए चुना जा सकता है मन की शांति है। मैं एकल या बहु आयामी सरणी से मैट बनाने के लिए एक ही वाक्यविन्यास पसंद करता हूं।

A = Mat(1, 10, CV_32FC1, data); //for 1D array 
A = Mat(2, 5, CV_32FC1, data); //for 2D array 

वापस क्वेरी के लिए - कि नोट, 1 डी सरणी से भी Mat के अपने निर्माण सही नहीं है। चरण पैरामीटर का उल्लेख 2 के रूप में किया गया है। यह केवल काम करने के लिए हुआ, ओपनसीवी overrides पंक्तियों की संख्या प्रदान की गई चरण पैरामीटर 1. उच्च आयामी सरणी के लिए, ओपनसीवी गलत चरण पैरामीटर के लिए assertion डीबग फेंकता है, जो आपको मिला है।

14

उपरोक्त उत्तरों के अतिरिक्त, another option है।

एक छोटे डेटा के लिए, मैं निम्नलिखित पसंद करेंगे:

Mat A = (Mat_<float>(2, 5) << 1, 2, 3, 4, 5, 7, 8, 9, 10, 11); 

आप आसानी से एक अतिरिक्त चर 'डेटा' को परिभाषित करने की आवश्यकता के बिना वांछित परिणाम प्राप्त कर सकते हैं।

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