OpenCV中Mat类成员data、dims、step、depth()、channels()、elemSize()等解析

cv:Mat是OpenCV中最重要的数据存储类,几乎可以存储所有的矩阵数据(包括2维图片数据)。

cv::Mat
The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array. It can be used to store (Mat类用于表示一个多维度的密集的单通道或多通道的数值数组,能用于存储):

  • real or complex-valued vectors or matrices (实数值或复合值向量、矩阵)
  • grayscale or color images (灰度图或者彩色图)
  • voxel volumes (立体元素)
  • vector fields (矢量场)
  • point clouds (点云)
  • tensors (张量)
  • histograms (though, very high-dimensional histograms may be better stored in a SparseMat ) (直方图,高纬度的最好存放在SparseMat中)

矩阵 (M) 中数据元素的地址计算公式:
addr(Mi0,i1,…im-1) = M.data + M.step[0] * i0 + M.step[1] * i1 + … + M.step[m-1] * im-1 (其中 m = M.dims,即M的维度)

重要的类成员:

  • data:数据存储的起始地址 (uchar*类型);
  • dims:矩阵维度。如 3 * 4 的矩阵为 2 维, 3 * 4 * 5 的为3维;
  • channels():通道数量,矩阵中表示一个元素所需要的值的个数。例:3 * 4矩阵中共有12个元素,如果每个元素需要3个值表示,那么此矩阵的通道数为3。常见的是一张彩色图片有B蓝、G绿、R红3个通道;
  • depth():深度,即表示单通道中元素值的位数(bits)。Mat.depth()返回的是一个 0~6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;
  • elemSize() : 单个元素在所有通道中大小之和,elemSize() = sizeof(数据类型) * channels()。如果Mat中的数据的数据类型是 CV_8U 那么 elemSize() = 1;CV_8UC3 那么 elemSize() = 3,CV_16UC2 那么 elemSize() = 4;
  • elemSize1() : 单个元素在1个通道中的大小。elemSize1() = sizeof(数据类型) = elemSize()  / channels()。 
  • step[]:可以看作是一个有dims个元素的动态数组,定义了矩阵的在各维度之间跳变时的最大步长(单位:字节。如2维Mat时,step[0]表示行长度,step[1]表示元素长度)。
  • step1(n):与step[n]对应范围的总通道数, step1(n) = step[n] / elemSize1();

实例分析1:2维情况(stored row by row)按行存储

上面是一个 3 * 4 的2维矩阵(线 * 点),有:

  • M.dims = 2;   
  • M.rows = 3;   
  • M.cols = 4;

假设其数据类型为 CV_8U,是单通道的 uchar 类型,那么:

  • M.depth() = 0;
  • M.channels() = 1; 
  • M.elemSize1() = sizeof(uchar) = 1;
  • M.elemSize() = M.elemSize1() * M.channels() = 1 * 1 = 1; 
  • M.step[]数组有两个元素。M.step[0]表示每行数据的大小,M.step[1] 表示每个数据元素的大小;
  • M.step[0]  = M.elemSize() * M.cols = 1 * 4 = 4 ; 
  • M.step[1]  = M.elemSize() = 1;
  • M.step1(0) = M.step[0] / M.elemSize1() = 4; 
  • M.step1(1) = M.step[1] / M.elemSize1() = 1。

假设上面的矩阵数据类型是 CV_8UC3,是3通道的 uchar 类型,那么:

  • M.depth() = 0;
  • M.channels() = 3; 
  • M.elemSize1() = sizeof(uchar) = 1;
  • M.elemSize() = M.elemSize1()  * M.channels() = 1 * 3 = 3; 
  • M.step[]数组有两个元素。M.step[0]表示每行数据的大小,M.step[1] 表示每个数据元素的大小;
  • M.step[0]  = M.elemSize() * M.cols = 3 * 4 = 12 ; 
  • M.step[1]  = M.elemSize() = 3;
  • M.step1(0) = M.step[0] / M.elemSize1() = 12 / 1 = 12; 
  • M.step1(1) = M.step[1] / M.elemSize1() = 3 / 1 = 3。


实例分析2:3维情况(stored plane by plane)按面存储

上面是一个 3 * 4 * 6 的3维矩阵(面 * 线 * 点),有:

  • M.dims = 3;   
  • M.rows = 4;   
  • M.cols = 6;

假设其数据类型为 CV_16SC4,是4通道的 short 类型,那么:

  • M.depth() = 3;
  • M.channels() = 4 ;
  • M.elemSize1() = sizeof(short) = 2 ;
  • M.elemSize() = M.elemSize1() * M.channels() = M.step[M.dims-1] = M.step[2] = 2 * 4 = 8;
  • M.step[0] = M.rows * M.cols * M.elemSize() = 4 * 6 * 8 = 192;
  • M.step[1] = M.cols * M.elemSize() = 6 * 8 = 48;
  • M.step[2] = M.elemSize() = 8;
  • M.step1(0) = M.step[0] / M.elemSize1() = 192 / 2 = 96 (第1维度(面)的总通道数);
  • M.step1(1) = M.step[1] / M.elemSize1() = 48 / 2 = 24(第2维度(线)的总通道数);
  • M.step1(2) = M.step[2] / M.elemSize1() = M.channels() = 4(第3维度(点)的总通道数);
  • 10
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值