CvMat矩阵数据结构是OpenCV的基础数据类型,对于图像处理这种密级型运算,经常需要访问,修改,设置其元素的值。OpenCV提供了很多优良的函数,能够很简单的实现上述功能。在《学习OpenCV》一书中,作者分别就简单的方法,麻烦的方法,和恰当的方法对相关函数进行了讲解,讲得比较清晰。本文主要讲解通过指针高效访问CvMat元素的方法z及平时容易忽视的一些小问题。
CvMat* mat;
mat = cvCreateMat(9,10,CV_64FC3);//注意所申请矩阵元素的类型,不同的类型访问操作方法不同,但类似可推导,以此为例。
opencv中的多通道矩阵CvMat元素的访问方法总结如下:
1.
mat(i,j,1): *(mat->data.db + i*(mat->step/8) + 3*j);//.db为double数据类型,step类型为int,代表矩阵每行的字节数,因此要处以sizeof(double) =8。
mat(i,j,2): *(mat->data.db + i*(mat->step/8) + 3*j+1);
mat(i,j,3): *(mat->data.db + i*(mat->step/8) + 3*j+2);
基本模式: *(mat->data.类型 + 行号*(该类型数据对应的一行的步长要按照该类型的长度来运算)+按照该类型来说的列数+所取的通道数)
2.
mat(i,j,1): ((double*)(mat->data.ptr+i*mat->step))[3*j];//ptr的类型为uchar*,step类型为int,代表矩阵每行的字节数。另外指针可以当做数组名,因此可以这样操作。
mat(i,j,2): ((double*)(mat->data.ptr+i*mat->step))[3*j+1];
mat(i,j,3): ((double*)(mat->data.ptr+i*mat->step))[3*j+2];
基本模式:((强转类型*)(mat->data.ptr+行号*mat->step))[3*列号+所取的通道数]
3.
mat(i,j,1): *( (double*)(mat->data.ptr+i*mat->step) + 3*j );//根据以上也可以这样
总之就是C语言中的指针操作啦,要注意指针的类型,以及step的单位是字节就可以了。
4.运用CV_MAT_ELEM宏来访问
mat(i,j,3): CV_MAT_ELEM(mat,double,i,3*j+2)
该方法最方便。
另外,实验测试发现,mat中数据一般不支持类似于二维数值的双中括号访问,比如
mat->data.db[i][j] 是不支持的。而一般只支持单个中括号的访问,即:
mat->data.db[i*mat->step/sizeof(double)+j]
自己的几点体会: