2012-11-09 16 views
5

Sono bloccato su questo.OpenCV SVM lancio dell'eccezione sul treno, "Argomento non valido (esiste solo una classe)"

Sto provando a eseguire alcune classificazioni di oggetti tramite il framework 2d di OpenCV, ma sto riscontrando problemi nell'addestramento del mio SVM.

Sono in grado di estrarre i vocabolari e raggrupparli con BowKMeansTrainer, ma dopo aver estratto le funzionalità dai dati di allenamento da aggiungere al trainer e aver eseguito il metodo SVM.train, ottengo la seguente eccezione.

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 

Ho provato modificando dimensione del dizionario, utilizzando diversi formatori, assicurando miei tipi di matrice sono corrette (al meglio delle mie capacità, ancora nuovo opencv).

Qualcuno ha visto questo errore o ha qualche idea su come risolverlo?

Il mio codice è simile al seguente:

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

Cosa fa esattamente "extractBOWDescriptor'? E qual è la dimensione di 'trainingData' e' labels'? – luhb

+0

extractBOWDescriptor esegue semplicemente un itereat attraverso un elenco di file, trova le caratteristiche (utilizzando il rilevatore di funzioni SURF), estrae quelle funzionalità, le spinge ai dati di formazione e quindi inserisce una voce nelle etichette. – tuck

+0

la dimensione dei dati di allenamento è dictionary_size x 2 e label is number_of_images x 2 – tuck

risposta

10

base all'errore, sembra che il tuo labels contiene una sola categoria di dati. Cioè, tutte le funzionalità nel tuo trainingData hanno la stessa etichetta.

Ad esempio, supponiamo di provare a utilizzare SVM per determinare se un'immagine contiene un gatto oppure no. Se ogni voce nel labels è lo stesso, allora o ...

  • tutte le immagini di addestramento sono etichettati come "sì questo è un gatto"
  • o, tutte le immagini di addestramento sono etichettati come "no, questo non è un gatto. "

SVM cercano di separare due (o qualche volta più) classi di dati, quindi la libreria SVM si lamenta se si fornisce solo una classe di dati.

Per verificare se questo è il problema, è consigliabile aggiungere una dichiarazione di stampa per verificare se labels contiene solo una categoria. Ecco il codice per fare questo:

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

Una volta che i extractBOWDescriptor() carica i dati in labels, sto supponendo che labels è di dimensioni (trainingData.rows, trainingData.cols). In caso contrario, questo potrebbe essere un problema.

Problemi correlati