1 | initial version |
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)
#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;
}
#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 :)