My goal here is to classify between SUVs and sedans using SVMs and HOG features.
First I read 86 training images, calculate the HOG features for each of them, and put them in a training Mat that is of size 86xdescriptorSize called HOGFeat_train.
Mat HOGFeat_train(num_train_images, derSize, CV_32FC1); //86xdescriptor size training Mat
for (int file_count = 1; file_count < (num_train_images + 1); file_count++)
{
ss << name << file_count << type; //'Vehicle_1.jpg' ... 'Vehicle_2.jpg' ... etc ...
string filename = ss.str();
ss.str("");
Mat training_img = imread(filename, 0); //Reads the training images from the folder
HOGDescriptor hog_train;
vector<float> descriptors_train;
vector<Point> locations_train;
hog_train.compute(training_img, descriptors_train, Size(16, 16), Size(0, 0), locations_train); //not sure about these values
for (int i = 0; i < descriptors_train.size(); i++)
HOGFeat_train.at<float>(file_count-1, i) = descriptors_train.at(i);
}
Next I create a labels_mat of 86 labels for the supervised learning portion of the SVM (I know this way is impractical and time consuming, which I'll fix later). 1 means SUV, and a -1 means a sedan. Not sure about these SVM Parameters but I've tried different varieties and values but all results are the same.
float labels[86] = { 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1};
Mat labels_mat(num_train_images, 1, CV_32S);
cout << "Beginning Training..." << endl;
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::LINEAR);
//svm->setDegree(3);
//svm->setGamma(2);
//svm->setC(.5);
cout << "Parameters Set..." << endl;
svm->train(HOGFeat_train, ROW_SAMPLE, labels_mat);
cout << "Training Successful" << endl;
Next I read 10 test images the same way I did with the train images, and compute the HOG features again. After the HOG features are computed they are placed into 1 row x descriptorSized HOGFeat_test Mat, and then I use svm->predict on that HOGFeat_test Mat which should return a value of -1 to denote a sedan or 1 to denote an SUV.
Mat HOGFeat_test(1, derSize, CV_32FC1); //Creates a 1 x descriptorSize Mat to house the HoG features from the test image
for (int file_count = 1; file_count < (num_test_images + 1); file_count++)
{
ss2 << name2 << file_count << type2; //'Test_1.jpg' ... 'Test_2.jpg' ... etc ...
string filename2 = ss2.str();
ss2.str("");
Mat test_image = imread(filename2, 0); //Read the file folder
HOGDescriptor hog_test;
vector<float> descriptors_test;
vector<Point> locations_test;
hog_test.compute(test_image, descriptors_test, Size(16, 16), Size(0, 0), locations_test);
for (int i = 0; i < descriptors_test.size(); i++)
HOGFeat_test.at<float>(0, i) = descriptors_test.at(i);
namedWindow("Test Image", CV_WINDOW_NORMAL);
imshow("Test Image", test_image);
//Should return a 1 if its an SUV, or a -1 if its a sedan
float result = svm->predict(HOGFeat_test);
if (result <= 0)
cout << "Sedan" << endl;
else
cout << "SUV" << endl;
cout << "Result: " << result << endl;
The following image shows the result, a test image, and the HOGFeat_train Mat in case it's useful to anyone. The result (Sedan, -8.412e08) is always the same no matter what values or parameters or images I use. The result is not a -1 or a 1 but -800000000000 and I'm assuming a negative value corresponds to a -1, but most importantly I'd like to know why the result isn't changing. Does anyone have any insight of this? Thanks.
EDIT----------------------------------------
I removed all of the ones from float labels[86] and simply left it as float labels[86]; //{1, 1, -1, etc...}
This showed no difference in the SVM result and it was still able to train successfully. This tells me that my labels arent going through the svm->train function or something. I will continue to investigate.
So this one was just a dumb mistake that I did to myself. I replaced the labels with float labels[86]; Basically I just removed the supervised learning portion of the SVM, yet I got the exact same results. Upon inspection I realize that I didnt fill the labels into the labels_mat!!!!!!
So performing the following results in a clear solution. Additionally, the result becomes 1 and -1 instead of -8.412e-8.
Mat labels_mat(num_train_images, 1, CV_32S, labels);