SVM trained model recognizes false image as true

asked 2018-07-23 09:03:18 -0600

VSRao gravatar image

I have a simple SVM code to train and test the model for checking whether the image is an eye or not. While testing the generated model using the same train images, for a non-eye image, it returns 1(which means eye). Here is the training code and testing code.

int main ( int argc, char** argv )
{
     cout << "OpenCV Training SVM Eye Recognition\n";
     cout << "\n";

     char *Eyes;
     char *NoEyes;
     int numEyes;
     int numNoEyes;
     int imageWidth=16;
     int imageHeight=16;
     int imgSize = (imageWidth * imageHeight);
     unsigned char buffer[imgSize];

     //Validate the arguments
     if(argc >= 5 )
     {
         numEyes= atoi(argv[1]);
         numNoEyes= atoi(argv[2]);
         Eyes= argv[3];
         NoEyes= argv[4];

     }else{
         cout << "Usage:\n" << argv[0] << " <num Eye Files> <num Non Eye Files> <path to eye folder files> <path to non eye files> \n";
         return 0;
     }        

     int num_files = (numEyes + numNoEyes);
     int file_num = 0;
     Mat training_mat(num_files,imgSize,CV_32FC1);
     Mat labels(num_files, 1, CV_32SC1);

     for(int m = 0; m < numEyes; m++)
     {
         stringstream ss(stringstream::in | stringstream::out);
         ss << Eyes << m << ".yuv";
         cout << ss.str() << endl;
         FILE *fp;
         fp = fopen(ss.str().c_str(), "rb");
         if (fp == NULL) {
             break;
         } else {
             if (fread(buffer, 1, imgSize, fp) != imgSize) {
                 break;
             }
             fclose(fp);
         }
         for (int i = 0; i < imageWidth*imageHeight; i++) {
             training_mat.at<float>(file_num, i) = ((float)buffer[i] / 1000.0f);
         }
         labels.at<int>(file_num) = 1;
         file_num++;
     }

     for(int m = 0; m < numNoEyes; m++)
     {
         stringstream ss(stringstream::in | stringstream::out);
         ss << NoEyes << m << ".yuv";
         cout << ss.str() << endl;
         FILE *fp;
         unsigned char buffer[imgSize];
         fp = fopen(ss.str().c_str(), "rb");
         if (fp == NULL) {
             break;
         } else {
             if (fread(buffer, 1, imgSize, fp) != imgSize) {
                 break;
             }
             fclose(fp);
         }
         for (int i = 0; i < imgSize; i++) {
             training_mat.at<float>(file_num, i) = ((float)buffer[i] / 1000.0f);
         }
         labels.at<int>(file_num) = -1;
         file_num++;
     }

     CvSVMParams params;
     params.svm_type = CvSVM::C_SVC;
     params.kernel_type = CvSVM::RBF;
     params.C = 10.0f;
     params.gamma = 8;
     params.term_crit = cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40, 0.001);

     CvSVM SVM;
     SVM.train(training_mat, labels, Mat(), Mat(), params);
     SVM.save("train.xml");

     return 0;
}

Here is the code for testing the model :

using namespace std;
using namespace cv;

int main ( int argc, char** argv )
{
     cout << "OpenCV Test - checking whether the given image is eye or not\n";
     cout << "\n";

     int segWidth=16;
     int segHeight=16;
     int imgSize = (segWidth * segHeight);

     //Validate argument
     if(argc < 2 )
     {
         cout << "Usage:\n" << argv[0] << " <Test image file> \n";
         return 0;
     }        

     stringstream ss(stringstream::in | stringstream::out);
     ss << argv[1];
     cout << ss.str() << endl;
     Mat test_data(1, imgSize, CV_32FC1);
     FILE *fp;
     unsigned char buffer[imgSize];

     fp = fopen(ss.str().c_str(), "rb");
     if (fp != NULL) {
         fread(buffer, 1, imgSize, fp);
         fclose(fp);
     }

     CvSVM svm;
     svm.load("train.xml");

     for (int m = 0; m < imgSize; m++) {
         test_data.at<float>(0, m++) = ((float)buffer[m] / 1000.0f);
     }
     float response = svm.predict(test_data);
     cout << response << endl;

     return 0;
}

Note: I am using OpenCV 2.4.8. I have ... (more)

edit retag flag offensive close merge delete

Comments

1

"I am using OpenCV 2.4.8" -- that's sad.

"I have given 7 eye images and 4 non-eye images " -- you would need ~500 images each.

you also have to consider left and right eyes here, imho.

berak gravatar imageberak ( 2018-07-23 09:13:16 -0600 )edit

Even to test against the same trained images?

VSRao gravatar imageVSRao ( 2018-07-24 00:08:00 -0600 )edit
1

testing against trained images is wrong, too.

berak gravatar imageberak ( 2018-07-24 00:15:32 -0600 )edit