ওপেনসিভিতে মাদুর :: প্রকার () সহ কোন ধরণের ম্যাট অবজেক্টের কী কী তা সন্ধান করবেন


118

আমি ওপেনসিভিতে অবজেক্টের type()পদ্ধতিতে বিভ্রান্ত হয়ে পড়েছি Mat
আমার যদি নিম্নলিখিত লাইন থাকে:

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

এবং type = 16। কীভাবে মাদুর ম্যাট্রিক্স হয় তা আমি কীভাবে আবিষ্কার করব?
আমি উত্তরটি এর ম্যানুয়ালটিতে বা দু'টি বইয়ে নিরর্থকভাবে চেষ্টা করার চেষ্টা করেছি।


6
মানুষের ব্যাখ্যার জন্য, ব্যবহার করেন depth()এবং channels()এর পরিবর্তে ব্যবহার করার, type()যা ডাটাটাইপ ও চ্যানেল সংখ্যার মধ্যে একটি জটিল মিশ্রণ ফেরৎ।
বিসোনিক

@ আলদুর, গভীরতার ফিরতি মূল্য () এখনও মানব পাঠযোগ্য নয়। আপনাকে এটি সংজ্ঞায়নের সাথে তুলনা করতে হবে: সিভি_ 8 ইউ, সিভি_ 8 এস, ইত্যাদি ...
অক্টোপাস

1
@ অক্টোপাস নিশ্চিত তবে কিছুটা অনুশীলনের সাহায্যে আপনি প্রচলিত depth()কোডগুলি শিখতে পারেন যা এর চেয়ে শক্ত type()
বিসোনিক

দয়া করে নোট করুন যে গভীরতা () এই ধরণের জন্য সিভি এনাম মান প্রদান করে (নতুনদের জন্য কিছুটা বিভ্রান্তিকর)। আপনার যদি ব্যাটগুলিতে মাদুরের মধ্যে থাকা একটি সংখ্যার আকারের প্রয়োজন হয় তবে Mat.elemSize1 () ব্যবহার করুন। রানটাইমের সময় আপনার যদি টাইপের প্রয়োজন হয়, যেমন কোনও ফাংশনের মধ্যে যেখানে বিভিন্ন ধরণের এটি প্রবিষ্ট হয় তবে আপনি টেম্পলেট টাইপ টাইপডেপথ <> খুঁজে পেতে পারেন (সম্ভবত এটির সিভি গভীরতা না হওয়ায় এটির আমাদের নামকরণ করা উচিত): স্ট্যাকওভারফ্লো / প্রশ্ন / 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
এই ফাংশনটির জন্য ধন্যবাদ, আপনি আমার জীবনকে আরও সহজ করে তুলেছেন! হতাশাজনক যে এই জাতীয় ফাংশন ইতিমধ্যে ওপেনসিভি থোতে সংহত নয়।
মিলানিয়া

1
আমি উদ্দেশ্যটি-সি-তে উত্তর থেকে পদ্ধতিটি সহ গিস্ট তৈরি করেছি। উপভোগ করুন!
টমসজ বেক

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 হয় তবে ওপেনসিভি ডেটা টাইপ হল সিভি_64FCফিসি 4। যদি টাইপ = 50 তবে ওপেনসিভি ডেটা টাইপ সিভি_16 ইউসি (7)।


6
সি (এক্স) এর অর্থ কী?
অ্যালানউক্স

5
The ম্যাট্রিক্সে চ্যানেলের সংখ্যা
অরিজিৎ

3
Then তাহলে সি 5 এবং সি (5) এর মধ্যে পার্থক্য কী?
মতিন উলহাক

1
এখানে কোন পার্থক্য নেই.
কেভিন জনস্রুড

1
ধন্যবাদ। এটি শীর্ষ উত্তর হতে হবে
রেগমডো

32

ওপেনসিভি শিরোলেখ " টাইপস_সিএইচকিউ " তে এখানে সংজ্ঞাগুলির একটি সেট রয়েছে যা এগুলি উত্পন্ন করে, ফর্ম্যাটটি CV_bits{U|S|F}C<number_of_channels>
সুতরাং উদাহরণস্বরূপ CV_8UC38 বিট স্বাক্ষরযুক্ত অক্ষর, 3 টি রঙিন চ্যানেল - এই প্রতিটি নামই সেই ফাইলে ম্যাক্রোগুলির সাথে একটি নির্বিচার পূর্ণসংখ্যার উপরে ম্যাপ করে।

সম্পাদনা করুন: উদাহরণস্বরূপ " প্রকারের_সিএইচডিচ " দেখুন :

#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 অ্যারে জানা প্রয়োজন।
মনে রাখবেন ওপেনসিভি জেপিকে বিজিআরতে রূপান্তর করবে (বা আপনি '0' এ পাস করলে ধূসর স্কেল imread) - সুতরাং এটি আপনাকে মূল ফাইল সম্পর্কে কিছু বলবে না।


এটি types_c.hমূল মডিউলে অবস্থিত তা জানতে দরকারী , উদাহরণস্বরূপ আপনি যদি একটি ফোল্ডারে ওপেনসিভি_2.4.11 সরাসরি সি ড্রাইভে ইনস্টল করে থাকেন তবে শিরোনাম ফাইলটি সিতে থাকবে: \ ওপেনসিভি_2.4.11 \ বিল্ড \ অন্তর্ভুক্ত \ ওপেনসিভি 2 \ কোর \ প্রকার_সি .h
ব্যবহারকারী 3731622

এছাড়াও, আপনি যদি ভিজুয়াল স্টুডিওর মতো "গো ডু সংজ্ঞা" কার্যকারিতা অন্তর্ভুক্ত কোনও আইডিই ব্যবহার করেন তবে আপনি cv::CV_8Uডান-ক্লিক টাইপ করতে পারেন এবং Go to Definitionযেখানে ফাইলটি cv::CV_8Uসংজ্ঞায়িত করা হয়েছে তা খোলার জন্য নির্বাচন করতে পারেন types_c.h
user3731622


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));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.