Ask Your Question

Revision history [back]

Hello,

I have written a code that fetches HOG features from a given set of data and trains accordingly. Now remember to change the parameters as per the comments in the code. Also I am mentioning a code that will allow you to test the svm_training. Both the codes have been written and tested in Ubuntu(linux)

#################svmTrain.cpp
#include "cv.h" 
#include "highgui.h"
#include "ml.h"
#include <stdio.h>
#include <iostream>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <sstream>
#include <string>
#include <cstring>
#include <stdlib.h>

using namespace cv; 
using namespace std;

void reverse(char str[], int length)
{
    int start = 0;
    int end = length -1;
    while (start < end)
    {
        swap(*(str+start), *(str+end));
        start++;
        end--;
    }
}

// Implementation of itoa()
char* itoa(int num, char* str, int base)
{
    int i = 0;
    bool isNegative = false;

    /* Handle 0 explicitely, otherwise empty string is printed for 0 */
    if (num == 0)
    {
        str[i++] = '0';
        str[i] = '\0';
        return str;
    }

    // In standard itoa(), negative numbers are handled only with
    // base 10. Otherwise numbers are considered unsigned.
    if (num < 0 && base == 10)
    {
        isNegative = true;
        num = -num;
    }

    // Process individual digits
    while (num != 0)
    {
        int rem = num % base;
        str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
        num = num/base;
    }

    // If number is negative, append '-'
    if (isNegative)
        str[i++] = '-';

    str[i] = '\0'; // Append string terminator

    // Reverse the string
    reverse(str, i);

    return str;
}

int main()  
{  
 //variables  

 char FirstFileName[100]="train/";                  //the location of the training images.Both positives and negatives must be in same folder
 char lastname[100] = ".JPG";                       //type of the images
 float data[1000][3];                               
 int FileNum=5781;                                  //Number of images(Positives + negatives)

 vector< vector < float> > v_descriptorsValues;  
 vector< vector < Point> > v_locations;  
 Mat Hogfeat; 
 float labelsMat[5781];                              //Length of array must be equal to number of training images

 int img_area = 1*61236;                    //61236 is the number of features detected. Make sure you mention the number of features detected.
 Mat training_mat(FileNum,img_area,CV_32FC1);

//  Mat training_mat(4, 2, CV_32FC1, trainingData);
 for(int i=1; i<=FileNum; i++)  
 {  

  char FullFileName[100] = "";
  char number[100] = "";
  strcat(FullFileName,FirstFileName);
    itoa(i,number,10);
    strcat(FullFileName,number);
    strcat(FullFileName,lastname);

  //read image file  

  Mat img, img_gray;  
  img = imread(FullFileName);  

  //resizing  
  resize(img, img, Size(64,48) ); //Size(64,48) ); //Size(32*2,16*2)); //Size(80,72) );   
  //gray  
  cvtColor(img, img_gray, CV_RGB2GRAY);

    if(i < 1761)                                 // i must be less han number of positives
        {
            labelsMat[i-1] = 1.0;
        }
        else
        {
            labelsMat[i-1] = -1.0;
        }
//      cout << "values of " << d << " filled in training_mat" << endl;  

  //extract feature  
  HOGDescriptor d( Size(32,16), Size(8,8), Size(4,4), Size(4,4), 9);  
  vector< float> descriptorsValues;  
  vector< Point> locations;  
  d.compute( img_gray, descriptorsValues, Size(0,0), Size(0,0), locations);  

  v_descriptorsValues.push_back( descriptorsValues );  
  v_locations.push_back( locations );

    Hogfeat.create(descriptorsValues.size(),1,CV_32FC1);
//  cout << descriptorsValues.size() << endl;
    for(int j=0;j<descriptorsValues.size();j++)
    {
     Hogfeat.at<float>(0,j)=descriptorsValues.at(j);
    }

/*  int ii = 0; // Current column in training_mat
        for (int p = 0; p<Hogfeat.rows; p++) 
        {
            for (int q = 0; q < Hogfeat.cols; q++) 
            {
                    training_mat.at<float>(i,ii) = Hogfeat.at<float>(p,q);
                            cout << Hogfeat.at<float>(p,q) << endl;
                            ii++;
            }
        }
*/
}

cout << v_descriptorsValues[0][0] << endl;
int row=v_descriptorsValues.size(), col=v_descriptorsValues[0].size();
printf("col=%d, row=%d\n", row, col);



for (int p = 0; p<row; p++) 
        {
            for (int q = 0; q<col; q++) 
            {
                    training_mat.at<float>(p,q) = v_descriptorsValues[p][q];


            }
        }  


    cout << endl << "Training data ready" << endl;  
    Mat labels(5781, 1, CV_32FC1, labelsMat);                               //First parameter is the number of images
for(int i=1; i<=FileNum; i++)  
 {  
        cout << labels.at< float >(i-1, 0);
    }


    cout << "labels also ready" << endl;

    CvSVMParams params;
    params.svm_type = CvSVM::C_SVC;
    params.kernel_type = CvSVM::RBF;
    params.gamma = 20;
    params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 10000, 1e-6);
    params.degree = 0;
    params.C = 7;
    cout << "parameters ready" << endl;

    cout << "training started" << endl;
    CvSVM svm;
    svm.train(training_mat, labels, Mat(), Mat(), params);
    cout << "training ended" << endl;


    svm.save("test.xml"); // saving
    cout << "file saved" << endl;


    return 0;


}
######################Now the testing code : svmTest.cpp
#include "cv.h" 
#include "highgui.h"
#include "ml.h"
#include <stdio.h>
#include <iostream>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <sstream>
#include <string>
#include <cstring>
#include <stdlib.h>

using namespace cv; 
using namespace std;

int main(int argc, char** argv)
{
    vector< vector < float> > v_descriptorsValues;  
    vector< vector < Point> > v_locations;  
    Mat Hogfeat; 
    cout << "loading svm" << endl;
CvSVM svm;
    svm.load("test_hog.xml"); // loading
    cout << "svm loaded" << endl;
int num_files = 1;
    int img_area = 1*61236;
    Mat training_mat(num_files,img_area,CV_32FC1);

    Mat img, img_gray;  
  img = imread(argv[1]);

    //resizing  
  resize(img, img, Size(64,48) ); //Size(64,48) ); //Size(32*2,16*2)); //Size(80,72) );   
  //gray  
  cvtColor(img, img_gray, CV_RGB2GRAY);  
  cout << "calculation starting" << endl;
  //extract feature  
  HOGDescriptor d( Size(32,16), Size(8,8), Size(4,4), Size(4,4), 9);  
  vector< float> descriptorsValues;  
  vector< Point> locations;  
  d.compute( img_gray, descriptorsValues, Size(0,0), Size(0,0), locations);  

  v_descriptorsValues.push_back( descriptorsValues );  
  v_locations.push_back( locations );
  cout << "descriptor calculated" << endl;

int row=v_descriptorsValues.size(), col=v_descriptorsValues[0].size();
for (int p = 0; p<row; p++) 
        {
            for (int q = 0; q<col; q++) 
            {
                    training_mat.at<float>(p,q) = v_descriptorsValues[p][q];


            }
        }

    int response = svm.predict(training_mat);
    cout << " response =  " << response << endl; 

return 0;
}

      I hope this will help you :)