Chris
Chris

Reputation: 22247

How to determine the data type of a CvMat

When using the CvMat type, the type of data is crucial to keeping your program running.

For example, depending on whether your data is type float or unsigned char, you would choose one of these two commands:

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

Is there a universal approach to this? If the wrong data type matrix is passed to these calls, they crash at runtime. This is becoming an issue, since a function I have defined is getting passed several different types of matrices.

How do you determine the data type of a matrix so you can always access its data?

I tried using the "type()" function as such.

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

This does not compile, saying "term does not evaluate to a function taking 0 arguments". If I remove the brackets after the word type, I get a type of 1111638032

EDIT minimal application that reproduces this...

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;
}

Output: tmp2 type = 1111638021 and CV_32FC1 = 5 and 0

Upvotes: 4

Views: 11882

Answers (4)

JBWanscher
JBWanscher

Reputation: 370

While the issue at hand is related to calling/accessing the 'type' member of the Mat class I believe that the CV_ENUM usage deployed in the ts module of opencv will provide you with a more informative alternative.

The type is essentially built from the 'depth' member value and the 'channels' member value. By using the MatDepth enumeration in the ts-module the method PrintTo is available.

If you wish you can probably extract the channel count from the type simply by masking (&-operator) the bit value and inspecting the remaining bits.

#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;

}

Upvotes: 0

toto_tico
toto_tico

Reputation: 19027

There is a function called

CV_MAT_TYPE()

So you can do something like this

CV_MAT_TYPE(tmp2->type)

That is going to return the 5 you need which is equivalent to the CV_32FC1.

PO. I came looking for what was the meaning of the 5 I was getting with CV_MAT_TYPE, so you gave me the answer with your question. Thanks.

Upvotes: 3

karlphillip
karlphillip

Reputation: 93410

The type is a variable, NOT a function:

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

EDIT:

As for the unusual value of type being printed, according to this answer, this variable stores more than the data type.

So the appropriate way of checking cvMat data type is using the macro 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;

The naming convention of the data type is:

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.

Upvotes: 9

Martin Beckett
Martin Beckett

Reputation: 96109

There are a number of type() functions to return the data type, both size and number of channels see http://opencv.willowgarage.com/documentation/cpp/basic_structures.html#cvmat

Upvotes: 0

Related Questions