词汇/词典使用Bag功能进行分类

时间:2014-01-23 19:25:49

标签: opencv svm

我正在尝试使用SVM进行3级分类。为此,我在SVM培训期间准备词汇。但由于我在SVM预测期间得到随机结果,所以我怀疑我的词汇创建方法存在一些问题。我创建词汇的代码如下:

//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

}

2 个答案:

答案 0 :(得分:0)

你应该包含字典中的所有词汇。 这意味着你应该一次循环所有的图片。然后,每个类别都要进行处理

答案 1 :(得分: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;
    }