Вычисление ковариационной матрицы с помощью OpenCV

Я пытаюсь использовать 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]

Что мне не хватает?

1

Решение

Это просто флаг, который отсутствует. Пытаться:

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

COVAR_ROWS mean : все входные векторы сохраняются в виде строк матрицы выборок. (из документа opencv 3.0)

1

Другие решения

Два дня назад у меня тоже есть эта проблема, и я не знаю, почему эта проблема возникает, но я пишу код, который работает для всех примеров, которые я тестирую в 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]
0

Я использовал следующую команду:

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

После деления cov на (nsamples-1) эта ковариация совпадает с результатом вычисления MATLAB.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector