初探step
在一篇博文中对type、depth、step这三个成员变量有比较清晰的解释,阅读后对step这个成员仍然存在一些疑惑,因此将自己观察到的信息记录下来,方便后续回忆。
-
疑惑1:step的用法?
第一次看到step,第一反应会是,是什么?怎么用?所以先介绍step这个变量怎么来用。
Mat last_img= imread("D:\\pic-test\\img1.png", 1);
cout << last_img.step[0] << " " << last_img.step[1] << " " << last_img.step[2] << " " << endl;
根据opencv的文档可知通常以step[i]的方式进行取值,因此这引出了第二个疑惑;
-
疑惑2:step[0]、step[1]、step[2]代表了什么意思?
为了说明这个问题,疑惑2中图片和代码借用了“太平洋上的冰山”发布的博文中的图片和代码,因为博主给图片和代码非常典型且能说明问题,谢谢博主~
- 为了解释清楚疑惑2,我们需要先了解 step 是做什么用的?
上图清晰的表明了,step 是为了更好的帮助我们查找元素o(x,y,z)在矩阵M中的位置而设置的,借助step,我们可以快速定位元素o在M中的地址,从而通过访问地址的方式完成对元素的操作,来提高我们的编程效率。
- 搞清楚step的作用后,我们就可以去理解step[i]表示的是什么意思?
int dim[3]={3,3,3};
Mat src(3,dims,CV_16SC2,Scalar_<short>(1,2);
cout<<"step[0]:"<<src.step[0]<<endl;
cout<<"step[1]:"<<src.step[1]<<endl;
cout<<"step[2]:"<<src.step[2]<<endl;
以上面代码为例,Mat中存储的数据类型为:2通道16字节short类型,Mat为3*3*3的三维数组,那么:
step[0]=(3*3)*(16*2/8bit)=36byte; //step[0]为面的大小
step[1]=3*(16*2/8bit)=12byte; //step[1]为线的大小
step[2]=1*(16*2/8bit)=4byte; //step[2]为点的大小
当我们想获得元素(1,2,1)的地址时:addr=step[0]*1,step[1]*2+step[2]*1;
-
疑惑3: Mat对象由picture构造时,step怎么使用?
我们常见的图像(.jpg,.bmp等),在opencv中打开都属于二维图像,因此
step[0]=cols*channels;//一行元素所占size
step[1]=channels;//一个元素所占size
对(x,y)定位为:addr=step[0]*x+step[1]*y;
-
疑惑4:step和step[1]之间的关系?
首先打印step和step[1]、step[2]的地址,发现,这三个地址之间相差8个单位;说明step和step[1]并不是同一个变量
打印step、step[1]的数值发现,这两个值相同,都为640*3=1920,说明step,step[1]代表的含义相同,至少在二维图像中,我们可以将step==step[1]。