简体   繁体   中英

Tutorials for SVM with c++

I am trying to use SVM for object detection with c++. I am following this answer . I am facing one problem that CvSVM is not used as of now. So I have modified the training code as follows.

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>

using namespace cv;
using namespace cv::ml;

int main()
{
    // Data for visual representation
        int width = 512, height = 512;
    Mat image = Mat::zeros(height, width, CV_8UC3); 

    // Set up training data
        float labels[4] = {1.0, -1.0, -1.0, -1.0};
        Mat labelsMat(4, 1, CV_32FC1, labels);  
    float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
    Mat trainingDataMat(4, 2, CV_32FC1, trainingData);

// Set up SVM's parameters
        Ptr<SVM> svm = SVM::create();
        svm->setType(SVM::C_SVC);
        svm->setKernel(SVM::LINEAR);
//svm.term_crit   = SVM::getTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);

// Train the SVM
//Ptr<SVM> svm1 = SVM::trainAuto();

        SVM->train(trainingDataMat, labelsMat, Mat(), Mat(), svm);

        Vec3b green(0,255,0), blue (255,0,0);
// Show the decision regions given by the SVM
        for (int i = 0; i < image.rows; ++i)
        for (int j = 0; j < image.cols; ++j)
        {
                Mat sampleMat = (Mat_<float>(1,2) << j,i);
                float response = svm->predict(sampleMat);

                if (response == 1)
                image.at<Vec3b>(i,j)  = green;
                else if (response == -1)
                image.at<Vec3b>(i,j)  = blue;
        }

// Show the training data
        int thickness = -1;
        int lineType = 8;
        circle( image, Point(501,  10), 5, Scalar(  0,   0,   0), thickness, lineType);
        circle( image, Point(255,  10), 5, Scalar(255, 255, 255), thickness, lineType);
        circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);
        circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType);

// Show support vectors
        thickness = 2;
        lineType  = 8;
        int c     = SVM.get_support_vector_count();

        for (int i = 0; i < c; ++i)
        {
            const float* v = SVM.get_support_vector(i);
            circle( image,  Point( (int) v[0], (int) v[1]),   6,   Scalar(128, 128, 128), thickness, lineType);
        }

        imwrite("result.png", image);        // save the image

        imshow("SVM Simple Example", image); // show it to the user
        waitKey(0);

}

I am not able to implement the train function. It says that the function is not found. Please help me out with a newer version of this code.

You have several errors in your code. Some are C++ syntactic errors, some are due the fact that you are using OpenCV 2.4.X api, which is different from OpenCV 3.0

1) When you are referring to the svm instance, you should use svm (the variable name), not SVM the class name.

2) In the case of classification problem the responses must be categorical. So

float labels[4] = { 1.0, -1.0, -1.0, -1.0 };
Mat labelsMat(4, 1, CV_32FC1, labels);

should be:

int labels[4] = { 1, -1, -1, -1 };
Mat labelsMat(4, 1, CV_32SC1, labels); 

3) train accepts different parameters. SVM->train(trainingDataMat, labelsMat, Mat(), Mat(), svm); should be: svm->train(trainingDataMat, ROW_SAMPLE, labelsMat);

4) get_support_vector_count doesn't exists in OpenCV 3.0. int c = SVM.get_support_vector_count(); should be: int c = svm->getSupportVectors().rows;

5) get_support_vector doesn't exists in OpenCV 3.0. const float* v = SVM.get_support_vector(i); should be: const float* v = svm->getSupportVectors().ptr<float>(i);


The code in this answer already works as expected. If you introduce such errors it won't work, obviously.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM