原创 OpenCV统计应用-共变量矩阵

2009-2-21 23:44 4245 8 8 分类: 软件与OS

OpenCV统计应用-共变量矩阵 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


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

变异数
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />62d0f9b4-4e55-4d9b-b6af-d3dd399a69d5.jpg

共变数
41d1697e-445e-4954-8ed8-72a745b5332a.jpg

而当两随机变量为独立事件的时候
aa3ae13d-2d5b-48c2-b9d2-f429aa751cd6.jpg

再来提到的是共变量矩阵(Covariance matrix),代表着随机变量所有共变量的种类,以两组随机变量来说所产生的共变量矩阵如下
3363d306-e0b1-472a-bc89-24aa94f6e1fa.jpg

而三组,四组以上随机变量的共变量矩阵又是不同情形了,在这边,随机变量的个数代表着向量的维度,而他的数对则是同时发生的情形,下面就以坐标的简单例子来示范
f28d6f67-db80-423b-ae1b-ee033c3a6446.jpg

这是个维度为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);
}

执行结果:
080b534a-2a68-4fed-a26d-6ae98805c1a6.jpg

计算方法:
8fa0d343-32e9-434c-9e3b-90f1c0694849.jpg

上面的方法是用个别的向量来实作,向量的维度为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

由上面可以知道,它是由2N次方所表达的,所以可以用合成参数的方式来表达cvCalcCovarMatrix()的共变量矩阵函式,也就是说,可以用CV_COVAR_SCRAMBLED+CV_COVAR_ROWS的组合,也可以用CV_COVAR_NORMAL+CV_COVAR_USE_AVG+CV_COVAR_ROWS之类的组合,而它所代表的含意分别是

CV_COVAR_SCRAMBLED
一种共变量矩阵的计算方式,不可以与CV_COVAR_NORMAL合用,表达方式如下
a21a23da-5d8c-46ad-87e7-20cb5cef608f.jpg
这计算方式在OpenCV说明文件提到为Eigenface的计算方式

CV_COVAR_NORMAL
共变量矩阵计算方式,不可与CV_COVAR_SCRAMBLED合用,表达方式如下
4280eeea-042e-42cd-98ac-c3752a064af2.jpg
这个则是为一般共变量矩阵的计算方式

CV_COVAR_USE_AVG
不用共变量矩阵内建计算平均数的函式,而是自己给予平均数值,可与任何参数共享

CV_COVAR_SCALE
对共变量矩阵的数据做向量个数总和的纯量积,用的是除法计算如下的共变量矩阵


55deb50f-9105-4e68-a600-6438159f8bae.jpg
可与任何参数共享,而如果没这参数则是无除以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");
}

执行结果:


cab3d3d6-94d1-4ebb-9580-a4bd538a76b7.jpg

上面的程序代码,如果想用矩阵来表达向量的方式计算共变量矩阵,就必须要将第一个自变量设为二维数组当做输入,输入的方式就如上面程序的写法,而其它地方则是没什么差异.

共变量矩阵在OpenCV,不但可以做到计算主成分分析(Principal Cmponents Analysis,PCA),以及另一个Mahalanobis距离的计算

cvCalcCovarMatrix()
计算共变量矩阵,输入可为多个IplImageCvMat数据结构,可输入高维度数据的向量,有多种输入方式,在数据输入方面,可以用单一CvMat数据结构,以列(Rows)为主或以行(Columns)为主,使用CV_COVAR_ROWS以及CV_COVAR_COLS的参数输入,而要做多个IplImageCvMat数据结构输入则不需提供CV_COVAR_ROWS,CV_COVAR_COLS的参数,在计算方面,又分为以维度为主的共变量矩阵参数输入CV_COVAR_NORMAL以及以个数为主的共变量矩阵CV_COVAR_SCRAMBLED,而他也可一自行定义平均值CV_COVAR_USE_AVG,以及除以是否除以共变量矩阵的共变量个数CV_COVAR_SCALE,而这些参数可以自行组合运算,第一个自变量为输入目标向量,第二个自变量为输出目标共变量矩阵,第三个自变量为输入或输出平均数向量,第四个自变量为cvCalcCovarMatrix()共变量计算函式的参数输入
cvCalcCovarMatrix(
输入多个IplImageCvMat数据结构,输出目标共变量矩阵,输入/出平均数向量,共变量矩阵参数或代号)
 


 

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条