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

╄→гoц情女王★ 提交于 2019-11-26 15:56:39

问题


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


回答1:


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




回答2:


OpenCV 2.4.9 deals with multi-dimensional sizes just fine. The struct cv::Mat::MSize can stores and return multiple dimensions. The data member cv::Mat::size is of the type cv::Mat::MSize. This code will enumerate the dimensions for you:

const int sz[] = {3, 4, 3, 6};
cv::Mat bigm(4, sz, CV_8UC1);
cout << bigm.dims << '\t';
for (int i=0; i<bigm.dims; ++i)
  cout << bigm.size[i] << ',';
cout << endl;

The output is:

4       3,4,3,6,



回答3:


std::vector<size_t> getMatDims(const cv::Mat& m)
{
    std::vector<size_t> dims(m.dims);
    std::partial_sum(&m.step[0],&m.step[0]+m.dims,dims.begin(),[](size_t a,size_t b){ return a/b; });
    return dims;
}


来源:https://stackoverflow.com/questions/18882242/how-do-i-get-the-size-of-a-multi-dimensional-cvmat-mat-or-matnd

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!