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
Post a Comment