简体   繁体   English

使用具有HOG功能的SVM对车辆进行分类

[英]Using SVM with HOG Features to Classify Vehicles

My goal here is to classify between SUVs and sedans using SVMs and HOG features. 我的目标是使用SVM和HOG功能在SUV和轿车之间进行分类。

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. 首先,我阅读了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);
}

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). 接下来,我为SVM的监督学习部分创建了86个标签的labels_mat(我知道这种方式不切实际且耗时,稍后将进行修复)。 1 means SUV, and a -1 means a sedan. 1表示SUV,-1表示轿车。 Not sure about these SVM Parameters but I've tried different varieties and values but all results are the same. 不确定这些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;

Next I read 10 test images the same way I did with the train images, and compute the HOG features again. 接下来,以与训练图像相同的方式读取10张测试图像,然后再次计算HOG功能。 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. 在计算出HOG功能后,将它们放入1行x描述符化的HOGFeat_test Mat中,然后在该HOGFeat_test Mat上使用svm-> predict,它应返回值-1表示轿车或1表示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. 下图显示了结果,测试图像以及HOGFeat_train Mat(如果它对任何人有用)。 The result (Sedan, -8.412e08) is always the same no matter what values or parameters or images I use. 无论我使用什么值,参数或图像,结果(Sedan,-8.412e08)始终相同。 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. 结果不是-1或1,而是-800000000000,我假设负值对应于-1,但最重要的是,我想知道为什么结果没有变化。 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]; 我从浮动标签[86]中删除了所有标签,然后将其保留为浮动标签[86]; //{1, 1, -1, etc...} // {1、1,-1等...}

This showed no difference in the SVM result and it was still able to train successfully. 这表明SVM结果没有差异,并且仍然能够成功进行训练。 This tells me that my labels arent going through the svm->train function or something. 这告诉我,我的标签arent通过svm-> train函数之类的东西。 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]; 我用浮动标签替换了标签[86]; Basically I just removed the supervised learning portion of the SVM, yet I got the exact same results. 基本上,我只是删除了SVM的监督学习部分,但得到的结果完全相同。 Upon inspection I realize that I didnt fill the labels into the labels_mat!!!!!! 经检查,我意识到我没有将标签填入labels_mat!

So performing the following results in a clear solution. 因此,执行以下操作可获得明确的解决方案。 Additionally, the result becomes 1 and -1 instead of -8.412e-8. 此外,结果变为1和-1,而不是-8.412e-8。

Mat labels_mat(num_train_images, 1, CV_32S, labels); 垫标签_垫(num_train_images,1,CV_32S,标签);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM