2015-07-09 1 views
2

Я пытаюсь создать классификатор для мешка слов. Я нашел вопрос на этом сайте (here), который помог мне привести код ниже, но я застрял в classifier->train(trainingData,ml::ROW_SAMPLE, labels);. По сути, программа работает нормально, но когда она добирается до этой строки, программа вылетает из строя. По-видимому, линия выполняет деление на ноль и, следовательно, сбой. Я просмотрел код, и я не могу найти ошибку. Это может быть ошибка перевода из openCV 2 -> 3, не совсем уверенная. Любая помощь будет принята с благодарностью!OpenCV 3.0 Нормальная ошибка классификатора Bayes

#include <opencv2/core/core.hpp> 
#include "opencv2/highgui/highgui.hpp" 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/features2d/features2d.hpp> 
#include <opencv2/xfeatures2d.hpp> 
#include <opencv2/ml.hpp> 

#include <iostream> 
#include <stdio.h> 
#include <dirent.h> 
#include <string.h> 




using namespace std; 
using namespace cv; 

#define TRAINING_DATA_DIR "testImages/" 
#define EVAL_DATA_DIR "evalImages/" 


int dictSize = 1000; 
TermCriteria tc(CV_TERMCRIT_ITER, 10, 0.001); 
int retries = 1; 
int flags = KMEANS_PP_CENTERS; 

Ptr<FeatureDetector> detector = xfeatures2d::SURF::create(); 
Ptr<DescriptorExtractor> extractor = xfeatures2d::SURF::create(); 
Ptr<DescriptorMatcher> matcher = FlannBasedMatcher::create("FlannBased"); 



BOWKMeansTrainer bowTrainer(dictSize, tc, retries, flags); 
BOWImgDescriptorExtractor bowDE(extractor, matcher); 

void extractTrainingVocabulary(string path){ 
    struct dirent *de = NULL; 
    DIR *d = NULL; 
    d = opendir(path.c_str()); 

    if(d == NULL) 
    { 
     cerr << "Couldn't open directory" << endl; 

    } else { 
     // Add all the names of the files to be processed to a vector 
     vector<string> files; 
     while ((de = readdir(d))) { 
      string nameOfFile(de->d_name); 
      if ((strcmp(de->d_name,".") != 0) && (strcmp(de->d_name,"..") != 0) && (strcmp(de->d_name,".DS_Store") != 0)) { 
       files.push_back(nameOfFile); 
      } 
     } 

     // Loop through all elements 
     for (int f = 0; f < files.size(); f++){ 
      string fullPath = "./"; 
      fullPath += TRAINING_DATA_DIR; 
      fullPath += files[f]; 

      cout << "[" << f+1 << "/" << files.size() << "]\tProcessing image: " << fullPath << endl; 

      Mat input = imread(fullPath); 
      if (!input.empty()){ 
       // Find all keypoints 
       vector<KeyPoint> keypoints; 
       detector->detect(input, keypoints); 
       if (keypoints.empty()){ 
        cerr << "Warning! could not find any keypoints in image " << fullPath << endl; 
       } else { 
        // Extract the features 
        Mat features; 
        extractor->compute(input, keypoints, features); 
        // Add them to the trainer 
        bowTrainer.add(features); 
       } 
      } else { 
       cerr << "Could not read image " << fullPath << endl; 
      } 
     } 

    } 
} 

