C++ 我如何获得多维 cv::Mat 的大小?(垫子或 MatND)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18882242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:17:48  来源:igfitidea点击:

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

c++opencvmat

提问by Pete

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

我正在创建一个多维 MAT 对象,并想获取对象的大小 - 例如,

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:

我相信生成的 MAT 为 10x10x9,我想确认一下,但 COUT 语句给出:

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

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

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

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

我怎样才能获得这个 Mat 对象的维度?我在 Mat::Mat 或 MatND 中没有看到任何方法

回答by brunocodutra

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

您刚刚发现自己是 OpenCV C++ API 的众多缺陷之一。

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

如果你看一下 OpenCV 2.4.6.1 版本的源代码,你会发现cv::Mat::size是一个 type 的成员对象,cv::Mat::MSize定义为

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 Sizeis defined as

因此cv::Mat::size()实际上是指cv::Mat::MSize::operator ()(),其返回类型Size定义为

typedef Size_<int> Size2i;
typedef Size2i Size;

Quoting from the OpenCV manual, Sizeis a

引自OpenCV 手册Size是一个

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

“用于指定图像或矩形大小的模板类。该类包括两个成员,称为宽度和高度。”

In other words, Sizeis only suitable for 2D matrices.

换句话说,Size只适用于二维矩阵。

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-thdimension.

幸运的是,cv::Mat::MSize::operator [](int i)并没有失去所有希望,因为您可以使用它来获得矩阵沿其第i维的大小

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

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

回答by Sameer

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

OpenCV 2.4.9 可以很好地处理多维尺寸。该structcv::Mat::MSize罐存储和返回多个维度。数据成员cv::Mat::size的类型为cv::Mat::MSize。此代码将为您枚举维度:

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,

回答by Steve132

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