How do i get the size of a multi-dimensional cv::Mat? (Mat, or MatND)

Pete picture Pete · Sep 18, 2013 · Viewed 23k times · Source

I am creating a multi-dimensional MAT object, and would like to get the size of the object - e.g.,

const int sz[] = {10,10,9};
Mat temp(3,sz,CV_64F);
std::cout << "temp.dims = " << temp.dims << " temp.size = " << temp.size() << " temp.channels = " << temp.channels() << std::endl;

I believe the resulting MAT to be 10x10x9, and I'd like to confirm, but the COUT statement gives:

temp.dims = 3 temp.size = [10 x 10] temp.channels = 1

I was hoping to see either:

temp.dims = 3 temp.size = [10 x 10 x 9] temp.channels = 1

Or:

temp.dims = 3 temp.size = [10 x 10] temp.channels = 9

How can I get the dimensionality of this Mat object? I didn't see any methods in Mat::Mat or MatND

Answer

brunocodutra picture brunocodutra · Sep 18, 2013

You just found yourself one of the many flaws of the OpenCV C++ API.

If you take a look at the source code of OpenCV, version 2.4.6.1, you will realize cv::Mat::size is a member object of type cv::Mat::MSize, which is defined as

struct CV_EXPORTS MSize
{
    MSize(int* _p);
    Size operator()() const;
    const int& operator[](int i) const;
    int& operator[](int i);
    operator const int*() const;
    bool operator == (const MSize& sz) const;
    bool operator != (const MSize& sz) const;

    int* p;
};

Thus cv::Mat::size() actually refers to cv::Mat::MSize::operator ()(), whose return type Size is defined as

typedef Size_<int> Size2i;
typedef Size2i Size;

Quoting from the OpenCV manual, Size is a

"Template class for specifying the size of an image or rectangle. The class includes two members called width and height."

In other words, Size is only suitable for 2D matrices.

Fortunately all hope is not lost as you can use cv::Mat::MSize::operator [](int i) to get the size of the matrix along its i-th dimension.

const int sz[] = {10,10,9}; 
cv::Mat temp(3,sz,CV_64F); 
std::cout << "temp.dims = " << temp.dims << "temp.size = [";
for(int i = 0; i < temp.dims; ++i) {
    if(i) std::cout << " X ";
    std::cout << temp.size[i];
}
std::cout << "] temp.channels = " << temp.channels() << std::endl;

temp.dims = 3 temp.size = [10 x 10 x 9] temp.channels = 1