OpenCV统计应用-共变数矩阵

共变数(Covariance),为两个随机变数的离均差除以母体个数,可以判断两个事件随机变数的相依性,而单一变数的共变数,那就是变异数(Variance)了,共变数以及变异数简单的定义如下

变异数:

共变数:

而当两随机变数为独立事件的时候

再来提到的是共变数矩阵(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[i]=cvCreateMat( 1 , 2 ,CV_32FC1);
cvSetReal1D(Vector[i], 0 ,Coordinates[i* 2 ]);
cvSetReal1D(Vector[i], 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( "%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资料结构,输出目标共变数矩阵,输入/出平均数向量,共变数矩阵参数或代号) 
 

 

 

posted on 2009-02-08 21:56  oskycar  阅读(2781)  评论(0编辑  收藏  举报

导航