GithubHelp home page GithubHelp logo

liho / svmlightclassifier Goto Github PK

View Code? Open in Web Editor NEW
22.0 2.0 12.0 353 KB

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

License: Other

C++ 2.46% C 95.29% Objective-C 2.25%

svmlightclassifier's Introduction

###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 :)

svmlightclassifier's People

Contributors

liho avatar jpjodoin avatar

Stargazers

Nguyễn Như Hải Long avatar Daniel Wolff avatar Gyeongik Shin avatar  avatar Volodymyr Donets avatar Leon Shan avatar  avatar Chris Olstrom avatar dexception avatar cr7INcs avatar Sandeep Chandappillai avatar Maxime Picaud avatar NeoSong avatar  avatar  avatar Carlos Eduardo Parra avatar Jan Hendriks avatar Rubik avatar Ashok Kumar Pant avatar Luke Dodd avatar Alberto avatar  avatar

Watchers

Alberto avatar Ashok Kumar Pant avatar

svmlightclassifier's Issues

Index of resulting single detector vector probably being incorrect

As found here: DaHoC/trainHOG#2

"The first value (Index 0) of the vector being generated in function getSingleDetectingVector() being always 0 due to the way SVMlight handles indices, as well as the last value (Index 3780) being overwritten by -b. An indexshift does not fix this issue because the positions/indices of the detecting vector components do matter for HOG."

I think I've found the solution to solve this issue if you want to try. You have to shift the indice by -1, remove the last line with the -model->b, and rescale the output to 3780.

We then use -model->b as the detection threshold.

Example:
void getSingleDetectingVector(std::vector& singleDetectorVector, std::vector& singleDetectorVectorIndices) {
// Now we use the trained svm to retrieve the single detector vector
DOC** supveclist = model->supvec;
printf("Calculating single descriptor vector out of support vectors (may take some time)\n");
// Retrieve single detecting vector (v1 | b) from returned ones by calculating vec1 = sum_1_n (alpha_y*x_i). (vec1 is a n x1 column vector. n = feature vector length )
singleDetectorVector.clear();
singleDetectorVector.resize(model->totwords, 0.);
printf("Resulting vector size %lu\n", singleDetectorVector.size());

        // Walk over every support vector
        for (long ssv = 1; ssv < model->sv_num; ++ssv) { // Don't know what's inside model->supvec[0] ?!
            // Get a single support vector
            DOC* singleSupportVector = supveclist[ssv]; // Get next support vector
            SVECTOR* singleSupportVectorValues = singleSupportVector->fvec;
            WORD singleSupportVectorComponent;
            // Walk through components of the support vector and populate our detector vector
            for (long singleFeature = 0; singleFeature < model->totwords; ++singleFeature) {
                singleSupportVectorComponent = singleSupportVectorValues->words[singleFeature];
                singleDetectorVector.at(singleSupportVectorComponent.wnum-1) += (singleSupportVectorComponent.weight * model->alpha[ssv]);
            }
        }
    }

float getThreshold() const
{
return model->b;
}

And when you want to detect, you can use something like this:
hogdetector.detect(im, ptList, svm.getThreshold(), cv::Size(8, 8),cv::Size(0, 0));

terminate called after throwing an instance of 'std:out_of_range'

i am getting this issue in the line when try to walk at ssv=1 in supveclist[ssv]; but model->sv_num is 11
error showing is terminate called after throwing an instance of 'std:out_of_range'
what():vector::_M_range_check

// Walk over every support vector
for (long ssv = 1; ssv < model->sv_num; ++ssv)
{
DOC* singleSupportVector = supveclist[ssv]; // Get next support vector
....
}

How to fix errors when compiling SvmLightLib?

I tried to compile SvmLightLib.cpp in my program,I got these errors:
`In file included from src/SvmLightLib.cpp:19:0:
src/svm_common.h:28:17: error: ‘__int32’ does not name a type
#define int32_t __int32
^
src/svm_common.h:42:18: note: in expansion of macro ‘int32_t’

define FNUM int32_t /* the type used for storing feature ids */

              ^

src/svm_common.h:58:3: note: in expansion of macro ‘FNUM’
FNUM wnum; /* word number /
^
src/SvmLightLib.cpp: In constructor ‘SVMLight::SVMLightImpl::SVMLightImpl()’:
src/SvmLightLib.cpp:42:38: warning: converting to non-pointer type ‘char’ from NULL [-Wconversion-null]
learn_parm->alphafile[0] = NULL;
^
src/SvmLightLib.cpp: In member function ‘void SVMLight::SVMLightImpl::getSingleDetectingVector(std::vector&, std::vector&)’:
src/SvmLightLib.cpp:142:74: error: ‘SVMLight::WORD’ has no member named ‘wnum’
singleDetectorVector.at(singleSupportVectorComponent.wnum) += (singleSupportVectorComponent.weight * model->alpha[ssv]);
^
src/SvmLightLib.cpp: In member function ‘std::vector SVMLight::SVMClassifier::getDescriptorVector()’:
src/SvmLightLib.cpp:190:122: error: no matching function for call to ‘SVMLight::SVMLightImpl::getSingleDetectingVector(std::vector&, std::vector)’
SVMLightImpl::getInstance()->getSingleDetectingVector(descriptorVector, std::vector() /
indices */);
^
src/SvmLightLib.cpp:190:122: note: candidate is:
src/SvmLightLib.cpp:124:14: note: void SVMLight::SVMLightImpl::getSingleDetectingVector(std::vector&, std::vector&)
void getSingleDetectingVector(std::vector& singleDetectorVector, std::vector& singleDetectorVectorIndices) {
^
src/SvmLightLib.cpp:124:14: note: no known conversion for argument 2 from ‘std::vector’ to ‘std::vector&’
`
what is my problem?

OpenCV Assertation failed in HOGDescriptor::checkDetectorSize()

I have collected some positive and negative samples. They are large 50x50px.
The train procedure runs fine, then, when I call:

HOGDescriptor hog;
hog.winSize = Size(32,48);
SVMLight::SVMClassifier c("classifier.dat");
vector<float> descriptorVector = c.getDescriptorVector();
std::cout << descriptorVector.size() << std::endl;
// this cout prints out 1621
hog.setSVMDetector(descriptorVector);

I get this assertation error
OpenCV Error: Assertion failed (checkDetectorSize()) in setSVMDetector
and "The program has unexpectedly finished."

I'm on Opencv 2.4.3 with Mac OS/X

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.