Сохранение объекта pca в opencv

Я работаю над проектом распознавания лиц, в котором мы используем PCA для уменьшения размера вектора признаков изображения. Проблема в том, что во время обучения я создаю объект PCA, используя все тренировочные изображения. Сейчас, при тестировании, мне нужен объект PCA, полученный ранее.

Я не могу понять, как записать объект PCA в файл, чтобы использовать его во время тестирования. Одна из альтернатив заключается в том, что я записываю собственные векторы в файл. Но было бы гораздо удобнее написать сам объект. Есть ли способ сделать это?


person Karan    schedule 09.11.2011    source источник
comment
Просмотрите другие вопросы и примите некоторые ответы!   -  person karlphillip    schedule 14.11.2011


Ответы (2)


Насколько мне известно, не существует универсального способа сохранения объектов PCA в файл. Вам нужно будет сохранить собственные векторы, собственные значения и среднее значение в файл, а затем после загрузки поместить их в новый PCA. Вы должны помнить об использовании формата, который не теряет точности, особенно для среднего значения.

Вот пример кода:

#include "opencv2/core/core.hpp"
#include <iostream>

...

cv::PCA pca1;
cv::PCA pca2;

cv::Mat eigenval,eigenvec,mean;
cv::Mat inputData;
cv::Mat outputData1,outputData2;

//input data has been populated with data to be used
pca1(inputData,Mat()/*dont have previously computed mean*/,
CV_PCA_DATA_AS_ROW /*depends of your data layout*/);//pca is computed
pca1.project(inputData,outputData1);

//here is how to extract matrices from pca
mean=pca1.mean.clone();
eigenval=pca1.eigenvalues.clone();
eigenvec=pca1.eigenvectors.clone();

//here You can save mean,eigenval and eigenvec matrices

//and here is how to use them to make another pca
pca2.eigenvalues=eigenval;
pca2.eigenvectors=eigenvec;
pca2.mean=mean;

pca2.project(inputData,outputData2);

cv::Mat diff;//here some proof that it works
cv::absdiff(outputData1,outputData2,diff);

std::cerr<<sum(diff)[0]<<std::endl; //assuming Youre using one channel data, there
                                    //is data only in first cell of the returned scalar

// if zero was printed, both output data matrices are identical
person morynicz    schedule 10.11.2011
comment
Можете ли вы упомянуть способ создания объекта PCA из собственных векторов и собственных значений? Кажется, я вижу в документации только один способ: передать исходные данные и maxcomponents для создания pca pbject. - person Karan; 12.11.2011

Вы можете попробовать это.

void save(const string &file_name,cv::PCA pca_)
{
    FileStorage fs(file_name,FileStorage::WRITE);
    fs << "mean" << pca_.mean;
    fs << "e_vectors" << pca_.eigenvectors;
    fs << "e_values" << pca_.eigenvalues;
    fs.release();
}

int load(const string &file_name,cv::PCA pca_)
{
    FileStorage fs(file_name,FileStorage::READ);
    fs["mean"] >> pca_.mean ;
    fs["e_vectors"] >> pca_.eigenvectors ;
    fs["e_values"] >> pca_.eigenvalues ;
    fs.release();

}

Вот источник.

person Quazi Marufur Rahman    schedule 22.03.2015