opencv 3 (C++) auto trained SVM loading issue

纵饮孤独 提交于 2019-12-12 03:17:53

问题


I'm using SVM to do classification, and I do the training in one project, testing in another, in order to train only once.

The TRAINing part is as follows:

classifier->trainAuto(trainData);
string svmDir = "/File/Dir/";
string svmFile = "svmClassifier.xml";
classifier->save(svmDir+svmFile);

And the TESTing part is:

string svmDir = "/File/Dir/";
string svmFile = "svmClassifier.xml";
Ptr<ml::SVM> classifier = ml::SVM::load<ml::SVM>(svmDir+svmFile);
...
float response = classifier->predict(tDescriptor);

The prediction gives all 0s (all negative). But when I do the prediction right after the SVM training in the Training Project, the predictions are correct (I used breakpoint before "predict", the tDescriptor passed to predict are the same in both projects.) So I think there might be something wrong with saving and loading process..

Can the auto trained SVM be saved and loaded? Or it must be in the statModel?

Thanks for help!


回答1:


The flowing code was taken and modified from Introduction to Support Vector Machines for open CV. I saved the SVM parameters from the object svmOld "trainedSVM.xml". Then loaded the XML file and used them to create the object svmNew.

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
using namespace cv;
using namespace cv::ml;
using namespace std;

int main()
{



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

    // Set up training data
    int Lable[] = { 1, -1, -1, -1 };
    Mat labelsMat(4, 1, CV_32S, Lable);


    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> svmOld = SVM::create();
    svmOld->setType(SVM::C_SVC);
    svmOld->setKernel(SVM::LINEAR);
    svmOld->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));

    // Train the SVM with given parameters
    Ptr<TrainData> td = TrainData::create(trainingDataMat, ROW_SAMPLE, labelsMat);
    svmOld->train(td);
    //same svm 
    svmOld->save("trainedSVM.xml");


    //Initialize SVM object   
    Ptr<SVM> svmNew = SVM::create();
    //Load Previously saved SVM from XML 

    svmNew = SVM::load<SVM>("trainedSVM.xml");



    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 = svmNew->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;
    Mat sv = svmNew->getSupportVectors();

    for (int i = 0; i < sv.rows; ++i)
    {
        const float* v = sv.ptr<float>(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);
    return(0);
}


来源:https://stackoverflow.com/questions/32863392/opencv-3-c-auto-trained-svm-loading-issue

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!