2015-08-31 5 views
1

Я создал решение PCA в Matlab, которое работает. Я сейчас в середине преобразования его в C++, где я использую функцию OpenCV cv::PCA. Где я нашел в ссылке, которую вы могли бы извлечь средние, собственные значения и собственные векторы с помощью:Собственные собственные векторы PCA и собственные значения

// Perform a PCA: 
cv::PCA pca(data, cv::Mat(), CV_PCA_DATA_AS_ROW, num_components); 

// And copy the PCA results: 
cv::Mat mean = pca.mean.clone(); 
cv::Mat eigenvalues = pca.eigenvalues.clone(); 
cv::Mat eigenvectors = pca.eigenvectors.clone(); 

Который компилирует и работает. Но когда я хочу использовать значение и посмотреть на размер и распределение, я получаю размер входного data, который кажется странным, т.е.

cv::Size temp= eigenvectors.size(); 
//temp has the same size as data.size(); 

В моем сознании собственные векторы должны быть определены с помощью num_components и мое трехмерное пространство должно быть только размером 3x3, т.е. 9 элементами. Может ли кто-нибудь объяснить обоснование размеров данных pca.x.clone()?

Также, как правильно работать с матрицей в opencv и C++, на основе документации, похоже, вы можете использовать операторы с cv::Mat. Используя вышеуказанное извлечение информации PCA вы можете сделать:

cv::Mat Z = data - mean; //according to documentation http://stackoverflow.com/questions/10936099/matrix-multiplication-in-opencv 
cv::Mat res = Z*eigenvectors; 

Он разбился в моих тестах на время выполнения, вероятно, из-за проблемами с «неправильным толкованием»/«интерпретацией» размера.

Вопрос Основной вопрос заключается в том, как правильно использовать функцию op opvv?

Редактировать Другим способом, который я испытал это использовать следующий код:

cv::PCA pca_analysis(mat, cv::Mat(), CV_PCA_DATA_AS_ROW, num_components); 
cv::Point3d cntr = cv::Point3d(static_cast<double>(pca_analysis.mean.at<double>(0, 0)), 
     static_cast<int>(pca_analysis.mean.at<double>(0, 1)), static_cast<double>(pca_analysis.mean.at<double>(0, 2))); 
//Store the eigenvalues and eigenvectors 
vector<cv::Point3d> eigen_vecs(num_components); 
vector<double> eigen_val(num_components); 
for (int i = 0; i < num_components; ++i) 
{ 
    eigen_vecs[i] = cv::Point3d(pca_analysis.eigenvectors.at<double>(0, i*num_components), 
      pca_analysis.eigenvectors.at<double>(0, i * num_components + 1), pca_analysis.eigenvectors.at<double>(0, i*num_components + 2)); 
    eigen_val[i] = pca_analysis.eigenvalues.at<double>(0,i); 
} 

Когда я сравниваю результаты приведенной выше коды с моей реализацией Matlab того cntr кажется правдоподобными (под процентная разница). Но собственные векторы и собственные значения равны нулю, когда я смотрю на них в отладчике. Это, похоже, вернется к моему первоначальному вопросу о том, как извлечь и понять вывод pca.

Может кто-нибудь уточнить, чего я не хватает?

ответ

1

Я столкнулся с вашим вопросом при поиске путей доступа к собственным значениям и собственным векторам.

Мне лично нужно было посмотреть полную информацию и следовало бы ожидать этого. Таким образом, возможно, что разработчики ожидали, что мой вариант использования будет более вероятным, чем ваш.

В любом случае, поскольку они отсортированы, вы можете взять первые собственные значения/собственные векторы num_components как информацию, которую вы используете.

Кроме того, с вашей точки зрения, т. Е. Если он работал так, как вы ожидаете, подумайте об обратном: если вы хотите увидеть полную информацию, как бы вы? Разработчикам придется реализовать новый параметр ...

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