如何在OpenCV中找到Mat对象的类型是Mat :: type()

Tae*_*hin 106 opencv opencv-mat

我对OpenCV中type()Mat对象方法感到困惑.
如果我有以下行:

mat = imread("C:\someimage.jpg");
type = mat.type();
Run Code Online (Sandbox Code Playgroud)

type = 16.如何找出垫阵的类型?
我试图在其手册或几本书中找到答案是徒劳的.

Oct*_*pus 175

这是一个方便的函数,可用于帮助在运行时识别opencv矩阵.我发现它至少对调试很有用.

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;
}
Run Code Online (Sandbox Code Playgroud)

如果M是var类型,Mat你可以像这样调用它:

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

将输出数据如:

Matrix: 8UC3 640x480 
Matrix: 64FC1 3x2 
Run Code Online (Sandbox Code Playgroud)

值得注意的是,还有Matrix方法Mat::depth()Mat::channels().这个函数只是从这两个值的组合中获得人类可读解释的一种方便方法,这两个值的位都存储在相同的值中.

  • 感谢您的这项功能,让您的生活更轻松!令人失望的是,这样的功能尚未集成在opencv thow中. (5认同)
  • 要获得 `depth` 和 `chans`,你可以分别使用宏 `CV_MAT_DEPTH(type)` 和 `CV_MAT_CN(type)`。它们的类型也应该是 `int`,这将允许你使用 `to_string(chans)` 而不是 `chans+'0'`。 (3认同)

Kev*_*ude 118

出于调试目的,如果您想在调试器中查找原始Mat ::类型:

+--------+----+----+----+----+------+------+------+------+
|        | 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 |
+--------+----+----+----+----+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)

因此,例如,如果type = 30,则OpenCV数据类型为CV_64FC4.如果type = 50,则OpenCV数据类型为CV_16UC(7).

  • C(X)是什么意思? (5认同)
  • ^矩阵中的通道数 (4认同)
  • 那么C5和C(5)有什么区别呢? (3认同)
  • @MateenUlhaq 只是一个小注释:您可以创建最多 4 位通道的图像(Mat 对象),而无需括号(在类型参数中),但创建 >=5 通道的图像将返回错误。示例:“Mat img(23, 53, CV_64FC(5))”有效,但“Mat img(23, 53, CV_64FC5)”无效。 (2认同)

Mar*_*ett 32

在OpenCV标题" types_c.h "中有一组生成这些的定义,格式是CV_bits{U|S|F}C<number_of_channels>
So,例如CV_8UC3意味着8位无符号字符,3个颜色通道 - 这些名称中的每一个都映射到该文件中的宏的任意整数.

编辑:例如,参见" types_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
Run Code Online (Sandbox Code Playgroud)

所以CV_8UC3 = 16 ,你不应该使用这个数字,只需检查type() == CV_8UC3你是否需要知道内部OpenCV数组是什么类型.
请记住,OpenCV会将jpeg转换为BGR(如果传递'0',则为灰度imread) - 因此它不会告诉您有关原始文件的任何信息.


Ang*_*ano 11

我总是使用这个链接来查看我得到的数字类型type():
OPENCV中的MAT TYPE列表
我希望这可以帮到你.


Pro*_*ber 10

其他一些人回答了这个问题,但我找到了一个对我来说非常有效的解决方案。

System.out.println(CvType.typeToString(yourMat.type()));
Run Code Online (Sandbox Code Playgroud)

  • C++:`cv::typeToString` (2认同)

YSc*_*arf 8

基于@Matt Edding 的评论(感谢 Mat(T) 双关语;)):

cout << cv::typeToString(inputMat.type()) << endl;

奇迹般有效。


sha*_*r_m 7

为了调试目的,我从@Octopus的答案中添加了一些可用性.

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;

}
Run Code Online (Sandbox Code Playgroud)