I'm trying to apply a SVM classifier to a PCA projected matrix, but I've some doubt on how to perform it. After training a PCA obj, I've applied a back-projection. Then I've trained my SVM obj with this back-projection and the labels matrix.
But when I need to predict a new image, should I recreate a PCA obj, train it with the image only and back-project it? or should I apply the previous PCA obj?
Here's my piece of code
Mat values = asRowMatrix(labels, CV_32FC1);
Mat desc_mat = asRowMatrix(images_cropped, CV_32FC1);
Mat average = Mat();
PCA pca(desc_mat, average, CV_PCA_DATA_AS_ROW);
Mat mean = pca.mean.clone();
Mat eigenvalues = pca.eigenvalues.clone();
Mat eigenvectors = pca.eigenvectors.clone();
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
Mat data(desc_mat.rows, images_cropped.size(), CV_32FC1); //This Mat will contain all the Eigenfaces that will be used later with SVM for detection
for (int i = 0; i<images_cropped.size(); i++) {
Mat projectedMat(1, images_cropped.size(), CV_32FC1);
pca.project(desc_mat.row(i), projectedMat);
projectedMat.row(0).copyTo(data.row(i));
}
CvSVM svm;
svm.train(data, values, Mat(), Mat(), params);
vector<Mat> images_cropped_t;
vector<int> labels_t;
//vectors with images and labels
int accuracy = 0;
Mat m_img = asRowMatrix(images_croppedt, CV_32FC1);
for (int i = 0; i < images_croppedt.size(); i++)
{
Mat face = m_img.row(i);
Mat projectedMat(1, images_croppedt.size(), CV_32FC1);
pca.project(face, projectedMat);
int predict = svm.predict(projectedMat);
accuracy = ((predict < 51) && (labelst[i] == 0)) ? ++accuracy : (((predict > 51) && (labelst[i] == 1)) ? ++accuracy : accuracy);
}
cout << endl;
cout << "ACCURACY: " << accuracy << "/" << images_croppedt.size() << " : - " << accuracy * 100 / images_croppedt.size() << "%" << endl;