如何确定CvMat的数据类型

4

当使用CvMat类型时,数据类型对于程序的运行至关重要。

例如,根据您的数据是float类型还是unsigned char类型,您将选择以下两个命令之一:

cvmGet(mat, row, col);
cvGetReal2D(mat, row, col);

有没有通用的方法来解决这个问题?如果将错误类型的矩阵传递给这些调用,它们会在运行时崩溃。这正在成为一个问题,因为我定义的函数被传递了几种不同类型的矩阵。

如何确定矩阵的数据类型,以便您始终可以访问其数据?

我尝试使用 "type()" 函数进行操作。

CvMat* tmp_ptr = cvCreateMat(t_height,t_width,CV_8U);
std::cout << "type = " << tmp_ptr->type() << std::endl;

这段代码不能编译,提示错误信息为"term does not evaluate to a function taking 0 arguments"。如果我删除type单词后面的括号,它会返回一个1111638032类型的结果。

编辑生成该问题最小化应用程序的代码如下...

int main( int argc, char** argv )
{
    CvMat *tmp2 = cvCreateMat(10,10, CV_32FC1);
    std::cout << "tmp2 type = " << tmp2->type << " and CV_32FC1 = " << CV_32FC1 << " and " << (tmp2->type == CV_32FC1) << std::endl;
}

输出:tmp2类型为1111638021,CV_32FC1 = 5且为0

4个回答

9

type是一个变量,而不是一个函数:

CvMat* tmp_ptr = cvCreateMat(t_height,t_width,CV_8U);
std::cout << "type = " << tmp_ptr->type << std::endl;

编辑:

至于打印出的不寻常值type,根据此答案,这个变量存储的不仅仅是数据类型。

因此,检查cvMat数据类型的适当方法是使用宏CV_MAT_TYPE()

CvMat *tmp2 = cvCreateMat(3,1, CV_32FC1);
std::cout << "tmp2 type = " << tmp2->type << " and CV_32FC1 = " << CV_32FC1 << " and " << (CV_MAT_TYPE(tmp2->type) == CV_32FC1) << std::endl;

数据类型的命名规范是:
CV_<bit_depth>(S|U|F)C<number_of_channels>

S = Signed integer
U = Unsigned integer
F = Float 

E.g.: CV_8UC1 means an 8-bit unsigned single-channel matrix, 
      CV_32FC2 means a 32-bit float matrix with two channels.

看,这就是我想的,但类型的结果是1111638032,完全错误。CV_8U应该得到整数0。这就是我的困惑所在。为什么类型会如此错误? - Chris
如果您使用CV_8UC1创建矩阵会怎样?您尝试创建的矩阵的大小是多少(宽度/高度)?您没有测试cvCreateMat()的成功,这可能是一个好主意。 - karlphillip
同样的想法...我再次尝试使用32FC1。CvMat *tmp2 = cvCreateMat(10,10, CV_32FC1); 我将tmp2->type与CV_32FC1进行了比较。tmp2->type返回1111638021,而cv float返回5。 - Chris
请编写一个完整的最小应用程序并将其放在您的问题中,以便我们尝试重现您的问题。 - karlphillip
将最小的应用程序添加到问题中。 - Chris

3
有一个名为的函数
CV_MAT_TYPE()

那么你可以这样做:
CV_MAT_TYPE(tmp2->type)

这将返回您所需的5,相当于CV_32FC1。

附注:我来寻找CV_MAT_TYPE返回的5的含义,所以您的问题给了我答案。谢谢。


0

谢谢。我之前看过这些函数,但是'type'函数对我不起作用。如果我使用mat->type(),这个代码就无法编译了。“Term does not evaluate to a function taking 0 arguments”。 - Chris
链接已失效。 - YScharf

0

虽然问题与调用/访问Mat类的'type'成员有关,但我相信在opencv的ts模块中部署的CV_ENUM用法将为您提供更详细的替代方案。

类型基本上是从'depth'成员值和'channels'成员值构建的。通过在ts模块中使用MatDepth枚举,可以使用PrintTo方法。

如果您希望,可以通过掩码(&-运算符)位值并检查剩余位来简单地提取类型的通道计数。

#include <opencv2/ts/ts_perf.hpp>
#include <iostream>

// Method for printing the information related to an image                                                                                                                                              
void printImageInfo(std::ostream * os, cv::Mat * image){
  int type = image->type();
  int channels = image->channels();
  cv::Size imageSize = image->size();
  perf::MatDepth depth(image->depth());
  *os << "Image information: " << imageSize << " type " << type
      << " channels " << channels << " ";
  *os << "depth " << depth << " (";
  depth.PrintTo(os);
  *os << ")" << std::endl;

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接