2017-12-21 8 views
0

여기 내 목표는 SVM 및 HOG 기능을 사용하여 SUV와 세단 간을 분류하는 것입니다.HOG 기능이있는 SVM을 사용하여 차량 분류

먼저 86 개의 학습 이미지를 읽고 각자의 HOG 기능을 계산 한 후 HOGFeat_train이라는 크기의 교육 매트 인 86xdescriptorSize에 넣습니다.

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); 
} 

다음 나는 SVM (내가 나중에 고칠거야하는이 방법은 실용적이지 시간이 소요 알고)의지도 학습 부분에 대한 86 개 레이블 labels_mat을 만들 수 있습니다. 1은 SUV를 의미하고 -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 기능을 다시 계산합니다. 호각 기능이 계산 된 후 1 행 x descriptorSized HOGFeat_test 매트에 배치 된 다음 svm-> predict를 사용하여 HOGFeat_test 매트에 -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; 

다음 이미지는 결과, 테스트 이미지 및 모든 사람에게 유용 할 수있는 HOGFeat_train 매트를 보여줍니다. 결과 (Sedan, -8.412e08)는 내가 사용하는 값이나 매개 변수 또는 이미지에 관계없이 항상 동일합니다. 결과는 -1 또는 1이 아닌 -800000000000이 아니며 음수 값이 -1과 일치한다고 가정하지만 가장 중요한 것은 왜 결과가 변경되지 않는지 알고 싶습니다. 누구도 이것에 대한 통찰력을 가지고 있습니까? 감사. enter image description here

편집 ----------------------------------------

나는 플로트 레이블 [86]에서 모든 것을 제거하고 플로트 레이블 [86]로 남겨 두었습니다. // {1, 1, -1, etc ...}

이것은 SVM 결과에 차이가 없었으며 여전히 성공적으로 훈련 할 수있었습니다. 이것은 내 레이블이 svm-> train 기능을 통과하지 못한다는 것을 말해줍니다. 나는 계속 조사 할 것이다.

답변

0

그래서이 것은 내가 나 자신에게 한 바보 같은 실수였습니다. 나는 플로트 라벨로 라벨을 대체했다. 기본적으로 SVM의 감독 학습 부분을 제거했지만 아직 정확한 결과를 얻었습니다. 나는 라벨에 라벨을 채우지 못했다는 것을 깨닫는다. !!!!!!

다음과 같은 결과를 명확한 해결책으로 수행하십시오. 또한 결과는 -8.412e-8 대신 1 및 -1이됩니다.

매트 labels_mat (num_train_images, 1, CV_32S, labels);

관련 문제