2012-11-09 10 views
5

私はこれに固執しています。OpenCV SVMが電車に例外を投げている、「不正な引数(クラスは1つだけです)」

私はOpenCV機能2dフレームワークを使ってオブジェクトの分類をしようとしていますが、私のSVMのトレーニングでは問題が発生しています。

BowKMeansTrainerを使用してボキャブラリを抽出できますが、トレーニングデータからフィーチャを抽出してトレーナに追加してSVM.trainメソッドを実行すると、次の例外が発生します。

OpenCV Error: Bad argument (There is only a single class) in  cvPreprocessCategoricalResponses, file /home/tbu/prog/OpenCV-2.4.2/modules/ml/src /inner_functions.cpp, line 729 
terminate called after throwing an instance of 'cv::Exception' 
what(): /home/tbuchy/prog/OpenCV-2.4.2/modules/ml/src/inner_functions.cpp:729: error:  (-5) There is only a single class in function cvPreprocessCategoricalResponses 

私はマトリックスタイプは(まだ新しいOpenCVのに、私の能力を最大限に)正しい確保し、異なるトレーナーを使用して、辞書サイズを変更しようとしています。

このエラーが発生しましたか、それを修正する方法についての洞察はありますか?

私のコードは次のようになります。エラーに基づいて

trainingPaths = getFilePaths(); 
extractTrainingVocab(trainingPaths); 
cout<<"Clustering..."<<endl; 
Mat dictionary = bowTrainer.cluster(); 
bowDE.setVocabulary(dictionary); 


Mat trainingData(0, dictionarySize, CV_32FC1); 
Mat labels(0, 1, CV_32FC1); 
extractBOWDescriptor(trainingPaths, trainingData, labels); 


//making the classifier 
CvSVM classifier; 
CvSVMParams params; 
params.svm_type = CvSVM::C_SVC; 
params.kernel_type = CvSVM::LINEAR; 
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6); 

classifier.train(trainingData, labels, Mat(), Mat(), params); 
+0

'extractBOWDescriptor'は正確に何をしますか? 'trainingData'と' labels'のサイズは? – luhb

+0

extractBOWDescriptorは、ファイルのリストをただちに検索し、(SURFフィーチャディテクタを使用して)フィーチャを見つけ出し、フィーチャを抽出し、trainingDataにプッシュして、ラベルにエントリをプッシュします。 – tuck

+0

トレーニングデータのサイズはdictionary_size x 2であり、ラベルはnumber_of_images x 2 – tuck

答えて

10

あなたlabelsはデータのみの一つのカテゴリが含まれているように、それが見えます。つまり、trainingDataのすべての機能に同じラベルが付いています。

たとえば、SVMを使用して画像に猫が含まれているかどうかを判断しようとしているとします。 labels内のすべてのエントリが同じであれば、どちらか...

  • すべてのあなたのトレーニング画像が
  • 「はい、これは猫である」や、すべてのあなたのトレーニング画像がありません「と表示されている、とラベル付けされていますこれは猫ではない」

SVMは2つ(またはそれ以上)のデータクラスを分離しようとするため、SVMライブラリは1つのクラスのデータのみを提供する場合に不平を言います。

これが問題であるかどうかを確認するには、labelsに1つのカテゴリのみが含まれているかどうかを確認するprint文を追加することをお勧めします。ここでは、この行うにはいくつかのコードです:labelsにあなたextractBOWDescriptor()データをロードしたら

//check: are the printouts all the same? 
for(int i=0; i<labels.rows; i++) 
    for(int j=0; j<labels.cols; j++) 
     printf("labels(%d, %d) = %f \n", i, j, labels.at<float>(i,j)); 

が、私はlabelsサイズ(trainingData.rows, trainingData.cols)であることを仮定しています。そうでない場合、これは問題になる可能性があります。

関連する問題