कैसे पता लगाया जाए कि OpenCV में Mat :: type () के साथ किस प्रकार का मैट ऑब्जेक्ट है


118

मैं OpenCV में ऑब्जेक्ट की type()विधि के साथ भ्रमित हूं Mat
अगर मेरे पास निम्नलिखित पंक्तियाँ हैं:

mat = imread("C:\someimage.jpg");
type = mat.type();

और type = 16। मुझे कैसे पता चलेगा कि मैट मैट्रिक्स किस प्रकार का है?
मैंने इसके मैनुअल में या व्यर्थ की एक-दो किताबों में इसका उत्तर खोजने की कोशिश की।


6
मानव व्याख्या के लिए, उपयोग करने के बजाय depth()और का उपयोग करना पसंद करते हैं channels(), type()जो डेटाटाइप और चैनलों की संख्या के बीच एक जटिल मिश्रण देता है।
ईसा पूर्व

@ आलूर, गहराई का वापसी मूल्य () अभी भी मानव पठनीय नहीं है। आप इसे परिभाषित करने के लिए है: CV_8U, CV_8S, आदि ...
ऑक्टोपस

1
@octopus यकीन है लेकिन अभ्यास के एक बिट के साथ आप आम depth()कोड सीख सकते हैं , जो इसके लिए बहुत कठिन है type()
बीसीोनिक

कृपया ध्यान दें कि गहराई () इस प्रकार के लिए सीवी एनम मूल्य (शुरुआती के लिए थोड़ा भ्रामक) लौटाता है। यदि आपको बाइट में मैट में संग्रहीत एक नंबर के आकार की आवश्यकता है, तो Mat.elemSize1 () का उपयोग करें। यदि आपको रनटाइम पर प्रकार की आवश्यकता होती है, उदाहरण के लिए एक फ़ंक्शन के भीतर जहां विभिन्न प्रकार इसमें पारित किए जाते हैं, तो आप एक टेम्पलेट प्रकार TypeDepth <> पा सकते हैं (शायद हमें इसका नाम बदलना चाहिए क्योंकि यह सीवी गहराई नहीं है): stackoverflow.com/questions/ 15245262 / ...
कर्स्टन

जवाबों:


196

यहां एक आसान कार्य है जिसका उपयोग आप रनटाइम पर अपने ओपनवेट मैट्रिसेस की पहचान करने में मदद करने के लिए कर सकते हैं। मुझे यह डिबगिंग के लिए उपयोगी लगता है, कम से कम।

string type2str(int type) {
  string r;

  uchar depth = type & CV_MAT_DEPTH_MASK;
  uchar chans = 1 + (type >> CV_CN_SHIFT);

  switch ( depth ) {
    case CV_8U:  r = "8U"; break;
    case CV_8S:  r = "8S"; break;
    case CV_16U: r = "16U"; break;
    case CV_16S: r = "16S"; break;
    case CV_32S: r = "32S"; break;
    case CV_32F: r = "32F"; break;
    case CV_64F: r = "64F"; break;
    default:     r = "User"; break;
  }

  r += "C";
  r += (chans+'0');

  return r;
}

यदि Mएक प्रकार का संस्करण है Matतो आप इसे इस तरह से कॉल कर सकते हैं:

string ty =  type2str( M.type() );
printf("Matrix: %s %dx%d \n", ty.c_str(), M.cols, M.rows );

डेटा का उत्पादन करेगा जैसे:

Matrix: 8UC3 640x480 
Matrix: 64FC1 3x2 

इसके लायक ध्यान देने योग्य बात यह भी मैट्रिक्स तरीके हैं कि Mat::depth()और Mat::channels()। यह फ़ंक्शन उन दो मूल्यों के संयोजन से मानव पठनीय व्याख्या प्राप्त करने का एक आसान तरीका है जिनके बिट्स सभी एक ही मूल्य में संग्रहीत हैं।


7
इस समारोह के लिए धन्यवाद, आपने मेरे जीवन को बहुत आसान बना दिया है! निराशाजनक है कि इस तरह के एक समारोह पहले से ही opencv में एकीकृत नहीं है।
मिलनिया

1
मैंने ऑब्जेक्टिव-सी में उत्तर से विधि के साथ Gist बनाया है। का आनंद लें!
टॉमस बज़

1
प्रकारों के अवलोकन के लिए यह उत्तर भी देखें (5 = 32F, 6 = 64F): stackoverflow.com/questions/12335663/…
Lenar Hoyt

क्या कोई वास्तव में ओपनकेवी के लिए एक आसान कार्य कर सकता है?
शरण दुग्गीराला

1
प्राप्त करने के लिए depthऔर chansआप क्रमशः मैक्रोज़ CV_MAT_DEPTH(type)और का उपयोग कर सकते CV_MAT_CN(type)हैं। उनका प्रकार भी होना चाहिए int, जो आपको to_string(chans)इसके बजाय उपयोग करने की अनुमति देगा chans+'0'
जॉन

151

डीबगिंग उद्देश्यों के लिए यदि आप एक कच्ची चटाई देखना चाहते हैं :: डिबगर में टाइप करें:

+--------+----+----+----+----+------+------+------+------+
|        | C1 | C2 | C3 | C4 | C(5) | C(6) | C(7) | C(8) |
+--------+----+----+----+----+------+------+------+------+
| CV_8U  |  0 |  8 | 16 | 24 |   32 |   40 |   48 |   56 |
| CV_8S  |  1 |  9 | 17 | 25 |   33 |   41 |   49 |   57 |
| CV_16U |  2 | 10 | 18 | 26 |   34 |   42 |   50 |   58 |
| CV_16S |  3 | 11 | 19 | 27 |   35 |   43 |   51 |   59 |
| CV_32S |  4 | 12 | 20 | 28 |   36 |   44 |   52 |   60 |
| CV_32F |  5 | 13 | 21 | 29 |   37 |   45 |   53 |   61 |
| CV_64F |  6 | 14 | 22 | 30 |   38 |   46 |   54 |   62 |
+--------+----+----+----+----+------+------+------+------+

उदाहरण के लिए, यदि टाइप करें = 30 तो OpenCV डेटा प्रकार CV_64FC4 है। यदि टाइप = 50 तो OpenCV डेटा प्रकार CV_16UC (7) है।


6
C (X) का क्या अर्थ है?
एलानवेक्स

5
^ मैट्रिक्स में चैनलों की संख्या
अरिजीत

3
^ C5 और C (5) में क्या अंतर है, फिर?
मतीन उलहाक

1
इसमें कोई फर्क नही है।
केविन जॉन्सुड

1
धन्यवाद। यह शीर्ष उत्तर होना चाहिए
regomodo

32

OpenCV हैडर " टाइप_अनह " में ऐसे डिफाइन का एक सेट होता है जो इन्हें उत्पन्न करता है, CV_bits{U|S|F}C<number_of_channels>
इसलिए फॉर्मेट उदाहरण के लिए CV_8UC38 बिट अहस्ताक्षरित वर्ण, 3 कलर चैनल - इन नामों में से प्रत्येक उस फ़ाइल में मैक्रोज़ के साथ एक मनमाना पूर्णांक पर मैप करता है।

संपादित करें: उदाहरण के लिए " type_c.h " देखें :

#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))

eg.
depth = CV_8U = 0
cn = 3
CV_CN_SHIFT = 3

CV_MAT_DEPTH(0) = 0
(((cn)-1) << CV_CN_SHIFT) = (3-1) << 3 = 2<<3 = 16

इसलिए, CV_8UC3 = 16 लेकिन आप इस नंबर का उपयोग करने वाले नहीं हैं, बस यह जांचने की type() == CV_8UC3ज़रूरत है कि आंतरिक ओपनसीवी सरणी किस प्रकार की है।
याद रखें OpenCV jpeg को BGR (या ग्रे स्केल में बदल देगा यदि आप '0' पास करते हैं imread) - तो यह आपको मूल फ़ाइल के बारे में कुछ नहीं बताता है।


यह जानना उपयोगी है कि types_c.hकोर मॉड्यूल में स्थित है, उदाहरण के लिए, यदि आपके पास OpenCV सी ड्राइव पर सीधे एक फ़ोल्डर में स्थापित है opencv_2.4.11 हैडर फ़ाइल सी पर होगी: \ opencv_2.4.11 \ build \ शामिल \ opencv_2 \ core \ type_c ज
user3731622

इसके अलावा, यदि आप एक IDE का उपयोग कर रहे हैं, जिसमें विजुअल स्टूडियो की तरह "गो डू डेफिनिशन" कार्यक्षमता शामिल है, तो आप cv::CV_8Uराइट-क्लिक कर सकते हैं और Go to Definitionउस फ़ाइल को खोलने के लिए चुन सकते हैं जहां cv::CV_8Uपरिभाषित किया गया है types_c.h
user3731622

12

मैं हमेशा इस लिंक का उपयोग यह देखने के लिए करता हूं कि मुझे किस प्रकार की संख्या मिलती है type():
LIST OF MAT TYPE IN OPENCV
मुझे उम्मीद है कि यह आपकी मदद कर सकता है।


8

मैंने डिबगिंग उद्देश्यों के लिए @ ओक्टोपस द्वारा उत्तर से फ़ंक्शन में कुछ प्रयोज्यता जोड़ी है।

void MatType( Mat inputMat )
{
    int inttype = inputMat.type();

    string r, a;
    uchar depth = inttype & CV_MAT_DEPTH_MASK;
    uchar chans = 1 + (inttype >> CV_CN_SHIFT);
    switch ( depth ) {
        case CV_8U:  r = "8U";   a = "Mat.at<uchar>(y,x)"; break;  
        case CV_8S:  r = "8S";   a = "Mat.at<schar>(y,x)"; break;  
        case CV_16U: r = "16U";  a = "Mat.at<ushort>(y,x)"; break; 
        case CV_16S: r = "16S";  a = "Mat.at<short>(y,x)"; break; 
        case CV_32S: r = "32S";  a = "Mat.at<int>(y,x)"; break; 
        case CV_32F: r = "32F";  a = "Mat.at<float>(y,x)"; break; 
        case CV_64F: r = "64F";  a = "Mat.at<double>(y,x)"; break; 
        default:     r = "User"; a = "Mat.at<UKNOWN>(y,x)"; break; 
    }   
    r += "C";
    r += (chans+'0');
    cout << "Mat is of type " << r << " and should be accessed with " << a << endl;

}

6

इसका जवाब कुछ अन्य लोगों ने दिया लेकिन मुझे एक ऐसा समाधान मिला जो मेरे लिए बहुत अच्छा काम करता है।

System.out.println(CvType.typeToString(yourMat));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.