2014-01-23 35 views
1

我正在嘗試使用SVM進行3級分類。爲此,我正在準備SVM培訓期間的詞彙。但是,由於我在SVM預測中得到隨機結果,所以我懷疑我的詞彙創建方法中存在一些問題。我創建詞彙表的代碼如下:使用Bag功能進行分類的詞彙/字典

//Mat train --- it should contain the feature vectors 
//Mat response-- it will contain the class labels 

void svm::createTrainingDateUsingBOW(int flag,Mat& train, Mat& response, int label) 
{ 

    int cluster = 9; // Common for all classes 
    cv::Mat imageForTraining; 
    std::vector<cv::KeyPoint> keypoints; 
    cv::SurfFeatureDetector detector(500); 
    cv::Ptr<cv::DescriptorExtractor> cvDescExt = new cv::SurfDescriptorExtractor(); 
    cv::Mat descriptors; 

    cv::BOWKMeansTrainer bow(cluster, cv::TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, FLT_EPSILON), 1, cv::KMEANS_PP_CENTERS); 
    cv::Mat vocabulary; 

    if (flag == 1) 
    { 
     for(int i=1; i<=400; i++) 
     { 
      counter++; 
      cout<<"\n counter: "<<counter; 

      char filepath[255]; 
      sprintf(filepath, "class1/%d.JPG",i); // we need class1/1.JPG etc 

      imageForTraining = cv::imread(filepath, CV_LOAD_IMAGE_GRAYSCALE); 

      // Preparing keypoints using detector 
      detector.detect(imageForTraining, keypoints); 

      // now getting the DESCRIPTORS for the given keypoints 
      cvDescExt->compute(imageForTraining, keypoints, descriptors); 

      //BOW 
      if(keypoints.size() > cluster) // so that (N<k) error won't come 
      { 
       if (!descriptors.empty()) bow.add(descriptors); 

       //VOCABULARY 
       vocabulary = bow.cluster(); 

       cv::Ptr<DescriptorExtractor> extractor = new SurfDescriptorExtractor(); 
       cv::Ptr<DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased"); 
       cv::BOWImgDescriptorExtractor descExtractor (extractor, matcher); 

       descExtractor.setVocabulary(vocabulary); 
       Mat bowDescriptors; 
       descExtractor.compute(imageForTraining, keypoints, bowDescriptors); 
       if (!bowDescriptors.empty()) 
       { 
        train.push_back(bowDescriptors); 
        response.push_back(label); 
       } 

      }// ending if loop 

     } // ending For loop  
    }// ending if(flag) loop 


    if (flag == 2) 
    { 
     for(int i=1; i<=400; i++) 
     { 
      counter++; 
      cout<<"\n counter: "<<counter; 

      char filepath[255]; 
      sprintf(filepath, "class2/%d.JPG",i); // we need class1/1.JPG etc 

      imageForTraining = cv::imread(filepath, CV_LOAD_IMAGE_GRAYSCALE); 

      // Preparing keypoints using detector 
      detector.detect(imageForTraining, keypoints); 

      // now getting the DESCRIPTORS for the given keypoints 
      cvDescExt->compute(imageForTraining, keypoints, descriptors); 

      //BOW 
      if(keypoints.size() > cluster) // so that (N<k) error won't come 
      { 
       if (!descriptors.empty()) bow.add(descriptors); 

       //VOCABULARY 
       vocabulary = bow.cluster(); 

       cv::Ptr<DescriptorExtractor> extractor = new SurfDescriptorExtractor(); 
       cv::Ptr<DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased"); 
       cv::BOWImgDescriptorExtractor descExtractor (extractor, matcher); 

       descExtractor.setVocabulary(vocabulary); 
       Mat bowDescriptors; 
       descExtractor.compute(imageForTraining, keypoints, bowDescriptors); 
       if (!bowDescriptors.empty()) 
       { 
        train.push_back(bowDescriptors); 
        response.push_back(label); 
       } 

      }// ending if loop 

     } // ending For loop  
    }// ending if(flag) loop 

....Similary for Class-3 

} 

回答

0

您應該包含詞典中的所有詞彙。 這意味着你要循環一次.rather過程中的所有圖片每個類別spraidly

+1

你能否提供更多的答案嗎?示例代碼展示如何解決這個問題會更有用。 –

+0

我已經提交了另一個答案 – AUG

0

碼這樣的恩...

struct timeval start,end;//compute time of the during 
    gettimeofday(&start,NULL);//get the time when program start 
    //inital stack 
    initModule_nonfree(); 
    initModule_features2d(); 
    initModule_contrib(); 
    //build dicationary 
    int wordCount = 10000;//num of vocabulary in dictionary 
    //string trainDataPath = "/home/win/winshare/datasets/4categories";//test datasets 
    string trainDataPath = "/workspace/datasets/mirflickr";//final using datsets 

    //change string to const char * 
    const char* c_trainDataPath = trainDataPath.c_str(); 
    struct dirent* ent = NULL; 
    DIR *pDir; 
    //readdir return following dirent 
    //struct dirent { 
    //  ino_t   d_ino;  /* inode number */ 
    //  off_t   d_off;  /* not an offset; see NOTES */ 
    //  unsigned short d_reclen; /* length of this record */ 
    //  unsigned char d_type;  /* type of file; not supported 
    //                 by all filesystem types */ 
    //  char   d_name[256]; /* filename */ 
    //}; 
    pDir = opendir(c_trainDataPath); 
    if (pDir == NULL){ 
      cout << "can not open dir ,maybe it's a file" << endl; 
      return -1; 
    } 
    Mat allDescriptors;//store all descriptors 
    Ptr<FeatureDetector> detector = FeatureDetector::create("SURF"); 
    Ptr<DescriptorExtractor> extractor = DescriptorExtractor::create("SURF"); 


     while ((ent = readdir(pDir)) != NULL){ 
      if (ent->d_type == 8)// 8 is a file 4 is a dir 
      { 
        //cout << ent->d_name << endl; 
        string current_file = trainDataPath + "/" + ent->d_name; 
        cout << "processing" + current_file << endl; 
        Mat image = imread(current_file); 
        if (!image.empty()){//pass non picture file 
          vector<KeyPoint> keyPoints; 
          Mat descriptors; 
          //compute keypoint in this picture 
          detector->detect(image, keyPoints); 
          //compute descriptors in this pircture 
          extractor->compute(image, keyPoints, descriptors); 
          if (allDescriptors.empty()){ 
            allDescriptors.create(0, descriptors.cols, descriptors.type()); 
          } 
          allDescriptors.push_back(descriptors);//collect all descriptor in allDescriptors 
        } 

      } 

    } 

    assert(!allDescriptors.empty()); //assert allDescriptors 
    cout << "building vocabulary ..." << endl; 
    BOWKMeansTrainer bowTrianer(wordCount); 
    Mat vocabulary = bowTrianer.cluster(allDescriptors); 
    cout << "done build vocabulary " << endl; 

    //done build dictionary 
    string result = trainDataPath + "/" + "result"; 
    const char* c_result = result.c_str(); 

    //create a drectory to store dictionary we build 
    mkdir(c_result, 0666); 
    string vocabularyFile = result + "/" + "vocabulary"; 

    FileStorage fs(vocabularyFile, FileStorage::WRITE); 
    if (fs.isOpened()){ 
      fs << "vocabulary" << vocabulary; 
    }