Ask Your Question

shige's profile - activity

2019-06-17 14:53:16 -0600 received badge  Famous Question (source)
2018-01-01 04:24:12 -0600 received badge  Popular Question (source)
2015-08-16 06:44:08 -0600 received badge  Notable Question (source)
2014-11-12 12:13:50 -0600 received badge  Popular Question (source)
2013-12-02 22:49:23 -0600 answered a question How to 2-Class Categolization using SURF+BoW+SVM

SVM predict code is, finally, I will determine class by predict value.

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;
}
2013-12-02 22:29:45 -0600 commented answer How to 2-Class Categolization using SURF+BoW+SVM

Thank you for comment, Guanta. I think that SVM predit value is distance of BoW descriptors. I am wrong ? my predict code is below.

2013-11-29 06:24:58 -0600 received badge  Nice Question (source)
2013-11-28 18:56:22 -0600 commented answer How to 2-Class Categolization using SURF+BoW+SVM

Thanks Guanta ! About exception case, I solved revising SurfDescriptorExtractor to BOWImgDescriptorExtractor. but I can not implement exact 2-class categolization, accuracy is about 30%. Indeed, I did not think about distance of BoW descriptors, I want more precise categolization. In that case, What parameter do I optimize at training sequence ?

2013-11-27 10:55:09 -0600 commented answer How to 2-Class Categolization using SURF+BoW+SVM

thanks for comment, and sorry, acctually code is below,

cv::Mat img = cv::imread( *file, CV_LOAD_IMAGE_GRAYSCALE ); std::vector<cv::KeyPoint> keypoints = detector.detect( img, keypoints); cv::Mat desc; dextract.compute( img, keypoints, desc );

2013-11-27 09:02:57 -0600 received badge  Student (source)
2013-11-27 06:42:03 -0600 asked a question 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;
        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.

2013-10-28 11:02:48 -0600 asked a question What mean is SVM predict method return value ?

I use predict method for 2-class classification with SVM labeled +1 or -1. And returnDFVal is false, then I get +1 or -1 accurate. but, returnDFVal is true, then return value is opposite to the label, i.e.

returnDFVal = false -> return = -1

returnDFVal = true  -> return = 1.07756

code is below, best regard.

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

    // compute descriptor for each keypoint
    cv::Mat desc;
    desc = getDescriptors(img, method);

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

    // convert descriptor -> vector
    cv::Mat centroids(1, 64, CV_32F);
    cv::Mat label(1, 1, CV_32F, cv::Scalar(-1));
    cv::kmeans(desc, 1, label, cv::TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0), 1, 2, centroids);

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

    return predict;
}
2013-10-27 21:57:15 -0600 answered a question how to specify SURF parameters at FeatureDetector object ?

thanks Monster, I tried below code, and could get 128-dimention SURF descriptors. And contained -431602080. values is initialized Mat data.

void getDescriptors(char* image) {

///// load image
cv::Mat img = cv::imread(image, CV_LOAD_IMAGE_GRAYSCALE);
if(img.empty()) return;

///// detect keypoints /////
cv::vector<cv::KeyPoint> keyPoints; // keypoint vector

// create feature detector
cv::SurfFeatureDetector detector = cv::SurfFeatureDetector(400, 4, 2, true, false);

// detect key points (feature point)
detector->detect(image, keyPoints);

///// compute descriptors /////
cv::Mat descriptor; // descriptors mat

// create descriptor extractor
cv::Ptr<cv::DescriptorExtractor> extractor = cv::DescriptorExtractor::create("SURF");
if(extractor.empty()) return;

// compute descriptor
extractor->compute(image, keyPoints, descriptor);

return descriptor;

}
2013-10-24 01:16:07 -0600 received badge  Supporter (source)
2013-10-24 01:15:23 -0600 received badge  Critic (source)
2013-10-24 01:14:55 -0600 received badge  Scholar (source)
2013-10-23 23:52:28 -0600 commented answer how to specify SURF parameters at FeatureDetector object ?

thanks for response me ! I try it.

2013-10-23 23:35:38 -0600 received badge  Editor (source)
2013-10-23 23:30:51 -0600 asked a question how to specify SURF parameters at FeatureDetector object ?

i try to get SURF descriptor with OpenCV 2.4.6.0, but FeatureDetector object cannot be specified SURF parameters. using FeatureDetector object, I can get descriptors Mat, then it contains unkown data.

i.e. -431602080.

about 35000's above data is contained in descriptors Mat. code is below,

void getDescriptors(char* image) {

///// load image
cv::Mat img = cv::imread(image, CV_LOAD_IMAGE_GRAYSCALE);
if(img.empty()) return;

///// detect keypoints /////
cv::vector<cv::KeyPoint> keyPoints; // keypoint vector

// create feature detector
cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create("SURF");
if(detector.empty()) return;

// detect key points (feature point)
detector->detect(image, keyPoints);

///// compute descriptors /////
cv::Mat descriptor; // descriptors mat

// create descriptor extractor
cv::Ptr<cv::DescriptorExtractor> extractor = cv::DescriptorExtractor::create("SURF");
if(extractor.empty()) return;

// compute descriptor
extractor->compute(image, keyPoints, descriptor);

return descriptor;
}