Ask Your Question
0

Is anyone using "ONE CLASS SVM"?

asked 2017-02-16 23:36:12 -0600

DoryeongPark gravatar image

updated 2017-02-17 02:09:50 -0600

I'm new at dealing with SVM and i created successfully multi0class svm examples. I have tried many times to implement ONE-CLASS SVM, but it always returns zero. I have all labels of sample filled with 1, though one class svm seems that it doesn't need to label samples. If there is complete example using one class svm, could you refer the link?

Here's my code

#include<iostream>
#include<vector>
#include<fstream>

#include<opencv2\core.hpp>
#include<opencv2\imgproc.hpp>
#include<opencv2\highgui.hpp>
#include<opencv2\xfeatures2d.hpp>
#include<opencv2\ml.hpp>

using namespace std;
using namespace cv;
using namespace xfeatures2d;
using namespace ml;

void main() {

    Mat groups;
    Mat samples;
    vector<KeyPoint> keypoints1;

    //ORB Detector
    Ptr<ORB> detector = ORB::create(20, 1.2f, 2, 31, 0, 2, ORB::HARRIS_SCORE, 31);

    Mat descriptors1, descriptors2;

    Ptr<SURF> extractor = SURF::create();

    //Sample of similar images
    for (int i = 1; i <= 40; ++i) {
        stringstream nn;
        nn << "models/" << i << ".png";

        Mat img = imread(nn.str());
        cvtColor(img, img, COLOR_BGR2GRAY);

        detector->detect(img, keypoints1);

        extractor->compute(img, keypoints1, descriptors1);

        samples.push_back(descriptors1.reshape(1, 1));
        keypoints1.clear();
    }

    for (int j = 1; j <= 40; ++j) {
        groups.push_back(1);
    }

    Ptr<SVM> classifierSVM = SVM::create();

    ifstream existence("trainingData.yml");

    if (existence.good()) {
        classifierSVM = Algorithm::load<SVM>("trainingData.yml");
    }
    else {
        classifierSVM->setType(SVM::ONE_CLASS);
        classifierSVM->setKernel(SVM::LINEAR);
        classifierSVM->setDegree(3);
        classifierSVM->setGamma(1);
        classifierSVM->setCoef0(0);
        classifierSVM->setC(1);
        classifierSVM->setNu(0.5);
        classifierSVM->setP(0);
        classifierSVM->setTermCriteria(cvTermCriteria(CV_TERMCRIT_ITER,
                                                     500, FLT_EPSILON));

        classifierSVM->train(samples, ml::ROW_SAMPLE, groups);
        classifierSVM->save("trainingData.yml");
    }

    //Test for 10 image sample - 7 & 9 must be classified.
    for (int i = 1; i <= 10; ++i) {
        stringstream nn;

        nn << "testers/" << "unknown" << i << ".png";

        Mat unknown = imread(nn.str());
        cvtColor(unknown, unknown, COLOR_BGR2GRAY);

        detector->detect(unknown, keypoints1);

        extractor->compute(unknown, keypoints1, descriptors2);

        float result = classifierSVM->predict(descriptors2.reshape(1, 1));

        cout << nn.str() << ": class " << result << endl;
    }

    waitKey(10);

}
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2017-02-17 02:57:23 -0600

LBerger gravatar image

Your program is OK. Ihave tested it . As you can see positive and negative values are not in same class..

        Mat groups;
        Mat samples(10,1,CV_32F);
        RNG r;
        r.fill(samples,RNG::NORMAL,0,2);
        cout<<samples<<endl;
        for (int j = 1; j <= 10; ++j) 
        {
            groups.push_back(0);
        }
        Ptr<ml::SVM> classifierSVM = ml::SVM::create();
            classifierSVM->setType(ml::SVM::ONE_CLASS);
            classifierSVM->setKernel(ml::SVM::LINEAR);
            classifierSVM->setDegree(3);
            classifierSVM->setGamma(1);
            classifierSVM->setCoef0(0);
            classifierSVM->setC(1);
            classifierSVM->setNu(0.5);
            classifierSVM->setP(0);
            classifierSVM->setTermCriteria(cvTermCriteria(CV_TERMCRIT_ITER,
                500, FLT_EPSILON));

            classifierSVM->train(samples, ml::ROW_SAMPLE, groups);
            classifierSVM->save("trainingData.yml");

        //Test for 10 image sample - 7 & 9 must be classified.
       for (int i = 1; i <= 10; ++i) {
            Mat test(1,1,CV_32F);
            test.at<float>(0,0)= float(r.gaussian(200));
            float result = classifierSVM->predict(test);
            cout << test.at<float>(0, 0) <<": class " << result << endl;
        }
        waitKey(0);

and results are

[-3.2061895e-09;
 0.31627011;
 -1.4018559;
 -0.85719198;
 2.4774842;
 -0.55601645;
 -1.2967975;
 0.61032659;
 1.0300292;
 -2.2900875]

153.969: class 0
-9.28624: class 1
261.181: class 0
-391.937: class 1
-379.843: class 1
-107.448: class 1
-149.658: class 1
379.299: class 0
54.8101: class 0
-276.041: class 1
edit flag offensive delete link more

Comments

Thank you for your nice comment. :) But how about result with images? If you are OK, I can send you images I tested by email.

DoryeongPark gravatar imageDoryeongPark ( 2017-02-17 03:32:09 -0600 )edit

And I just wanna figure out why my code can't classify images

DoryeongPark gravatar imageDoryeongPark ( 2017-02-17 04:12:41 -0600 )edit

I'm trying to understand what does it mean ONE_CLASS; If you want you can help me to find bug . One class a gaussian center at (0,0) with variance(2,4) ... Red points are data green points good class and flase classification in white

LBerger gravatar imageLBerger ( 2017-02-17 05:26:27 -0600 )edit

Hello everybody!

I have the same problem, the prediction always returns 0. I'm trying to classify images with faces, and i just want to check if one face is or not in the training class. Just for test, i tried to train svm with the same image of the prediction, and it returns 0 the same!! I'm clearly doing wrong somewhere..
My code is the same of yours! Have you found a solution?

crazyfool gravatar imagecrazyfool ( 2018-02-26 05:57:57 -0600 )edit

@crazyfool , please do not post answers here, if you have a question or comment, thank you.

berak gravatar imageberak ( 2018-02-26 06:06:34 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2017-02-16 23:36:12 -0600

Seen: 2,490 times

Last updated: Feb 17 '17