Ask Your Question

luisb1393's profile - activity

2017-04-26 12:23:34 -0600 commented answer How to choose index in getDecisionFunction for multiclass SVM

Thank you very much... I will try according to your advice. I will also use English for my code... Thank you... I will let you know how it goes... Really... I am very grateful for how quickly your response arrived... I had just posted this question yesterday at night (in Peru it was about 9 p.m., and the time I am writing this is 12.23 midday).

2017-04-25 21:01:00 -0600 asked a question How to choose index in getDecisionFunction for multiclass SVM

The objective is to train an SVM to classify up to 10 digits handwritten. So the SVM is a muticlass classifier.

As a result of the training, I have got a yml file which indicates the SVM has a total of 1009 support vectors, a class_count of 10 (because there are 10 digits in the training dataset). It all works very fine. But now I would like to use cv::ml::HOGDescripctor::detectMiltiscale(), in order to detect the digits in any other image or video. My problem arrises when I try to use the HOG::setSVMDetector function, since the SVM model I have just created is not compatible (I tried and it returned errors). So I search on the Internet the way to process the SVM support vectors so as to load it in the setSVMDetector function.

I have found loads of forums pointing to this function:

void get_svm_detector(const Ptr<SVM>& svm, vector< float > & hog_detector ){
// get the support vectors
Mat sv = svm->getSupportVectors();
const int sv_total = sv.rows;
// get the decision function
Mat alpha, svidx;
double rho = svm->getDecisionFunction(0, alpha, svidx);

CV_Assert( alpha.total() == 1 && svidx.total() == 1 && sv_total == 1 );
CV_Assert( (alpha.type() == CV_64F && alpha.at<double>(0) == 1.) ||
           (alpha.type() == CV_32F && alpha.at<float>(0) == 1.f) );
CV_Assert( sv.type() == CV_32F );
hog_detector.clear();

hog_detector.resize(sv.cols + 1);
memcpy(&hog_detector[0], sv.ptr(), sv.cols*sizeof(hog_detector[0]));
hog_detector[sv.cols] = (float)-rho;

}

But I have analize it, and the ASSERT this code have will launch an exception in runtime since the sv_total is not equal to 1 for my SVM model (it is equal to 1009). So I have to get rid of the ASSERTS, but now, the problem I with which index I should ue in the getDecisionFunction(0, alpha, svidx) since according to documentation, 0 is just for one or two-class models, but mine is 10-class model. I tried using 45, since there will be 45 different equations to solve, but it launches and error, I tried with 1, 2, and with 10, but I never finds the correct digits on my test image.

The code I implemented is the following (I try to use my variable names in Spanish, I love my language jejeje):

cv::Mat sv = svm->getSupportVectors();
const int sv_total = sv.rows;
cv::Mat alpha, svidx;
double rho = svm->getDecisionFunction(10, alpha, svidx);
vector<float> svmDetector;
svmDetector.clear();
svmDetector.resize(sv.cols + 1);
memcpy(&svmDetector[0], sv.ptr(), sv.cols * sizeof(svmDetector[0]));
svmDetector[sv.cols] = (float)-rho;

And I use the result, svmDetector, in this way with the rest:

hog.setSVMDetector(svmDetector);
hog.detectMultiScale(imagenPrueba, encontrados, 2);
cout << encontrados.size() << endl;
cv::Mat resultadoImagen;
vector<cv::Mat> grises;
grises.push_back(imagenPrueba);
grises.push_back(imagenPrueba);
grises.push_back(imagenPrueba);
cv::merge(grises, resultadoImagen);
for(int i=0;i<encontrados.size();i++)
    cv::rectangle(resultadoImagen, encontrados[i], cv::Scalar(0, 0, 255));

cv::imshow("RESULTADO", resultadoImagen);
cv::waitKey(0);

I have read a lot about it, but still cannot figure out how to ... (more)