Skip to content

nkint/SVMLightClassifier

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

###SVMLightClassifier

A simple static library wrapping SVMLight meant for classification using HOG features.

####Usage

Project using this static library shall contain the following header:

#ifndef __SVMLIGHTLIB_H__
#define __SVMLIGHTLIB_H__

#include <vector>
#include <string>
#include <fstream>

namespace SVMLight
{
    class SVMTrainer
    {
    private:
        std::fstream featuresFile_;
        std::string featuresFileName_;
    public:
        SVMTrainer(const std::string& featuresFileName);
        void writeFeatureVectorToFile(const std::vector<float>& featureVector, bool isPositive);
        void trainAndSaveModel(const std::string& modelFileName);
    };

    class SVMClassifier
    {
    public:
        SVMClassifier(const std::string& modelFileName);
        std::vector<float> getDescriptorVector();
    };
}

#endif

#####Training

The training can use the SVMTrainer wrapper the following way:

    // we are going to use HOG to obtain feature vectors:
    HOGDescriptor hog;
    hog.winSize = Size(32,48);

    // and feed SVM with them:
    SVMLight::SVMTrainer svm("features.dat");

    size_t posCount = 0, negCount = 0;
    for (size_t i = 1; i <= 800; ++i)
    {
        // in this concrete case I had files 0001.JPG to 0800.JPG in both "positive" and "negative" subfolders:
        std::ostringstream os;
        os << TRAINING_SET_PATH << "positive\\" << std::setw(4) << std::setfill('0') << i << ".JPG";
        Mat img = imread(os.str(),CV_LOAD_IMAGE_GRAYSCALE);
        if (!img.data)
            break;
        
        // obtain feature vector:
        vector<float> featureVector;
        hog.compute(img, featureVector, Size(8, 8), Size(0, 0));
        
        // write feature vector to file that will be used for training:
        svm.writeFeatureVectorToFile(featureVector, true);                  // true = positive sample
        posCount++;

        // clean up:
        featureVector.clear();
        img.release();              // we don't need the original image anymore
        os.clear(); os.seekp(0);    // reset string stream
        
        // do the same for negative sample:
        os << TRAINING_SET_PATH << "negative\\" << std::setw(4) << std::setfill('0') << i << ".JPG";
        img = imread(os.str(),CV_LOAD_IMAGE_GRAYSCALE);
        if (!img.data)
            break;
        
        hog.compute(img, featureVector, Size(8, 8), Size(0, 0));
        svm.writeFeatureVectorToFile(featureVector, false);
        negCount++;
        img.release();
    }

    std::cout   << "finished writing features: "
                << posCount << " positive and "
                << negCount << " negative samples used";
    std::string modelName("classifier.dat");
    svm.trainAndSaveModel(modelName);
    std::cout   << "SVM saved to " << modelName;

#####Classification

The classification can be then performed by the instance of HOGDescriptor, you just need to feed it with your own SVM detector in form of std::vector<float>:

    HOGDescriptor hog;
    hog.winSize = Size(32,48);
    SVMLight::SVMClassifier c("classifier.dat");
    vector<float> descriptorVector = c.getDescriptorVector();
    hog.setSVMDetector(descriptorVector);

and later once you retrieve some segment, you can do something like:

    Mat segment = img(Rect(x0, y0, x1 - x0, y1 - y0));
    vector<Rect> found;
    Size padding(Size(0, 0));
    Size winStride(Size(8, 8));
    hog.detectMultiScale(segment, found, 0.0, winStride, padding, 1.01, 0.1);

That's all :)

About

Simple static library based on SVMLight and SVMLightLib meant for classification using HOG features.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 90.3%
  • C++ 7.6%
  • Objective-C 2.1%