OpenCV学习:Mat类详细解析+源码剖析(四)MSize类和Mstep类

Msize类和MStep类是Mat的内部嵌套类:

class CV_EXPORTS Mat
{
public:
    ......
    struct CV_EXPORTS MSize
    {
        MSize(int* _p);
        ......
        int* p;
    };
    struct CV_EXPORTS MStep
    {
        MStep();
        ......
        size_t* p;
    };
    MSize size;
    MStep step;
    ......
};
size和step成员变量为了方便矩阵访问。其中size记录了矩阵中每一维的维数,step记录了每一维中数据量。下面详细分析:

矩阵如何存储:

一维矩阵很简单,就是数组;二维矩阵可以看作数组的数组,即数组的每一个元素都是数组;三维矩阵可以看作数组的二维矩阵,即二维矩阵的每一个元素都是数组;同理,四维,.....,n维。如下图所示:


上面一幅矩阵图只是矩阵在人脑中的形式化表现,在计算机中,无论是一维数组、二维矩阵、三维还是n维,它在内存中的表示只有一种,那就是:

OpenCV学习:Mat类详细解析+源码剖析(四)MSize类和Mstep类_第1张图片

不同维度的数组在内存中的存储方式如下图所示:


因此,对于矩阵来说,维度信息是必须的,Mat类中矩阵的维度信息存储在成员变量size中。还有一个大问题,如何定位矩阵中的元素,维度之间步长的确定!

维数 表示方法            编译器处理后表示方法
1 a[i] a[i]
2 a[i][j] a[i*len2+j]
3 a[i][j][k] a[i*len2*len3+j*len3+k]
... ... ...
n a[i][j][k]...[w] a[i*len2*len3*...*lenn+...w]
其中leni表示第i维的长度

对上表格作简单解释:

一维自不必说;二维空间,一维中每个“槽”包含len2个元素;三维空间中,一维中每个槽包含len2×len3个元素。所以以三维空间定位到(i,j,k)为例,结合矩阵在内存中的存储模式,首先i×len2×len3定位到了该点在一维空间的位置,然后j×len3定位到了该点在二维空间中的位置,最后k定位到了该点在三维空间中的位置。以上分析可知,len2×len3就是一维空间中相邻两个“槽”间的步长len3是二维空间中相邻两“槽”的步长。两过程如下图,

OpenCV学习:Mat类详细解析+源码剖析(四)MSize类和Mstep类_第2张图片

不同维度中相邻两个“槽”间的步长很重要,Mat类中以step数据成员存储步长,把这些步长存储起来可以方便编程。下面是Mat类中三维矩阵的ptr函数(该函数通过第1、2维坐标,得到第三维数据的首地址)

template inline const _Tp* Mat::ptr(int i0, int i1) const
{
    return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1]);
}
上面程序中,data是矩阵首地址,其中step.p[0]中存储第一维空间槽间步长,step.p[1]存储第二维空间槽间步长。经过 data + i0*step.p[0] + i1*step.p[1] 操作,数据指针从矩阵首地址-->二维空间首地址-->三维空间首地址。然后直接可以运用(ptr(i,j))[k]获取矩阵元素了。

综上可以对步长做如下定义:对于n维矩阵M,第i维空间步长是i后各维数据长度的乘积。即第一维步长step1=len2×len3×...×lenn,第二维步长step2=len3×...×lenn。

下面通过size和step的初始化过程验证下以上分析:

for( i = _dims-1; i >= 0; i-- )//
{
      int s = _sz[i];  //_sz[]中存储矩阵各维度大小 
      m.size.p[i] = s; //初始化size
      ......
      {
       m.step.p[i] = total;//初始化 step (注意total的计算方式!就是以上step的定义!)
       int64 total1 = (int64)total*s;// i*len3*len2+j*len3
       total = (size_t)total1;
      }
      ......
  }

 综上:Mat类中step成员存储维度的步长,size成员存储维度大小。

你可能感兴趣的:(OpenCV,OpenCV学习)