Я создал решение 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.
Может кто-нибудь уточнить, чего я не хватает?