受SVM训练的模型将虚假图像识别为真实

时间:2018-07-23 06:14:02

标签: opencv svm

我有一个简单的SVM代码来训练和测试模型,以检查图像是否是眼睛。在使用相同的火车图像测试生成的模型时,对于非眼睛图像,它将返回1(表示眼睛)。这是培训代码和测试代码。

 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;
 }

这是测试模型的代码:

 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;
 }

注意:我正在使用OpenCV 2.4.8。我给出了7张眼睛图像和4张非眼睛图像进行训练。我觉得使用相同的训练图像测试模型时,最初的图像数量足够。

有什么建议吗?

0 个答案:

没有答案