【问题标题】:Calculating covariance matrix with OpenCV用 OpenCV 计算协方差矩阵
【发布时间】:2015-03-31 04:32:42
【问题描述】:

我正在尝试使用 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]

我错过了什么?

【问题讨论】:

  • opencv 在行上工作,matlab 在 cols 上工作,所以将 CV_COVAR_COLS 添加到您的标志中
  • 根据opencv doc,CV_COVAR_COLS 只能与调用cv::calcCovarMatrix 的不同原型一起使用,在查看函数的源代码后,提到的标志被删除了。
  • 如果你使用opencv3.0,cv::COVAR_COLS
  • 同样在 opencv 中,您需要在 cov=cov/(nsamples-1) 之后缩放 cov 矩阵。

标签: c++ matlab opencv covariance


【解决方案1】:

这只是一个缺失的标志。试试:

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

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

【讨论】:

    【解决方案2】:

    我使用了以下命令:

    calcCovarMatrix(Z.t(), cov, mu, CV_COVAR_ROWS | CV_COVAR_SCRAMBLED |CV_COVAR_NORMAL);

    cov除以(nsamples-1)后,这个协方差与MATLAB计算结果匹配。

    【讨论】:

    • 我们不能同时使用 Scrambled 和 normal
    【解决方案3】:

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

    void matlab_covar(Mat A,Mat B)
    {
       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
       }
       vconcat(A,B,A);          //vertical attaching
       cv::calcCovarMatrix(A,covar, mean,CV_COVAR_COLS|CV_COVAR_NORMAL);
       Mat Matlab_covar = covar/(A.cols-1);  //scaling
       cout<<Matlab_covar<<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
    

    OpenCV

    [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
    

    OpenCV

        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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      • 2018-08-25
      • 2011-11-25
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多