简体   繁体   English

使用SVM和BOW进行图像分类?

[英]image classification using SVM and BOW?

i am not too experienced with openCV. 我对openCV不太了解。 I have some images and i want to check whether they contain a sign which i am looking for or not. 我有一些图像,我想检查它们是否包含我正在寻找的标志。 So, i want to use the SVM technique for which i have some code. 因此,我想使用我有一些代码的SVM技术。 I have understood most the parts of the code but i don't know how can i implement this code. 我已经了解了代码的大部分内容,但是我不知道如何实现此代码。 The code has three functions ie createTrainDataUsingBow() second is int trainSVM and int svmPredict . 该代码具有三个功能,即createTrainDataUsingBow()其次是int trainSVMint svmPredict

Problem: I know that first i have to train the SVM and then use the predict(). 问题:我知道首先我必须训练SVM,然后使用predict()。 But, i don't understand the arguments to be passed during their call. 但是,我不理解在通话期间要传递的参数。 I mean, if i create a main() then with what parameters i should call the int trainSVM . 我的意思是,如果我创建main() ,则应使用什么参数调用int trainSVM

The whole code is given below: 整个代码如下:

1. Code for createTrainDataUsingBow() 1. createTrainDataUsingBow()的代码

void createTrainDataUsingBow(std::vector<char*> files, cv::Mat& train, cv::Mat&        response, int label)
{
    cv::Ptr<cv::DescriptorMatcher> matcher =    cv::DescriptorMatcher::create("FlannBased");
    cv::Ptr<cv::DescriptorExtractor> extractor = new cv::SurfDescriptorExtractor();
    cv::BOWImgDescriptorExtractor dextract( extractor, matcher );
    cv::SurfFeatureDetector detector(500);

    // cluster count
    int cluster = 100;

    // create the object for the vocabulary.
    cv::BOWKMeansTrainer bow( cluster,cv::TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, FLT_EPSILON), 1, cv::KMEANS_PP_CENTERS );

    // get SURF descriptors and add to BOW each input files
    std::vector<char*>::const_iterator file;
    for( file = files.begin(); file != files.end(); file++)
    {
        cv::Mat img = cv::imread( *file, CV_LOAD_IMAGE_GRAYSCALE );
        std::vector<cv::KeyPoint> keypoints = detector.detect( img, keypoints);
        cv::Mat descriptors;
        extractor->compute( img, keypoints, descriptors);
        if ( !descriptors.empty() ) bow.add( descriptors );
    }

    // Create the vocabulary with KMeans.
    cv::Mat vocabulary;
    vocabulary = bow.cluster();

    for( file = files.begin(); file != files.end(); file++)
    {
        // set training data using BOWImgDescriptorExtractor
        dextract.setVocabulary( vocabulary );
        std::vector<cv::KeyPoint> keypoints;
        cv::Mat img = cv::imread( *file, CV_LOAD_IMAGE_GRAYSCALE );
        detector.detect( img, keypoints);
        cv::Mat desc;
        dextract.compute( img, keypoints, desc );
        if ( !desc.empty() )
        {
            train.push_back( desc );            // update training data
            response.push_back( label );        // update response data
        }
    }
}

2. Code for trainSVM() 2. trainSVM()的代码

int trainSVM((std::vector<char*> positive, std::vector<char*> negative)
{
    // create training data
    cv::Mat train;
    cv::Mat response;
    createTrainDataUsingBow(positive, train, response, 1.0);
    createTrainDataUsingBow(negative, train, response, -1.0);

    // svm parameters
    CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
    CvSVMParams svm_param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0,     0.5, 0.1, NULL, criteria);

    // train svm
    cv::SVM svm;
    svm.train(train, response, cv::Mat(), cv::Mat(), svm_param);
    svm.save("svm-classifier.xml");

    return 0;
}

3. Code for svmPredict() 3. svmPredict()的代码

int svmPredict(const char* classifier, const char* vocaname, const char* query, const char* method)
{
    // load image
    cv::Mat img = cv::imread(query, CV_LOAD_IMAGE_GRAYSCALE);

    // load svm
    cv::SVM svm;
    svm.load(classifier);

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

    // load vocabulary data
    cv::Mat vocabulary;
    cv::FileStorage fs( vocaname, cv::FileStorage::READ);
    fs["vocabulary data"] >> vocabulary;
    fs.release();
    if( vocabulary.empty()  ) return 1;

    // Set the vocabulary
    dextract.setVocabulary( vocabulary );
    std::vector<cv::KeyPoint> keypoints;
    detector.detect( img, keypoints);
    cv::Mat desc_bow;
    dextract.compute( img, keypoints, desc_bow );
    if( desc_bow.empty() )  return 1;

    // svm predict
    float predict = svm.predict(centroids, true);

    std::cout << predict << std::endl;

    return 0;
}

what parameters i should call the int trainSVM. 我应该将哪些参数称为int trainSVM。

trainSVM() takes two char* vectors which are lists of names of image files for the positive and negative samples respectively. trainSVM()采用两个char *向量,分别是正样本和负样本的图像文件名称列表。 It would probably best to make a file containing a list of positive image filenames, and the same for negatives, and to read those in. 最好制作一个包含正片图像文件名列表的文件,对于负片文件名也是如此,然后读取其中的文件名。

BTW, this line has a syntax error: 顺便说一句,这行有一个语法错误:

int trainSVM((std::vector<char*> positive, std::vector<char*> negative)

A bigger concern is how are you going to normailize the data, and how are you going to do cross validation to get the proper values for svm_params? 一个更大的问题是如何对数据进行规范化处理,以及如何进行交叉验证以获取svm_params的正确值?

Also, since svmPredict() reloads everything for every test case, it will be very inefficient. 另外,由于svmPredict()为每个测试用例重新加载所有内容,因此效率很低。

You would be probably be better off using the libsvm command line tools until you know whether it is going to work. 使用libsvm命令行工具可能会更好,直到您知道它是否将起作用。 It would be trivial to dump the mats output from createTrainDataUsingBow() data in libsvm format. 以libsvm格式转储来自createTrainDataUsingBow()数据的createTrainDataUsingBow()输出将很简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM