2017-12-21 15 views
0

セダンとSUVの画像を分類するOpenCVでSVMを実装しようとしています。私は頻繁にこの記事を参照していますusing OpenCV and SVM with imagesSVMを使ってSUVとセダンを分類する

私はセダンとSUVの29枚のトレーニング画像を持っている、と私は、このように私の訓練は29ximage_areaのサイズをマット作り、1本当に長い行する各画像を伸ばします。下の写真は、training_matがすべて白で表示されていることを示しています。私はそれが正しいと確信していませんし、私の結果に影響を与えるかもしれません。

これは、training_matがフロートタイプである可能性があるためです。たとえば、training_matをCV_8UC1に変更すると、各画像がtraining_matで展開されていることがわかりますが、svm-> train関数はtraining_matを受け入れません。

私は実装の監視バージョンとしてlabels_matを使用します。 A 1はSUVを意味し、-1はセダンを意味する。下の図で、SVMモデルを使ってSUVを予測しようとすると、-800000000000のような値が得られます。私が何をするにしても(パラメータを変更し、すべての白のテスト画像、すべての黒のテスト画像、ラベルを1または-1に変更するだけです)、私はいつも同じ-80000000000の値を取得します。今や負の結果は-1(セダン)を意味するかもしれませんが、決して変わらないので私は確信できません。もし誰かがこれについての洞察力を持っていればそれは認められるでしょう

ここに私のコード、結果、そして全ての白いtraining_matがあります。 Result Image

int num_train_images = 29;  //29 images will be used to train the SVM 
int image_area = 150 * 200;  
Mat training_mat(num_train_images, image_area, CV_32FC1); // Creates a 29 rows by 30000 columns... 29 150x200 images will be put into 1 row per image 

                  //Converts 29 2D images into a really long row per image 
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 

    int ii = 0;         //Scans each column 
    for (int i = 0; i < training_img.rows; i++) 
    { 
     for (int j = 0; j < training_img.cols; j++) 
     { 
      training_mat.at<float>(file_count - 1, ii) = training_img.at<uchar>(i, j); //Fills the training_mat with the read image 
      ii++; 
     } 
    } 
} 

imshow("Training Mat", training_mat); 
waitKey(0); 

//Labels are used as the supervised learning portion of the SVM. If it is a 1, its an SUV test image. -1 means a sedan. 
int labels[29] = { 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1 }; 

//Place the labels into into a 29 row by 1 column matrix. 
Mat labels_mat(num_train_images, 1, CV_32S); 

cout << "Beginning Training..." << endl; 

//Set SVM Parameters (not sure about these values) 
Ptr<SVM> svm = SVM::create(); 
svm->setType(SVM::C_SVC); 
svm->setKernel(SVM::RBF); 
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6)); 
svm->setGamma(1); 
svm->setDegree(3); 

cout << "Parameters Set..." << endl; 

svm->train(training_mat, ROW_SAMPLE, labels_mat); 

cout << "End Training" << endl; 

waitKey(0); 

Mat test_image(1, image_area, CV_32FC1);  //Creates a 1 x 1200 matrix to house the test image. 

Mat SUV_image = imread("SUV_1.jpg", 0);   //Read the file folder 

int jj = 0; 
for (int i = 0; i < SUV_image.rows; i++) 
{ 
    for (int j = 0; j < SUV_image.cols; j++) 
    { 
     test_image.at<float>(0, jj) = SUV_image.at<uchar>(i, j); //Fills the training_mat 
     jj++; 
    } 
} 

//Should return a 1 if its an SUV, or a -1 if its a sedan 
float result = svm->predict(test_image); 

if (result < 0) 
    cout << "Sedan" << endl; 
else 
    cout << "SUV" << endl; 

cout << "Result: " << result << endl; 

namedWindow("Test Image", CV_WINDOW_NORMAL); 
imshow("Test Image", SUV_image); 
waitKey(0); 
+0

あなたのラボは浮動小数点でなければならないと思います。それは説明されていませんが、私が見たすべての例がそうです。少なくとも試してみるのは簡単です。また、OpenCVでは、浮動小数点数のcv :: Matは、表示目的で0〜1の間であると想定されています。つまり、1.0より大きい場合は白になります。値が1.0より大きい場合は正常になる可能性があります。それを視覚化するには、cv :: normalize(floatMat、anotherMat、0,255、cv :: NORM_MINMAX、CV_8U)を実行します。 (私はメモリでそれを書いて以来、私は間違っている最後の2つのパラメータの順序を持​​っている可能性があります) – api55

答えて

0

この問題を解決するには、この記事を参照してください。 Using SVM with HOG Features to Classify Vehicles

ここでは、イメージの単なるピクセル値ではなく、HOG機能を使用します。 training_matはもはや白ではなく、クラシファイアはうまく機能します。さらに、出力結果は1または-1です。

関連する問題