Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

PCA+SVM Explanation

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;