【问题标题】:Opencv in memory Mat representationOpencv 在内存中的 Mat 表示
【发布时间】:2016-05-05 01:24:29
【问题描述】:

我知道在内存中 opencv 将 Mat 对象表示为一个大数组。因此,如果我有 3 个尺寸为 200x200 的通道垫,那么在内存中它将将此垫存储在一个大小为 3x200x200 的数组中。或者更一般地说,内存中的任何 Mat 都将存储为 channels*rows*cols。我们可以得到这样的数组

double *array = (double)mat.data;

假设矩阵是双精度型

现在我的问题是索引这个数组的方法是什么,例如如果我想访问通道 ch 的元素,行 r 和 col c 是有效的索引

array[ch*rows*cols + c * rows + r]

array[ch*rows*cols + r * cols + c]

问候 阿山

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    正如您在 documentation 上报告的数据布局中看到的,您可以访问以下值:

    for(int r=0; r<rows; ++r){
        for(int c=0; c<cols; ++c){
            for(int ch=0; ch<nchannels; ++ch){
                double val = array[(nchannels*mat.step*r) + (nchannels*c) + ch];
            }
        }
    }
    

    【讨论】:

    • mat.step 是什么?我还没有从文档中找到它的定义。
    • @Raining 看Mat对象的“详细描述”:docs.opencv.org/master/d3/d63/classcv_1_1Mat.html
    • 它只是描述了它是如何使用的,但我仍然很困惑,现在正在寻找更清晰的解释。
    • @Rainning 查看Mat() 的可选step 参数的解释constructor: "每个矩阵行占用的字节数。该值应包括在每行的末尾(如果有)。如果缺少参数(设置为 AUTO_STEP ),则假定没有填充,实际步长计算为 cols*elemSize()。参见 Mat::elemSize。"。所以在这种情况下:cols * sizeof(double)(假设没有填充默认值)。
    【解决方案2】:

    你可以像这样在数组中获取值:

    double val = array+ (r*mat.step)+c*mat.channels()+ch;
    

    【讨论】:

      【解决方案3】:

      我发现其他答案有点令人困惑:mat.step 是以字节为单位的行大小,而不是(双)元素,它确实已经考虑了通道的数量。要访问 val,您应该使用:

      double* array = (double*) mat.data; // was (double) mat.data in the question
      double value = array[ ((mat.step)/mat.elemSize1())*c+mat.channels()*r+ch]; // (mat.step)/mat.elemSize1() is the actual row length in (double) elements
      

      您可以验证此方法和其他方法,将它们与.at&lt;&gt; 运算符进行比较,如下所示:

      #include <iostream>
      #include <opencv2/core.hpp>
      
      using namespace cv;
      using namespace std;
      
      int main()
      {
      const int w0=5;
      const int h=3;
      const int w=4;
      double data[w0*h*3];
      for (int y=0; y<h; y++)
          for (int x=0; x<w0; x++)
              for (int ch=0; ch<3; ch++)
                  data[3*(x+w0*y)+ch]=1000+100*(y)+10*(x)+ch;
      
      Mat m0(h,w0,CV_64FC3, data);
      Rect roi(0,0,w,h);
      Mat mat=m0(roi);
      
      int c=3, r=2, ch=1;
      Vec3d v = mat.at<Vec3d>(r,c);
      cout<<"the 3 channels at row="<<r<<", col="<<c<<": "<<v<<endl;
      double* array= (double*) mat.data;
      double expect = 1000+100*r+10*c+ch;
      double value= array[ ((mat.step)/mat.elemSize1())*r+mat.channels()*c+ch];
      cout<<"row="<<r<<", col="<<c<<", ch="<<ch<<": expect="<<expect<<", value="<<value<<endl;
      return  0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-18
        • 2014-01-07
        • 2016-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多