如何使用OpenCV中的Mat::type()找出Mat对象的类型

如何使用OpenCV中的Mat::type()找出Mat对象的类型,opencv,opencv-mat,Opencv,Opencv Mat,我对OpenCV中Mat对象的type()方法有点困惑。如果我有以下几行: mat = imread("C:\someimage.jpg"); type = mat.type(); 和type=16。如何找出mat矩阵的类型?我试图在手册或几本书中找到答案,但都没有成功。在OpenCV标题“types|c.h”中有一组生成这些矩阵的定义,格式是CV|bits{U|S|F}c 例如,CV_8UC3意味着8位无符号字符,3个颜色通道-这些名称中的每一个都映射到该文件中宏的任意整数上 编辑:参见“类

我对OpenCV中
Mat
对象的
type()
方法有点困惑。
如果我有以下几行:

mat = imread("C:\someimage.jpg");
type = mat.type();
type=16
。如何找出mat矩阵的类型?
我试图在手册或几本书中找到答案,但都没有成功。

在OpenCV标题“types|c.h”中有一组生成这些矩阵的定义,格式是
CV|bits{U|S|F}c

例如,
CV_8UC3
意味着8位无符号字符,3个颜色通道-这些名称中的每一个都映射到该文件中宏的任意整数上

编辑:参见“类型\u 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 CV_制作类型(CV_8U,3)

#定义CV_MAKETYPE(depth,cn)(CV_MAT_depth(depth)+((cn)-1)这是一个方便的函数,可以帮助您在运行时识别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;
}
如果
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()
。此函数只是一种方便的方法,可以从这两个值的组合中获取人类可读的解释,这两个值的位都存储在同一个值中。

我总是使用此链接来查看使用
type()



我希望这能对您有所帮助。

为了便于在调试器中查找原始Mat::type时进行调试:

+--------+----+----+----+----+------+------+------+------+
|        | 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 |
+--------+----+----+----+----+------+------+------+------+

例如,如果type=30,则OpenCV数据类型为CV_64FC4。如果type=50,则OpenCV数据类型为CV_16UC(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;

}
void MatType(Mat inputMat)
{
int inttype=inputMat.type();
字符串r,a;
uchar depth=inttype&CV\u MAT\u depth\u MASK;
uchar chans=1+(inttype>>CV\u CN\u SHIFT);
开关(深度){
案例CV_8U:r=“8U”;a=“材料在(y,x)”处断裂;
案例CV_8S:r=“8S”;a=“材料在(y,x)”处”;断裂;
案例CV_16U:r=“16U”;a=“材料在(y,x)”;断裂;
案例CV16s:r=“16S”;a=“材料在(y,x)”处的断裂;
案例CV_32S:r=“32S”;a=“材料在(y,x)”处的断裂;
案例CV_32F:r=“32F”;a=“材料在(y,x)”;断裂;
案例CV_64F:r=“64F”;a=“材料在(y,x)”处的断裂;
默认值:r=“User”;a=“Mat.at(y,x)”;中断;
}   
r+=“C”;
r+=(chans+'0');

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

System.out.println(CvType.typeToString(yourMat.type()));

对于人工解释,最好使用
depth()
channels()
,而不是使用
type()
,后者返回数据类型和通道数之间的复杂混合。@Aldur,depth()的返回值)仍然不是人类可读的。您必须将其与定义进行比较:CV_8U、CV_8S等。@octopus当然可以,但通过一点练习,您可以学习常见的
depth()
代码,这对于
type()
来说要困难得多。请注意depth()返回此类型的CV枚举值(对初学者有点误导)。如果需要以字节为单位存储在Mat中的一个数字的大小,请使用Mat.elemSize1()。如果在运行时需要该类型,例如在传递不同类型的函数中,可以找到模板类型TypeDepth(可能我们应该重命名它,因为它不是CV depth)这里:感谢这个函数,你让我的生活变得更加轻松!令人失望的是,这样一个函数还没有集成到opencv thow中。我用Objective-C中的答案创建了Gist with method。有关类型的概述,请参见这个答案(5=32F,6=64F):有人真的能把它变成openCV的一个方便的函数吗?要获得
深度
通道
,你可以分别使用宏
CV\u MAT\u深度(类型)
CV\u MAT\u CN(类型)
。它们的类型也应该是
int
,这将允许你使用
来创建字符串(通道)
而不是
chans+'0'
。知道
types\u c.h
位于核心模块中是很有用的,例如,如果您使用包含“go-do定义”的IDE,则如果在c驱动器上直接安装了OpenCV,则头文件将位于c:\OpenCV\u 2.4.11\build\include\opencv2\core\types\u c.hAlso类似Visual Studio的功能您可以键入
cv::cv_8U
右键单击并选择
Go to Definition
打开定义了
cv::cv_8U
的文件,即
types_c.h
。c(X)是什么意思?^矩阵中的通道数^C5和c(5)之间的区别是什么,那么?没有区别。谢谢。这应该是最重要的答案C++:
cv::typeToString