2013-05-05 3 views
0

Я столкнулся с ошибкой в ​​этом коде, который у меня есть ... Раньше я столкнулся с проблемой использования opencv класса Ptr, после чего я сменил его на обычный собственный указатель на C++. Тогда проблема заключалась в маркировке, в которой entryPath.filename(). C_str() становится недействительным ... поэтому я изменил его на строку, используя встроенный состав. Теперь проблема возникает в evalData(). Пожалуйста, помогите мнеСумка слов opencv Код не работает. Ошибка при оценке данных

#include "stdafx.h" 
#include <vector> 
#include <boost/filesystem.hpp> 
#include <opencv2/opencv.hpp> 
#include <opencv2/nonfree/features2d.hpp> 

using namespace std; 
using namespace boost::filesystem; 
using namespace cv; 

//location of the training data 
#define TRAINING_DATA_DIR "data\\train\\" 
//location of the evaluation data 
#define EVAL_DATA_DIR "dataeval\\" 

////See article on BoW model for details 
//Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased"); 
//Ptr<DescriptorExtractor> extractor = DescriptorExtractor::create("SURF"); 
//Ptr<FeatureDetector> detector = FeatureDetector::create("SURF"); 

cv::DescriptorExtractor *extractor = new cv::SurfDescriptorExtractor(); 
cv::FeatureDetector *detector = new cv::SurfFeatureDetector(1000); 
cv::DescriptorMatcher *matcher = new cv::FlannBasedMatcher; 


//See article on BoW model for details 
int dictionarySize = 1000; 
TermCriteria tc(CV_TERMCRIT_ITER, 10, 0.001); 
int retries = 1; 
int flags = KMEANS_PP_CENTERS; 

//See article on BoW model for details 
BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags); 
//See article on BoW model for details 
BOWImgDescriptorExtractor bowDE(extractor, matcher); 

/** 
* \brief Recursively traverses a folder hierarchy. Extracts features from the training images and adds them to the bowTrainer. 
*/ 
void extractTrainingVocabulary(const path& basepath) { 
    for (directory_iterator iter = directory_iterator(basepath); iter 
      != directory_iterator(); iter++) { 
     directory_entry entry = *iter; 

     if (is_directory(entry.path())) { 

      cout << "Processing directory " << entry.path().string() << endl; 
      extractTrainingVocabulary(entry.path()); 

     } else { 

      path entryPath = entry.path(); 
      if (entryPath.extension() == ".jpg") { 

       cout << "Processing file " << entryPath.string() << endl; 
       Mat img = imread(entryPath.string()); 
       if (!img.empty()) { 
        vector<KeyPoint> keypoints; 
        detector->detect(img, keypoints); 
        if (keypoints.empty()) { 
         cerr << "Warning: Could not find key points in image: " 
           << entryPath.string() << endl; 
        } else { 
         Mat features; 
         extractor->compute(img, keypoints, features); 
         bowTrainer.add(features); 
        } 
       } else { 
        cerr << "Warning: Could not read image: " 
          << entryPath.string() << endl; 
       } 

      } 
     } 
    } 
} 

/** 
* \brief Recursively traverses a folder hierarchy. Creates a BoW descriptor for each image encountered. 
*/ 
void extractBOWDescriptor(const path& basepath, Mat& descriptors, Mat& labels) { 
    for (directory_iterator iter = directory_iterator(basepath); iter 
      != directory_iterator(); iter++) { 
     directory_entry entry = *iter; 
     if (is_directory(entry.path())) { 
      cout << "Processing directory " << entry.path().string() << endl; 
      extractBOWDescriptor(entry.path(), descriptors, labels); 
     } else { 
      path entryPath = entry.path(); 
      if (entryPath.extension() == ".jpg") { 
       cout << "Processing file " << entryPath.string() << endl; 
       Mat img = imread(entryPath.string()); 
       if (!img.empty()) { 
        vector<KeyPoint> keypoints; 
        detector->detect(img, keypoints); 
        if (keypoints.empty()) { 
         cerr << "Warning: Could not find key points in image: " 
           << entryPath.string() << endl; 
        } else { 
         Mat bowDescriptor; 
         bowDE.compute(img, keypoints, bowDescriptor); 
         descriptors.push_back(bowDescriptor); 
         float label=atof(entryPath.string().c_str()); 
         labels.push_back(label); 
        } 
       } else { 
        cerr << "Warning: Could not read image: " 
          << entryPath.string() << endl; 
       } 
      } 
     } 
    } 
} 


int main(int argc, char ** argv) { 

    cout<<"Creating dictionary..."<<endl; 
    extractTrainingVocabulary(path(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"<<endl; 
    Mat dictionary = bowTrainer.cluster(); 
    bowDE.setVocabulary(dictionary); 
    cout<<"Processing training data..."<<endl; 
    Mat trainingData(0, dictionarySize, CV_32FC1); 
    Mat labels(0, 1, CV_32FC1); 
    extractBOWDescriptor(path(TRAINING_DATA_DIR), trainingData, labels); 

    NormalBayesClassifier classifier; 
    cout<<"Training classifier..."<<endl; 

    classifier.train(trainingData, labels); 

    cout<<"Processing evaluation data..."<<endl; 
    Mat evalData(0, dictionarySize, CV_32FC1); 
    Mat groundTruth(0, 1, CV_32FC1); 
    extractBOWDescriptor(path(EVAL_DATA_DIR), evalData, groundTruth); 

    cout<<"Evaluating classifier..."<<endl; 
    Mat results; 
    classifier.predict(evalData, &results); 

    double errorRate = (double) countNonZero(groundTruth - results)/evalData.rows; 

    cout << "Error rate: " << errorRate << endl; 

} 

сталкиваюсь ошибку, когда программа падает evalData .. Пожалуйста, помогите

+0

Какая ошибка? – Niko

+0

Исключение памяти. Ошибка возникает при обработке EvalData(). Исключение: boost :: filesystem3 :: filesystem_error в ячейке памяти 0x001cf8fc .. Ошибка не исправлена, поэтому я интерпретирую ошибку не только одну, возможно, есть еще одна ошибка, которая происходит раньше где-то в программе и распространяется, следовательно, приводит к случайным ошибкам .. –

ответ

0

opencv::Ptr является refcounter смарт-класс указателя. Это плохой пример для такого умного указателя, поскольку он имеет неявный конструктор, который использует необработанный указатель, но претендует на право собственности на такое преобразование. Я думаю, что это то, что вы спотыкаясь:

  1. вы создаете объект с использованием новых
  2. вы передаете указатель на функцию, принимая cv::Ptr
  3. в cv::Ptr экземпляр создается, принимая право собственности на объект
  4. cv::Ptr экземпляр будет уничтожен, разрушив выделенный объект с этим
  5. вы используете сырой указатель, кто есть значение по-прежнему без изменений, и увидеть странные сбои
Смежные вопросы