2017-12-15 25 views
0

感謝を作る...はイメージでSVMをトレーニングと予測あなたの助けのための

私は正常トラフィックの移動動画に車を検出し、そのしばらく前にいくつかのコードを書きました。そのコードの出力とこのコードの最終的な入力を150x200サイズの車両イメージとみなしてみましょう。

私が実装しようとしているのは、それらの車を取り、セダンとSUVの間でそれらを分類できるSVMです。 (セダンとSUVだけがあると仮定します)。 https://docs.opencv.org/3.0-beta/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html このリンク:using OpenCV and SVM with images

は、これらのリンクと提携構文はSVMを最新バージョンにSVMの実装のために少し時代遅れであることに注意してください

次のコードは密接にこのリンク上の情報を、以下によって実装されました私は持っている。

//Used to read multiple files from folder 
stringstream ss; 
string name = "Vehicle_"; 
string type = ".jpg"; 

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, 1);  //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++; 
     } 
    } 
} 

//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. 
float 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_32FC1, labels); 

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::LINEAR); 
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6)); 

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 30000 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 
svm->predict(test_image); 

waitKey(0); 

それでは、私がここでやっていることは、私がテスト画像を撮影し、その後training_mat 30,000列行で1行に各150 200で画像を変換です。

labels_matは、トレーニング画像がSUVまたはセダンであるかどうかを示すSVMの教師あり学習部分です。

コードはうまく構築されますが、残念なことにsvm-> trainになると正しく失敗し、「OpenCV Error:間違った引数です(応答がカテゴリに分類されている必要があります。 "TrainDataを作成するときにvarTypeを指定するか、整数応答を渡す")。

これは私のパラメータに何か問題がある可能性があります。 SVMにフィードする前に、画像の特徴を抽出する必要があるかもしれないと友人が示唆しました。

おかげ

+0

生のピクセルをフィーチャとして使用することはできますが、そのため、通常はまずフィーチャーを抽出します。物体検出/分類のためにSVMで使用される一般的な特徴は、HoG(指向勾配のヒストグラム)である。現在、多くの人々が、SVMの代わりに深い学習畳み込みニューロンネットワークを使用している。 ConvNetsのメリットの1つは、生の画像のみをフィードに与え、有用な機能(畳み込みフィルタとして)を身に付けさせることです。 – Micka

答えて

0

は、この問題は、整数型であることを、CV_32Sにlabels_matを変更することで解決しました。残念ながら、svm-> predict(test_image)が-1または1以外の大きな値を返すという新しい問題は依然として残っています。

関連する問題