2015-10-12 2 views
1

Я использую OpenCV для вычисления PCA для набора пикселей, представленных в виде 2D-точек. Но я не уверен, как PCA вычисляет среднее значение этих точек, поскольку это не то, что я ожидал бы.Как вычисляется среднее значение PCA OpenCV

Если у меня есть следующие 3 очка (x,y):

(2,1), (2,2), (2,3) 

А потом я вычисляю PCA (используется OpenCvSharp, но это просто обертка):

Mat input = new Mat(3,2, MatType.CV_32FC1); 
input.Set(0,0, 2f); 
input.Set(0,1, 1f); 
input.Set(1,0, 2f); 
input.Set(1,1, 2f); 
input.Set(2,0, 2f); 
input.Set(2,1, 3f); 

Mat mean = new Mat(); 
PCA pcaResult = new PCA(input, mean, PCA.Flags.DataAsRow); 

float meanX = pcaResult.Mean.Get<float>(0,0); 
float meanY = pcaResult.Mean.Get<float>(0,1); 

meanX и meanY являются (0.6666667, 0), соответственно. Где бы я ожидал, что они будут (2,2) (я предполагаю, что происходит какая-то форма нормализации). Как рассчитывается значение СПС, и что мне нужно сделать, чтобы вычислить среднее значение, которое я ожидаю? Или мне нужно передать среднее значение в PCA?

ответ

0

Используя этот перенос в C++ вашего кода:

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat1f input = (Mat1f(3,2) << 2, 1, 2, 2, 2, 3); 

    PCA pca(input, Mat(), CV_PCA_DATA_AS_ROW); 

    float meanX = pca.mean.at<float>(0, 0); 
    float meanY = pca.mean.at<float>(0, 1); 

    std::cout << meanX << " - " << meanY << std::endl; 

    return 0; 
} 

я получил среднее, как (2,2), как и ожидалось. Вероятно, это проблема с оболочкой C#.


Среднего в конечном счете, вычисляются с помощью метода calcCovarMatrix в качестве операции редукции:

... 
bool takeRows = (flags & CV_COVAR_ROWS) != 0; 
ctype = std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), CV_32F); 
... 
reduce(_src, _mean, takeRows ? 0 : 1, CV_REDUCE_AVG, ctype); 
+1

Да, оказывается, что это был OpenCvSharp, то среднее возвращает собственные значения. Я опубликовал эту проблему на странице Github OpenCvSharp. – Ayb4btu

Смежные вопросы