一袋字opencv代码不工作。评估数据时出错

时间:2013-05-05 08:22:34

标签: c++ opencv

我在这段代码中遇到一个错误...我以前在使用opencv Ptr类时遇到问题然后我将其更改为普通的本机c ++指针。然后问题在于标签,其中entryPath.filename()。c_str()变得无效......因此我使用内置的强制转换将其更改为字符串。现在问题出现在evalData()中。请帮帮我

#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时我遇到错误..请帮助

1 个答案:

答案 0 :(得分:0)

opencv::Ptr是一个refcounter智能指针类。对于这样的智能指针来说,这是一个不好的例子,因为它有一个非显式构造函数,它接受一个原始指针,但声称对这种转换拥有所有权。我想这就是你磕磕绊绊的地方:

  1. 使用新
  2. 创建对象
  3. 将指针传递给采用cv::Ptr
  4. 的函数
  5. 创建cv::Ptr实例,获取对象的所有权
  6. cv::Ptr实例被销毁,用它破坏已分配的对象
  7. 你正在使用原始指针,它的值仍未改变,并且看到了神秘的失败
相关问题