Моя цель здесь - разделить внедорожники и седаны с использованием функций SVM и HOG.
Сначала я прочитал 86 обучающих изображений, вычислил характеристики HOG для каждого из них и поместил их в обучающую матрицу размером 86xdescriptorSize под названием 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);
}
Затем я создаю label_mat из 86 меток для контролируемой обучающей части SVM (я знаю, что этот способ непрактичен и требует много времени, что я исправлю позже). 1 означает внедорожник, а -1 означает седан. Не уверен в этих параметрах SVM, но я пробовал разные варианты и значения, но все результаты одинаковы.
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;
Затем я прочитал 10 тестовых изображений так же, как и с изображениями поездов, и снова вычислил особенности HOG. После того, как функции HOG вычислены, они помещаются в 1 строку x descriptorSized HOGFeat_test Mat, а затем я использую svm-> прогноз на этом мате HOGFeat_test, который должен возвращать значение -1 для обозначения седана или 1 для обозначения внедорожника.
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;
На следующем изображении показан результат, тестовое изображение и коврик HOGFeat_train на случай, если он будет кому-то полезен. Результат (седан, -8.412e08) всегда один и тот же, независимо от того, какие значения, параметры или изображения я использую. Результатом будет не -1 или 1, а -800000000000, и я предполагаю, что отрицательное значение соответствует -1, но, что наиболее важно, я хотел бы знать, почему результат не меняется. Кто-нибудь знает об этом? Спасибо.
РЕДАКТИРОВАТЬ----------------------------------------
Я удалил все метки из меток с плавающей запятой [86] и просто оставил их как метки с плавающей запятой [86]; // {1, 1, -1 и т. Д. ...}
Это не показало разницы в результатах SVM, и он все еще мог успешно тренироваться. Это говорит мне, что мои ярлыки не проходят через функцию svm-> train или что-то в этом роде. Я продолжу расследование.