Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

How to 2-Class Categolization using SURF+BoW+SVM

I try to 2-Class Categolization. I retreive Image descriptors SURF and BOW, and SVM is used for training. My question is what I specify to clusterCount of BOWKMeansTrainer. training code is like below,

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 = detector.detect( img, keypoints);
        cv::Mat img = cv::imread( *file, CV_LOAD_IMAGE_GRAYSCALE );
        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
        }
    }
}

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

classifier xml file is successfully created, but exception occerred when I use SVM predict method. I doubt clusterCount is illegal ?

exception is below,

OpenCV Error: Sizes of input arguments do not match (The sample size is different from what has been used for training) in cvPreparePredictData, file ......\src\opencv\modules\ml\src\inner_functions.cpp, line 1114.

How to 2-Class Categolization using SURF+BoW+SVM

I try to 2-Class Categolization. I retreive Image descriptors SURF and BOW, and SVM is used for training. My question is what I specify to clusterCount of BOWKMeansTrainer. training code is like below,

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 = detector.detect( img, keypoints);
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
        }
    }
}

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

classifier xml file is successfully created, but exception occerred when I use SVM predict method. I doubt clusterCount is illegal ?

exception is below,

OpenCV Error: Sizes of input arguments do not match (The sample size is different from what has been used for training) in cvPreparePredictData, file ......\src\opencv\modules\ml\src\inner_functions.cpp, line 1114.