20

我正在创建一个多维 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;

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

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

我希望看到:

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

或者:

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

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

4

3 回答 3

36

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

如果你看一下 OpenCV 的源代码,版本 2.4.6.1,你会发现cv::Mat::size它是一个类型为 的成员对象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;
};

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

typedef Size_<int> Size2i;
typedef Size2i Size;

引用OpenCV 手册Size

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

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

幸运的是,所有希望都没有丢失,因为您可以使用它cv::Mat::MSize::operator [](int i)来获取矩阵沿其i-th维度的大小。

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

于 2013-09-18T21:58:03.440 回答
14

OpenCV 2.4.9 可以很好地处理多维尺寸。struct cv::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;

输出是:

4       3,4,3,6,
于 2014-11-20T04:12:34.230 回答
1
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;
}
于 2015-01-14T11:15:47.523 回答