c++ - OpenCV SVM Training Data -


i learn svm implementation using opencv 3.00 library in c++ , visual studio 2013. code:

#include<stdio.h> #include<math.h> #include<opencv\cv.h> #include<opencv\highgui.h> #include<opencv2\objdetect\objdetect.hpp> #include<opencv2\highgui\highgui.hpp> #include<opencv2\imgproc\imgproc.hpp> #include<vector> #include <windows.h> #include <atlstr.h> #include <iostream> #include <sstream> #include <iomanip> #include <opencv2\imgproc\imgproc.hpp> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv\cvaux.hpp>  using namespace cv; using namespace std;  #include <opencv2\ml.hpp>  using namespace cv;  int main() {     // data visual representation     int width = 512, height = 512;     mat image = mat::zeros(height, width, cv_8uc3);      // set 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 svm's parameters      ptr<ml::svm> svm = ml::svm::create();     // edit: params struct got removed,     // use setter/getter now:     svm->settype(ml::svm::c_svc);     svm->setkernel(ml::svm::linear);     svm->setgamma(3);      svm->train(trainingdatamat, ml::row_sample, labelsmat);      mat res;   // output       vec3b green(0, 255, 0), blue(255, 0, 0);     // show decision regions given svm     (int = 0; < image.rows; ++i)         (int j = 0; j < image.cols; ++j)         {         mat samplemat = (mat_<float>(1, 2) << j, i);         float response = svm->predict(samplemat, res);          if (response == 1)             image.at<vec3b>(i, j) = green;         else if (response == -1)             image.at<vec3b>(i, j) = blue;         }      // show 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 = svm->getsupportvectors();      (int = 0; < 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 image      imshow("svm simple example", image); // show user     waitkey(0);  }  

after running code, got error:

opencv error: bad argument < in case of classification problem responses must categorical;  either specify vartype when creating traindata, or pass integer responses > in cv::ml::svmimpl::train,  file c:\builds\master_packslave-win64-vc12-shared\opencv\modules\ml\src\svm.cpp, line 1610 

i debugged code. debugger stops @ line: svm->train(trainingdatamat, ml::row_sample, labelsmat);

it says:

 first-chance exception @ 0x000007fefda5aaad in train.exe: microsoft c++ exception: cv::exception @ memory location 0x00000000001cee50.     unhandled exception @ 0x000007fefda5aaad in train.exe: microsoft c++ exception: cv::exception @ memory location 0x00000000001cee50. 

besides, says that:

(win32): loaded 'c:\opencv3.0.0\opencv\build\x64\vc12\bin\opencv_world300d.dll'. cannot find or open pdb file. 

actually, understand problem related memory.

the type of responses cannot float or double.

change

float labels[4] = { 1.0, -1.0, -1.0, -1.0 }; mat labelsmat(4, 1, cv_32fc1, labels); 

to

int labels[4] = { 1, -1, -1, -1 }; mat labelsmat(4, 1, cv_32s, labels); 

btw, if using linear kernel, parameter c, not need setgamma.


another problem way predicted response. since each time there 1 sample predict, if want use return value response, should not pass res predict.

you can change

float response = svm->predict(samplemat, res); 

to

float response = svm->predict(samplemat); 

otherwise, if want use res, return value no longer response value. can response res instead.

you can change

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

to

if (res.at<float>(0) == 1)     image.at<vec3b>(i, j) = green; else if (res.at<float>(0) == -1)     image.at<vec3b>(i, j) = blue; } 

Comments

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -

How to provide Authorization & Authentication using Asp.net, C#? -