Я застрял на этом.
Я пытаюсь провести некоторую классификацию объектов с помощью OpenCV Feature 2d Framework, но у меня возникают проблемы при обучении моего 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);
Судя по ошибке, похоже, что labels
содержит только одну категорию данных. То есть все функции в вашем trainingData
иметь одинаковую метку.
Например, скажем, вы пытаетесь использовать SVM, чтобы определить, содержит ли изображение кошку или нет. Если каждая запись в labels
то же самое, то либо …
SVM пытаются разделить два (или иногда больше) класса данных, поэтому библиотека SVM жалуется, если вы предоставляете только один класс данных.
Чтобы увидеть, если это проблема, Я рекомендую добавить заявление на печать, чтобы проверить, labels
содержит только одну категорию. Вот некоторый код для этого:
//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));
Однажды ваш extractBOWDescriptor()
загружает данные в labels
Я предполагаю, что labels
имеет размер (trainingData.rows, trainingData.cols)
, Если нет, это может быть проблемой.
Других решений пока нет …