再来简单的介绍CvMat矩阵数据结构,这边矩阵数据结构就比IplImage数据结构简单些.
CvMat数据结构程序实例
#include <cv.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
float Array[]={1,2,3,4,5,6,7,8,9,10,11,12};
CvMat Matrix1;
Matrix1=cvMat(3,4,CV_32FC1,Array);
printf("The type is : %d\n",Matrix1.type);
printf("The depth is : %d\n",cvCvToIplDepth(Matrix1.type));
printf("The step is : %d\n",Matrix1.step);
printf("The rows is : %d\n",Matrix1.rows);
printf("The cols is : %d\n",Matrix1.cols);
cvmSet(&
Matrix1,1,1,50);
printf("The (1,1) is : %.1f\n\n",cvmGet(&
Matrix1,1,1));
for(int i=0;i<3;i++)
{
for(int j=0;j<4;j++)
{
printf("%.1f\n",Matrix1.data.fl[i*Matrix1.cols+j]);
}
}
system("pause");
}
执行结果:
一 开始,用一个一维数组填入信息,使用cvMat()初始化CvMat数据结构的矩阵类型,给它信道1的二维数组,这里制作了一个3*4的矩阵数据结构,而 实际上,CvMat仍然是存在一维数组里的,要看里面的数据则必须要像IplImage数据结构的使用方法一样,这个程序使用了信道1的矩阵结 构,32bits空间大小,列为3栏为4,Matrix1.type就是这个矩阵CV_8UC1的参数数据代号,是经由OpenCV的内部公式代换出来 的,cvCvToIplDepth()则是可以藉由公式转换回它的bit数(32bits),Matrix1.step则是矩阵空间的cols*参数类型 byte数*Channel数也就是它二维数组栏(Colunm)的总bytes长度,CvMat可以用cvmGet()跟cvmSet()存取数据,但 是他这边只能限定用float(32bits)跟double(64bits)的类型,其他uchar,int,short都不能用,但是CvMat可以 用循环直接存取的方式,而当使用了循环存取数据的方法,因为CvMat数据结构是使用union联集变量的方式,因此数据可以直接跟 uchar,short,int,float,double类型通用,data底下分别代表的变量名称为 ptr(uchar*),s(short*),i(int*),fl(float*),db(double*),但是要注意的是,cvMat()的数组喂 什么数据类型进去就要用什么样的数据类型读出来.
+号以下代表OpenCV常用类型,-号以下表示OpenCV内部使用的数据类型
下面是CvMat数据结构读取3个信道的个别矩阵质实做,与前面的IplImage数据结构相似.
CvMat数据结构读取矩阵数据
#include <cv.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
uchar Array[]={1,1,1,2,2,2,3,3,3,4,4,4,
5,5,5,6,6,6,7,7,7,8,8,8,
9,9,9,10,10,10,11,11,11,12,12,12};
uchar Channel1[3][4];
uchar Channel2[3][4];
uchar Channel3[3][4];
CvMat Matrix1;
Matrix1=cvMat(3,4,CV_8UC3,Array);
for(int i=0;i<3;i++)
{
for(int j=0;j<4*3;j=j+3)
{
Channel1[i][(int)j/3]=Matrix1.data.ptr[i*Matrix1.cols*3+j];
Channel2[i][(int)j/3]=Matrix1.data.ptr[i*Matrix1.cols*3+j+1];
Channel3[i][(int)j/3]=Matrix1.data.ptr[i*Matrix1.cols*3+j+2];
}
}
for(int i=0;i<3;i++)
{
for(int j=0;j<4;j++)
{
printf("%d\n",Channel3[i][j]);
}
}
system("pause");
}
执行结果:
由上面的实例,CvMat数据结构的矩阵数据就可以轻易的读出来啦,要注意的是,使用uchar类型的话data就要用ptr,要不然读出来的数据是错误的,在去考虑它的信道个数来读取数据,因此3个信道的矩阵就可以很轻易的读出来了.
cvMat()
初始化CvMat矩阵数据结构,给它二维数组的维度,第一个为列(row),第二个为栏(column),第三个参数为矩阵参数,第四个参数为一维数组的数据输入,矩阵参数的种类为
CV_8UC1 CV_8SC1 CV_16UC1 CV_16SC1 CV_32SC1 CV_32FC1 CV_64FC1
CV_8UC2 CV_8SC2 CV_16UC2 CV_16SC2 CV_32SC2 CV_32FC2 CV_64FC2
CV_8UC3 CV_8SC3 CV_16UC3 CV_16SC3 CV_32SC3 CV_32FC3 CV_64FC3
CV_8UC4 CV_8SC4 CV_16UC4 CV_16SC4 CV_32SC4 CV_32FC4 CV_64FC4
参数的意义则要去参考前面的命名规则
cvMat(row数目,col数目,矩阵参数,一维数组数据)
cvCvToIplDepth()
输入CvMat的矩阵参数数据,可以得知它的深度,也就是一个矩阵被声明的空间大小,可以参考变量对应的部分做适当的分配
cvCvToIplDepth(CvMat矩阵参数代号数据)
cvmSet()
设立CvMat数据结构内的数值,设立的数值要为double类型,但是它只限订单信道矩阵使用.
cvmSet(CvMat数据结构,row列的数据,col栏的数据,double类型数值)
cvmGet()
取得CvMat数据结构内的数值,取得的数值为double类型,但是它只限订单信道使用.
cvmGet(CvMat数据结构,row列的数据,col栏的数据)