OpenCV经常用到的几个Mat的属性,但是每次用到都要查一下,今天直接弄清楚些。
首先要明白几个计算机基础的基本概念:
Bit意为“位”或“比特”,是计算机运算的基础,属于二进制的范筹;
Byte意为“字节”,是计算机文件大小的基本计算单位;
这两者应用的场合不同。通常用bit来作数据传输的单位,因为物理层,数据链路层的传输对于用户是透明的,而这种通信传输是基于二进制的传输。在应用层通常是用byte来作单位,表示文件的大小,在用户看来就是可见的数据大小。比如一个字符就是1byte,如果是汉字,则是2byte。
下面是2个具体应用实例:
Mbps=mega bits per second(兆位/秒)是速率单位,
MB=mega bytes(兆比、兆字节)是量单位,1MB/S(兆字节/秒)=8MBPS(兆位/秒)。
我们所说的硬盘容量是40GB、80GB、100GB,这里的B指是的Byte也就是“字节”。(与容量相关,应用层)
1 bit = 1 二进制数据
1 byte = 8 bit
1 字母 = 1 byte = 8 bit
1 汉字 = 2 byte = 16 bit
1Byte=8Bit=1字节
1字=2字节
1 KB = 1024 bytes =2^10 bytes
1 MB = 1024 KB = 2^20 bytes
1 GB = 1024 MB = 2^30 bytes
USB2.0标准接口传输速率是480兆位/秒,即480MBps。这里的B指是的Bit也就是“位”。(与传输相关,底层)
注:另外,Byte通常简写为B(大写),而bit通常简写为b(小写)。可以这么记忆,用大写的就是数据值比较大的位,而小字的就是数据值比较小的字节,1B=8b。
字节和字长的区别:由于常用的英文字符用8位二进制就可以表示,所以通常就将8位称为一个字节。字长的长度是不固定的,对于不同的CPU、字长的长度也不一样。8位的CPU一次只能处理一个字节,而32位的CPU一次就能处理4个字节,同理字长为64位的CPU一次可以处理8个字节。
理解字长、字节、位的概念以后,对下列的问题应该会更加清晰一些
step1(i):每一维元素的通道数
step[i]:每一维元素的大小,单位字节
size[i]:每一维元素的个数
elemSize():每个元素大小,单位字节
elemSize1():每个通道大小,单位字节
按照代码实例来看一下
#include <iostream>
#include <opencv/highgui.h>
using namespace cv;
void Learn_Mat_Definiton()//测试一下step[]的各个维度大小
{
//Demo1(3维矩阵)///
printf("//Demo1(3维矩阵)\n");
//最后面的两个数:(行,列),确定了一个面
//是一个依次降维的过程
//8,10组成了面,5个面,组成了立方体
int matSize[] = {5,8,10};//每一维元素的个数:8:行,10:列
Mat mat1(3,matSize, CV_16UC3, Scalar::all(0));
//求step[i]的大小:每一维元素的大小(单位字节)
printf("\n///step[i]的大小//\n");
printf("step[0]:%d\n",mat1.step[0]);//480:面的大小(第一维)
printf("step[1]:%d\n",mat1.step[1]);//60:线的大小(第二维)
printf("step[2]:%d\n",mat1.step[2]);//6:点的大小(第三维)
//求size[i]:每一维元素的个数
printf("\n///size[i]的大小///\n");
printf("size[0]:%d\n",mat1.size[0]);//5:面
printf("size[1]:%d\n",mat1.size[1]);//8:线
printf("size[2]:%d\n",mat1.size[2]);//10:点
//求step1(i):每一维元素的通道数
printf("\n///step1(i)的大小///\n");
printf("step1(0):%d\n",mat1.step1(0));//240:面
printf("step1(1):%d\n",mat1.step1(1));//30:线
printf("step1(2):%d\n",mat1.step1(2));//3:点
//求elemSize:每个元素的大小(单位字节)
printf("\n///elemSize的大小///\n");
printf("elemSize:%d\n",mat1.elemSize());//6:每个元素的大小
//求elemSize1:每个通道的大小(单位字节)
printf("\n///elemSize1的大小///\n");
printf("elemSize1:%d\n",mat1.elemSize1());//2:每个通道的大小
}
int main() {
std::cout << "Hello, OpenCV!" << std::endl;
Learn_Mat_Definiton();
return 0;
}
编译出的结果如下:
我们先看第一组step[i],其实如果倒着看理解会更加深刻一些,首先定义的每个元素是CV_16UC3,16bits,3通道,所以对应每个元素的大小是
step[2] = 16/8*3=6 bytes
step[1]:对应的是线的大小,第二维的元素的大小,也就是二维矩阵每一行的大小,所以
step[1] = 10*6 = 60 bytes
step[0]:对应的是面的大小,每一行的大小再乘以行数
step[0] = 60*8 = 480 bytes
第二组size[i]的大小,
size[0] = 5
size[1] = 8
size[2] = 10
因为
step1[i] = step.p[i]/elemSize1();
就先看一下elemSize和elemSize1的具体含义
elemSize 表示每个元素的大小(单位是字节),每个元素可能有多个通道,按照代码中对应的定义,每个元素有三个通道,每个通道类型为CV_16U,所以3个通道的总数是6,和step[2]的数值相等。
elemSize1 每个通道的大小(单位字节),CV_16=2字节
所以规整化的step1[i]分别为:
step1[0] = step[0]/elemSize1 = 240 bytes
step1[1] = step[1]/elemSize1 = 30 bytes
step1[2] = step[2]/elemSize1 = 3 bytes
一次性弄弄清楚,每次都查一下,得不偿失O(∩_∩)O哈哈~
参考地址:
[1]https://blog.csdn.net/panjunnn/article/details/5611241
[2]https://blog.csdn.net/qianqing13579/article/details/45318279
[3]https://blog.csdn.net/Sunshine_in_Moon/article/details/45268971