SVM for classification

The Support Vector Machine (SVM) classifier finds a discriminant function by maximizing the geometrical margin between the classes. Thus, the space is mapped in such a way that the classes are as widely separated as possible. SVM minimizes both the training error and the geometrical margin. Nowadays, this classifier is one of the best classifiers available and has been applied to many real-world problems. The following SVMClassifier sample code performs a classification using the SVM classifier and a dataset of 66 image objects. The dataset is divided into four classes: a training shoe (class 1), a cuddly toy (class 2), a plastic cup (class 3), and a bow (class 4). The following screenshot shows the examples of the four classes. A total of 56 images and 10 images were used for the training and the test sets, respectively. Images in the training set take the following name structure: [1-14].png corresponds to class 1, [15-28].png to class 2, [29-42].png to class 3, and [43-56].png to class 4. On the other hand, images in the test set are characterized by the word unknown followed by a number, for example, unknown1.png.

Tip

The images of the four classes have been extracted from the Amsterdam Library of Object Images (ALOI) available at http://aloi.science.uva.nl/.

SVM for classification

Classes selected for the SVM classification example

The SVMClassifier sample code is as follows:

//… (omitted for simplicity)
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>

using namespace std;
using namespace cv;

int main(int argc, char *argv[]){

    Mat groups;
    Mat samples;
    vector<KeyPoint> keypoints1;
    //ORB feature detector with 15 interest points
    OrbFeatureDetector detector(15, 1.2f, 2, 31,0, 2, ORB::HARRIS_SCORE, 31);
    Mat descriptors, descriptors2;
    //SURF feature descriptor
    SurfDescriptorExtractor extractor;

    //Training samples
    for(int i=1; i<=56; i++){
        stringstream nn;
        nn <<i<<".png";
        //Read the image to be trained
        Mat img=imread(nn.str());
        cvtColor(img, img, COLOR_BGR2GRAY);
        //Detect interest points
        detector.detect(img, keypoints1);
        //Compute SURF descriptors
        extractor.compute(img, keypoints1, descriptors);
        //Organize and save information in one row
        samples.push_back(descriptors.reshape(1,1));
        keypoints1.clear();
    }

    //Set the labels of each sample
    for(int j=1; j<=56; j++){
        if(j<=14)  groups.push_back(1);
        else if(j>14 && j<=28)  groups.push_back(2);
             else if(j>28 && j<=42)  groups.push_back(3);
                  else groups.push_back(4);
    }

    //Indicate SVM parameters
    CvSVMParams params=CvSVMParams(CvSVM::C_SVC, CvSVM::LINEAR, 0, 1, 0, 1, 0, 0, 0, cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, FLT_EPSILON));

    //Create SVM classifier
    CvSVM classifierSVM;

    //Train classifier
    classifierSVM.train(samples, groups, Mat(), Mat(), params );

    //Test samples
    for(int i=1; i<=10; i++){
        stringstream nn;
        nn <<"unknown"<<i<<".png";
        //Read the image to be tested
        Mat unknown=imread(nn.str());
        cvtColor(unknown, unknown, COLOR_BGR2GRAY);
        //Detect interest points
        detector.detect(unknown, keypoints1);
        //Compute descriptors
        extractor.compute(unknown, keypoints1, descriptors2);
        //Test sample
        float result=classifierSVM.predict(descriptors2.reshape(1,1));
        //Print result
        cout<<nn.str()<<": class "<<result<<endl;
    }
    return 0;
}

The explanation of the code is given as follows. In this example, images are represented by their descriptors (see Chapter 5, Focusing on the Interesting 2D Features). For each image in the training set, its interest points are detected using an Oriented FAST and Rotated BRIEF (ORB) detector (OrbFeatureDetector) and its descriptors are computed using the Speeded Up Robust Features (SURF) descriptor (SurfDescriptorExtractor).

An SVM classifier is created using the CvSVM class and its parameters are set using the CvSVMParams::CvSVMParams(int svm_type, int kernel_type, double degree, double gamma, double coef0, double Cvalue, double nu, double p, CvMat* class_weights, CvTermCriteria term_crit) constructor. The interesting parameters in this constructor are the type of SVM (svm_type) and the type of kernel (kernel_type). The first specified parameter takes, in our case, the CvSVM::C_SVC value because an n-classification (n SVM for classification 2) with an imperfect separation of the classes is needed. It also uses a C penalty value for atypical values. C acts, therefore, as a regularizer. The kernel_type parameter indicates the type of SVM kernel. The kernel represents the basis function required to separate the cases. For the SVM classifier, OpenCV includes the following kernels:

  • CvSVM::LINEAR: The linear kernel
  • CvSVM::POLY: The polynomial kernel
  • CvSVM::RBF: The radial basis function
  • CvSVM::SIGMOID: The sigmoid kernel

Then, the classifier builds an optimal linear discriminating function using the training set (with the train function). Now, it is prepared to classify new unlabeled samples. The test set is used for this purpose. Note that we also have to calculate the ORB detector and the SURF descriptors for each image in the test set. The result is as shown in the following screenshot, where all the classes have been classified correctly:

SVM for classification

The classification result using SVM

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset