matlab 用OpenCV计算协方差矩阵

mutmk8jj  于 2023-03-13  发布在  Matlab
关注(0)|答案(3)|浏览(211)

我尝试使用opencv的cv::calcCovarMatrix来获得协方差矩阵,我创建了一个虚拟测试用例:

A = [1 2; 3 4] // matlab style 
B = [1 0; 5 8]

如果我用matlab运行这个,我得到:

>> cov(A,B)
ans =
1.6667    4.3333
4.3333   13.6667

根据我的计算,这似乎是可以的,但当我使用cv::calcCovarMatrix时,我无法获得相同的结果:

cv::Mat covar, mean;
cv::Mat A = (cv::Mat_<float>(2,2) << 1, 2, 3, 4);
cv::Mat B = (cv::Mat_<float>(2,2) << 1, 0, 5, 8);
cv::Mat x[2] = {A, B};
cv::calcCovarMatrix(x, 2, covar, mean, CV_COVAR_SCRAMBLED );
std::cout << covar << std::endl; 
// gives [6, -6;
//        -6, 6]

我错过了什么?

kx1ctssn

kx1ctssn1#

两天前我遇到了同样的问题,我不知道为什么会出现这个问题,但我已经编写了一个代码,适用于我在OpenCV和MATLAB中测试的所有示例。

void matlab_covar(cv::Mat A,cv::Mat B)
{
   cv::Mat covar,mean;
   if(A.rows!=1) // check if A and B has one row don't reshape them 
   {
       A=A.reshape(1,A.rows*A.cols).t(); //reshape A to be one row
       B=B.reshape(1,A.rows*A.cols).t(); //rehsape B to be one row
   }
   cv::vconcat(A,B,A);          //vertical attaching
   cv::calcCovarMatrix(A,covar, mean,CV_COVAR_COLS|CV_COVAR_NORMAL);
   cv::Mat Matlab_covar = covar/(A.cols-1);  //scaling
   std::cout<<Matlab_covar<<std::endl;
}

我测试了一些例子来证明这段代码可以正常工作(但是我不确定为什么它可以工作)

示例-1

在MATLAB中

>> A = [1 2; 3 4];
>> B = [1 0; 5 8];
>> cov(A,B)

ans =

1.6667    4.3333
4.3333   13.6667

在Opencv

cv::Mat A = (cv::Mat_<double>(2,2) << 1,2,3,4);
    cv::Mat B = (cv::Mat_<double>(2,2) << 1,0,5,8);
    matlab_covar(A,B);   //the function i write

输出

[1.666666666666667, 4.333333333333333;
 4.333333333333333, 13.66666666666667]

示例-2

MATLAB语言

>> A = [3 3 3;2 2 2];
>> B = [1 2 3;3 2 1];
>> cov(A,B)

ans =

0.3000         0
     0    0.8000

开放式计算机虚拟化

[0.3, 0;
 0, 0.8]

示例-3

Matlab语言

>> a=rand(3,1)

 a =

 0.8147
 0.9058
 0.1270

 >> b=rand(3,1)

 b =

 0.9134
 0.6324
 0.0975

 >> cov(a,b)

 ans =

 0.1813    0.1587
 0.1587    0.1718

开放式计算机虚拟化

cv::Mat A = (cv::Mat_<double>(3,1) << 0.8147,0.9058,0.1270);
    cv::Mat B = (cv::Mat_<double>(3,1) << 0.9134,0.6324,0.0975);
    matlab_covar(A,B);

    [0.1812933233333333, 0.1586792416666666;
     0.1586792416666666, 0.1717953033333333]
cbeh67ev

cbeh67ev2#

只是缺少一个标志。请尝试:

cv::calcCovarMatrix(x, 2, covar, mean, cv::COVAR_ROWS | cv::COVAR_SCRAMBLED );

COVAR_ROWS mean:所有输入向量都存储为样本矩阵的行。(来自opencv 3.0 doc)

7eumitmz

7eumitmz3#

我使用了以下命令:
calcCovarMatrix(Z.t(), cov, mu, CV_COVAR_ROWS | CV_COVAR_SCRAMBLED |CV_COVAR_NORMAL);
在cov除以(nsamples-1)之后,该协方差与MATLAB计算结果相匹配。

相关问题