一、基础概念
1、data:unchar类型的指针,指向Mat矩阵的首地址,可以理解为表示一个房屋的门牌号。
2、elemSize:
elem是element(元素)的缩写,表示矩阵中每一个元素的数据大小,如果Mat中的数据类型是CV_8UC1,那么 elemSize==1;如果是CV_8UC3或CV_8SC3,那么elemSize==3;如果是CV_16UC3或者CV_16SC3,那么 elemSize==6;即elemSize是以8位(一个字节)为一个单位,乘以通道数和8位的整数倍
可以理解为整个房间可以睡多少人,这个时候就得累计上房间内所有床位数(通道)和每张床的容纳量了;
3、step:
step这里指出的是图像在各个梯级上的字节数大小,而这里的梯级指的是构成图像的名层次。 上图三维图像由一个一个名面(第一级)构成,每一个平面由一行一行(第二级)构成,每行由一个一个点(第三级)构成。 同理:二维图像由一行一行(第一级)构成,而每一行又由一个一个点(第二级)构成。 Mat中的step[0]就是我们每一个第一级,在内存中占据的字节数量。例如,二维图像中step[0]就是每一行(第一级)在矩阵内存中,占据的字节的数量。也就是说step[i]就是第i+1级在矩阵内存中占据的字节的数量。 M 数组的数据布局是由阵列 M.step[]定义的,使元素的地址(i0,。。。。iM.dims-1),其中 0<= ik < M.size [k],可以计算为: addr( Mi0 ;:::;iM.dims-1) = M.data+ M.step[ 0]*i0 + M.step[ 1] *i1 + .…+ M.step[ M:dims- 1] iM:dims- 1 2维的数组的情况下根据上述公式被减至: addr( Mi,j)= M.data+ M.step[ 0]*i+ M.step[ 1] *j
// 此代码展示将彩色图转换为灰度图 #include<iostream> #include<opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { Mat src = imread("C:/Users/lenovo/Pictures/Saved Pictures/Lena.png"); Mat dst; cv::Size size = src.size(); typedef double pixel_t; // 定义像素类型 if (dst.empty()) dst.create(size, CV_64F); uchar* srcData = src.data; pixel_t* dstData = (pixel_t*) dst.data; int dstStep = dst.step / sizeof(dstData[0]); // sizeof(dstData[0])=8,因为像素数据类型为double, 64位,8字节. int srcStep = src.step / sizeof(srcData[0]); // step表示每行的字节数 int numRow = src.rows; int numCol = src.cols; int numChannel = src.channels(); cout << "numRow:" << numRow << endl; cout << "numCol:" << numCol << endl; cout << "src.channels:" << numChannel << endl; cout << "src.step:" << src.step << endl; cout << "sizeof(dstData[0]):" << sizeof(dstData[0])<<" "<<"dstStep:"<< dstStep << endl; cout << "sizeof(srcData[0]):" << sizeof(srcData[0]) <<" "<<"srcStep:"<< srcStep <<endl; for (int j = 0; j < src.cols; j++) { for (int i = 0; i < src.rows; i++) { double b = *(srcData + src.step*i + src.channels() * j + 0) / 255.0; double g = *(srcData + src.step*i + src.channels() * j + 1) / 255.0; double r = *(srcData + src.step*i + src.channels() * j + 2) / 255.0; *(dstData + dstStep*i + dst.channels()*j) = (b + g + r) / 3; } } cv::imshow("image", dst); waitKey(); }代码运行结果:
Ref:
1、https://blog.csdn.net/dcrmg/article/details/52294259(Opencv Mat矩阵中data、size、depth、elemSize、step等属性的理解)
2、https://blog.csdn.net/qianqing13579/article/details/45318279(OpenCV中Mat属性step,size,step1,elemSize,elemSize1)
3、https://blog.csdn.net/lanmeng_smile/article/details/47864615(opencv的Mat中step)