OpenCV:CvMat结构体
1、1.CvMat结构体:多通道矩阵、矩阵头
typedef struct CvMat
{
int type;
//数据类型,比如CV_32FC1含义是32位浮点型单通道,
// 再比如CV_8UC3含义是8位无符号整型三通道 int step;//以字节为单位的行数据长度:元素个数*元素类型的字节长度
/* for internal use only */
int* refcount;//数据引用计数
inthdr_refcount;
union
{
//指向data数据的第一个元素
uchar* ptr;//无符号类型
short* s;//短整型
int* i;//整型
float* fl;//浮点
double* db;//双精度
} data;//共同体data,里面成员公用一个空间,也就是说数据类型可以有这五种。
#ifdef __cplusplus
union
{
int rows;//行
int height;//高
};
union
{
int cols;//列
int width;//宽
};
#else
int rows;
int cols;
#endif
}CvMat;

2、2.CvMat的基本操作:
①CvMat* cvCreateMat(int rows, int cols, int type);
功能:分配矩阵空间
参数:type: 矩阵元素类型,格式为CV_<bit_depth>(S|U|F)C<number_of_channels>.
CV_8UC1 表示8位无符号单通道矩阵,
CV_32SC2表示32位有符号双通道矩阵.
②cvReleaseMat(&M):释放矩阵空间
CvMat* M = cvCreateMat(4,4,CV_32FC1);
cvReleaseMat(&M);
③cvCloneMat复制矩阵:
CvMat* M1 = cvCreateMat(4,4,CV_32FC1);
CvMat* M2;
M2=cvCloneMat(M1);
③cvMat初始化矩阵:
double a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
CvMat Ma=cvMat(3, 4, CV_64FC1, a);
④cvInitMatHeader始化矩阵头:
CvMat Ma;
cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a);
⑤cvSetData( CvArr* arr, void* data, int step );矩阵赋值
⑥void cvCopy( constCvArr* src, CvArr* dst, constCvArr* mask=NULL );
⑦cvmSet( CvMat* mat,int row,int col,double value ):逐点赋值







3、矩阵计算
①:矩阵与矩阵:+、-、*运算
CvMat *Ma,*Mb,*Mc;
cvAdd(Ma,Mb,Mc);//Ma+Mb-->Mc
cvSub(Ma,Mb,Mc);// Ma-Mb-->Mc
cvMatMul(Ma,Mb,Mc);// Ma*Mb->Mc
②:按元素的矩阵操作:.*、./、
CvMat *Ma,*Mb,Mc;
cvMul(Ma,Mb,Mc);//Ma .* Mb-->Mc对应元素相乘
cvDiv(Ma,Mb,Mc);//Ma ./ Mb-->Mc对应元素相除
cvAddS(Ma,cvScalar(-10.0),Mc);//Ma.-10-->Mc
③:向量乘积:
double va[] = {1, 2, 3};
double vb[] = {0, 0, 1};
double vc[3];
CvMat Va=cvMat(3, 1, CV_64FC1, va);
CvMat Vb=cvMat(3, 1, CV_64FC1, vb);
CvMat Vc=cvMat(3, 1, CV_64FC1, vc);
double res=cvDotProduct(&Va,&Vb); // 点乘: Va . Vb -> res
cvCrossProduct(&Va, &Vb, &Vc); // 向量积: Va x Vb -> Vc
【注】:Va,Vb,Vc在向量积中向量元素个数须相同.

4、4.CvMat矩阵方程:
①:单矩阵操作
CvMat *Ma, *Mb;
//注:不能对自身进行转置
cvTranspose(Ma, Mb); // transpose(Ma) -> Mb
CvScalar t = cvTrace(Ma); // trace(Ma) -> t.val[0]
double d = cvDet(Ma); // det(Ma) -> d 行列式
cvInvert(Ma, Mb); // inv(Ma) -> Mb
②:非齐次线性方程求解:
CvMat* A = cvCreateMat(3,3,CV_32FC1);
CvMat* x = cvCreateMat(3,1,CV_32FC1);
CvMat* b = cvCreateMat(3,1,CV_32FC1);
cvSolve(&A, &b, &x); // solve (Ax=b) for x
③特征值分析(针对对称矩阵):
CvMat* A = cvCreateMat(3,3,CV_32FC1);
CvMat* E = cvCreateMat(3,3,CV_32FC1);
CvMat* l = cvCreateMat(3,1,CV_32FC1);
cvEigenVV(&A, &E, &l); // l = A的特征值 (降序排列) , E = 对应的特征向量 (每行)
④:奇异值分解SVD:
CvMat* A = cvCreateMat(3,3,CV_32FC1);
CvMat* U = cvCreateMat(3,3,CV_32FC1);
CvMat* D = cvCreateMat(3,3,CV_32FC1);
CvMat* V = cvCreateMat(3,3,CV_32FC1);
cvSVD(A, D, U, V, CV_SVD_U_T|CV_SVD_V_T); // A = U D V^T

5、5.CvMat、IplImage、Mat相互转换
如下所示:



6、6.CvMat矩阵数据访问:
CvMat中type:CV_<bit_depth>(S|U|F)channels,S
其中,S表示有符号的,U表示无符号的,F表示浮点数;
比如CV_32F1,表示32位1通道浮点数;
CV_8U3,表示8位无符号3通道整形;
type:决定了CvMat数据的分布,
比如,若元素类型CV_8U1,则CvMat数据排列是每行按照ggggggg格式排列;
若元素类型CV_8UC3,则表示彩色图像,其行排列为bgrbgrbgr;