void extractBOWDescriptor(string path, Mat& descriptors, Mat& labels){ 
    struct dirent *de = NULL; 
    DIR *d = NULL; 
    d = opendir(path.c_str()); 

    if(d == NULL) 
    { 
     cerr << "Couldn't open directory" << endl; 

    } else { 
     // Add all the names of the files to be processed to a vector 
     vector<string> files; 
     while ((de = readdir(d))) { 
      string nameOfFile(de->d_name); 
      if ((strcmp(de->d_name,".") != 0) && (strcmp(de->d_name,"..") != 0) && (strcmp(de->d_name,".DS_Store") != 0)) { 
       files.push_back(nameOfFile); 
      } 
     } 

     // Loop through all elements 
     for (int f = 0; f < files.size(); f++){ 
      string fullPath = "./"; 
      fullPath += EVAL_DATA_DIR; 
      fullPath += files[f]; 

      cout << "[" << f+1 << "/" << files.size() << "]\tProcessing image: " << fullPath << endl; 

      Mat input = imread(fullPath); 
      if (!input.empty()){ 
       // Find all keypoints 
       vector<KeyPoint> keypoints; 
       detector->detect(input, keypoints); 
       if (keypoints.empty()){ 
        cerr << "Warning! could not find any keypoints in image " << fullPath << endl; 
       } else { 
        Mat bowDescriptor; 
        bowDE.compute(input, keypoints, bowDescriptor); 
        descriptors.push_back(bowDescriptor); 
        // Current file 
        string fileName = files[f]; 
        // Strip extension 
        fileName.erase (fileName.end()-4, fileName.end()); 

        float label = atof(fileName.c_str()); 
        cout << "Filename: " << fileName << endl; 

        labels.push_back(label); 
       } 
      } else { 
       cerr << "Could not read image " << fullPath << endl; 
      } 
     } 

    } 
} 




int main(int argc, char ** argv) { 
    // ============================ LEARN ============================ 
    cout << "Creating dict" << endl; 
    extractTrainingVocabulary(TRAINING_DATA_DIR); 




    vector<Mat> descriptors = bowTrainer.getDescriptors(); 

    int count=0; 
    for(vector<Mat>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++){ 
     count+=iter->rows; 
    } 

    cout << "Clustering " << count << " features. This might take a while..." << endl; 

    Mat dictionary = bowTrainer.cluster(); 

    cout << "Writing to dict..."; 
    FileStorage fs("dict.yml",FileStorage::WRITE); 
    fs << "vocabulary" << dictionary; 
    fs.release(); 
    cout << "Done!" << endl; 

    // =========================== EXTRACT =========================== 
    // This will have to be loaded if we run it in two different instances 
    bowDE.setVocabulary(dictionary); 

    cout << "Processing training data..." << endl; 
    Mat trainingData(0, dictSize, CV_32FC1); 
    Mat labels(0,1,CV_32FC1); 

    extractBOWDescriptor(EVAL_DATA_DIR, trainingData, labels); 



    Ptr<ml::NormalBayesClassifier> classifier = ml::NormalBayesClassifier::create(); 

    if (trainingData.data == NULL || labels.data == NULL){ 
     cerr << "Mats are NULL!!" << endl; 
    } else { 
     classifier->train(trainingData,ml::ROW_SAMPLE, labels); 
    } 
//#warning Not yet tested 
// cout << "Processing evaluation data" << endl; 
// Mat evalData(0,dictSize,CV_32FC1); 
// Mat groundTruth(0,1,CV_32FC1); 
// extractBOWDescriptor(EVAL_DATA_DIR, evalData, groundTruth); 

    return 0; 
} 

EDIT

В соответствии с поручением здесь ошибка.

  • через терминал: Floating point exception: 8
  • XCode 6: Thread 1:EXC_ARITHMETIC (code=EXC_i386_DIV, subcode=0x0)
+0

Можете ли вы добавить исключение? –

+0

в исходном вопросе – ruben1691

+0

Я столкнулся с той же проблемой с opencv 3.0.0 SVM-классификатором. Вы нашли решение? –

ответ

0

Пожалуйста, попробуйте изменить

labels.push_back(label); 

в

labels.push_back((int)label); 

Я имел такую ​​же пр oblem с обучением SVM и понял, что метки классов должны быть ints.

Cheers!

0

Просто поделиться тем, как я решил такую ​​же проблему на моем OS X проекта.

По-видимому, это действительно кажется, что матрица, содержащая ярлыки проблема в моем проекте тоже. По какой-то странной причине создание матрицы каким-либо другим способом или приведение к int значений, введенных в матрицу, не сработало для меня.

Проблема была решена только следующий код так, как OpenCV 3.0.0 SVM Учебное пособие по инициализирован ее матрицу меток. OpenCV SVM tutorial

Который идет:

int labels[4] = {1, -1, -1, -1}; 
Mat labelsMat(4, 1, CV_32SC1, labels); 

После того как я изменил мою матрицу меток быть инициализирован как таковой из массива целых меток, ошибка ушла.