Использование SVM с функциями HOG для классификации транспортных средств

Моя цель здесь - разделить внедорожники и седаны с использованием функций 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 или что-то в этом роде. Я продолжу расследование.


person David Rose    schedule 21.12.2017    source источник


Ответы (1)


Так что это была просто глупая ошибка, которую я сделал сам с собой. Я заменил метки на метки с плавающей запятой [86]; По сути, я просто удалил контролируемое обучение из SVM, но получил точно такие же результаты. При осмотре я понимаю, что не залил ярлыки в label_mat !!!!!!

Таким образом, выполнение следующих результатов дает четкое решение. Вдобавок результат будет 1 и -1 вместо -8.412e-8.

Коврик labels_mat (num_train_images, 1, CV_32S, labels);

person David Rose    schedule 22.12.2017