OpenCV统计应用-共变量矩阵 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
共变量(Covariance),为两个随机变数的离均差除以母体个数,可以判断两个事件随机变量的相依性,而单一变量的共变量,那就是变异数(Variance)了,共变量以及变异数简单的定义如下
变异数
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
共变数
而当两随机变量为独立事件的时候
再来提到的是共变量矩阵(Covariance matrix),代表着随机变量所有共变量的种类,以两组随机变量来说所产生的共变量矩阵如下
而三组,四组以上随机变量的共变量矩阵又是不同情形了,在这边,随机变量的个数代表着向量的维度,而他的数对则是同时发生的情形,下面就以坐标的简单例子来示范
这是个维度为2的坐标数组,代表的是一个坐标平面的点集合,而下面就是给它跑cvCalcCovarMatrix()共变量矩阵的计算方法
共变数矩阵1
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
float Coordinates[20]={1.5,2.3,
3.0,1.7,
1.2,2.9,
2.1,2.2,
3.1,3.1,
1.3,2.7,
2.0,1.7,
1.0,2.0,
0.5,0.6,
1.0,0.9};
int main()
{
CvMat *Vector[10];
CvMat *CovarMatrix;
CvMat *AvgMatrix;
IplImage *Image1=cvCreateImage(cvSize(450,450),IPL_DEPTH_8U,3);
Image1->origin=1;
for(int i=0;i<10;i++)
{
Vector=cvCreateMat(1,2,CV_32FC1);
cvSetReal1D(Vector,0,Coordinates[i*2]);
cvSetReal1D(Vector,1,Coordinates[i*2+1]);
cvCircle(Image1,cvPoint((int)(Coordinates[i*2]*100),(int)(Coordinates[i*2+1]*100)),0,CV_RGB(0,0,255),10,CV_AA,0);
}
CovarMatrix=cvCreateMat(2,2,CV_32FC1);
AvgMatrix=cvCreateMat(1,2,CV_32FC1);
cvCalcCovarMatrix((const CvArr **)Vector,10,CovarMatrix,AvgMatrix,CV_COVAR_SCALE+CV_COVAR_NORMAL);
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
printf("%f ",cvGetReal2D(CovarMatrix,i,j));
}
printf("\n");
}
cvNamedWindow("Coordinates",1);
cvShowImage("Coordinates",Image1);
cvWaitKey(0);
}
执行结果:
计算方法:
上面的方法是用个别的向量来实作,向量的维度为2,而图片显示的结果为它们二维坐标的分布情况,cvCalcCovarMatrix()必须给它空的平均值向量矩阵来计算,而cvCalcCovarMatrix()它的参数被定义如下
#define CV_COVAR_SCRAMBLED 0
#define CV_COVAR_NORMAL 1
#define CV_COVAR_USE_AVG 2
#define CV_COVAR_SCALE 4
#define CV_COVAR_ROWS 8
#define CV_COVAR_COLS 16
由上面可以知道,它是由2的N次方所表达的,所以可以用合成参数的方式来表达cvCalcCovarMatrix()的共变量矩阵函式,也就是说,可以用CV_COVAR_SCRAMBLED+CV_COVAR_ROWS的组合,也可以用CV_COVAR_NORMAL+CV_COVAR_USE_AVG+CV_COVAR_ROWS之类的组合,而它所代表的含意分别是
CV_COVAR_SCRAMBLED
一种共变量矩阵的计算方式,不可以与CV_COVAR_NORMAL合用,表达方式如下
这计算方式在OpenCV说明文件提到为Eigenface的计算方式
CV_COVAR_NORMAL
共变量矩阵计算方式,不可与CV_COVAR_SCRAMBLED合用,表达方式如下
这个则是为一般共变量矩阵的计算方式
CV_COVAR_USE_AVG
不用共变量矩阵内建计算平均数的函式,而是自己给予平均数值,可与任何参数共享
CV_COVAR_SCALE
对共变量矩阵的数据做向量个数总和的纯量积,用的是除法计算如下的共变量矩阵
可与任何参数共享,而如果没这参数则是无除以N的计算
CV_COVAR_ROWS
将共变量矩阵的输入值用矩阵的方式表达,而不是用向量的方式,矩阵表达方式以列(Rows)为主,并且参数不可与CV_COVAR_COLS合用
CV_COVAR_COLS
将共变量矩阵的输入值用矩阵的方式表达,而不是用向量的方式,矩阵表达方式以栏(Columns)为主,并且参数不可与CV_COVAR_ROWS共享
共变量矩阵有几个规则,也就是,输入一定要是方阵,平均数的长度要是向量的维度,而平均数的长度也一定要是向量的大小,然后一定要是用单通道CV_32FC1或是CV_64FC1做为输入,cvCalcCovarMatrix()函式,第一个自变量则必须要用(const CvArr **)强制型别转换,第二个自变量为输入向量的数目,第三个自变量为空的或是非空平均数向量,第四个自变量为cvCalcCovarMatrix()这函式要输入的参数,而下面,则是使用矩阵方式表达共变量矩阵的范例
共变数矩阵2
#include <cv.h>
#include <stdio.h>
#include <stdlib.h>
float Coordinates[20]={1.5,2.3,
3.0,1.7,
1.2,2.9,
2.1,2.2,
3.1,3.1,
1.3,2.7,
2.0,1.7,
1.0,2.0,
0.5,0.6,
1.0,0.9};
int main()
{
CvMat *Vector[1];
CvMat *Vector1;
CvMat *CovarMatrix;
CvMat *avg;
Vector1=cvCreateMat(10,2,CV_32FC1);
cvSetData(Vector1,Coordinates,Vector1->step);
Vector[0]=Vector1;
CovarMatrix=cvCreateMat(2,2,CV_32FC1);
avg=cvCreateMat(1,2,CV_32FC1);
cvCalcCovarMatrix((const CvArr **)Vector,10,CovarMatrix,avg,CV_COVAR_SCALE+CV_COVAR_NORMAL+CV_COVAR_ROWS);
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
printf("%f ",cvGetReal2D(CovarMatrix,i,j));
}
printf("\n");
}
system("pause");
}
执行结果:
上面的程序代码,如果想用矩阵来表达向量的方式计算共变量矩阵,就必须要将第一个自变量设为二维数组当做输入,输入的方式就如上面程序的写法,而其它地方则是没什么差异.
共变量矩阵在OpenCV内,不但可以做到计算主成分分析(Principal Cmponents Analysis,PCA),以及另一个Mahalanobis距离的计算
cvCalcCovarMatrix()
计算共变量矩阵,输入可为多个IplImage或CvMat数据结构,可输入高维度数据的向量,有多种输入方式,在数据输入方面,可以用单一CvMat数据结构,以列(Rows)为主或以行(Columns)为主,使用CV_COVAR_ROWS以及CV_COVAR_COLS的参数输入,而要做多个IplImage或CvMat数据结构输入则不需提供CV_COVAR_ROWS,CV_COVAR_COLS的参数,在计算方面,又分为以维度为主的共变量矩阵参数输入CV_COVAR_NORMAL以及以个数为主的共变量矩阵CV_COVAR_SCRAMBLED,而他也可一自行定义平均值CV_COVAR_USE_AVG,以及除以是否除以共变量矩阵的共变量个数CV_COVAR_SCALE,而这些参数可以自行组合运算,第一个自变量为输入目标向量,第二个自变量为输出目标共变量矩阵,第三个自变量为输入或输出平均数向量,第四个自变量为cvCalcCovarMatrix()共变量计算函式的参数输入
cvCalcCovarMatrix(输入多个IplImage或CvMat数据结构,输出目标共变量矩阵,输入/出平均数向量,共变量矩阵参数或代号)
文章评论(0条评论)
登录后参与讨论