一个具有零行和1000列的矩阵? [英] A matrix with zero rows and 1000 columns?

查看:148
本文介绍了一个具有零行和1000列的矩阵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在看一个 CvNormalBayesClassifier :: train 的例子,其中输入/输出矩阵是一个1D向量。



我看到的例子通过使用这一行创建一个0行和1000列的cv :: Mat矩阵来实现这一点:



Mat trainingData(0,1000,CV_32FC1);



在opencv文档中读取基本数据类型这是我发现Mat:


有许多不同的方法来创建Mat对象。这里有一些
流行的:

 使用create(nrows,ncols,type)方法或

类似的构造函数

Mat(nrows,ncols,type [,fill_value])构造函数。


无论如何,第一个参数是行。我看看它的方式是即使我们创建一个1000列矩阵,它将至少有1行。如何可以有0行?



如果这是一个非常基本的问题, ,这里是完整的代码。

  #include< vector& 
#include< boost / filesystem.hpp>
#include< opencv2 / opencv.hpp>

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

//训练数据的位置
#define TRAINING_DATA_DIRdata / train /
//评估数据的位置
#define EVAL_DATA_DIRdata / eval /

//有关详细信息,请参阅BoW模型的文章
Ptr< DescriptorMatcher> matcher = DescriptorMatcher :: create(FlannBased);
Ptr< DescriptorExtractor> extractor = DescriptorExtractor :: create(SURF);
Ptr< FeatureDetector> detector = FeatureDetector :: create(SURF);

//有关详细信息,请参阅BoW模型的文章
int dictionarySize = 1000;
TermCriteria tc(CV_TERMCRIT_ITER,10,0.001);
int retries = 1;
int markers = KMEANS_PP_CENTERS;

//详情请参阅BoW模型的文章
BOWKMeansTrainer bowTrainer(dictionarySize,tc,retries,flags);
//有关详细信息,请参阅BoW模型的文章
BOWImgDescriptorExtractor bowDE(extractor,matcher);

/ **
* \brief递归地遍历文件夹层次结构。从训练图像中提取特征,并将它们添加到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< 处理目录< entry.path()。string()<< endl;
extractTrainingVocabulary(entry.path());

} else {

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

cout< 处理文件<< entryPath.string()<< endl;
Mat img = imread(entryPath.string());
if(!img.empty()){
vector< KeyPoint>关键点;
detect-> detect(img,keypoints);
if(keypoints.empty()){
cerr<< 警告:找不到图片中的关键点:
<< entryPath.string()<< endl;
} else {
Mat features;
extractor-> compute(img,keypoints,features);
bowTrainer.add(features);
}
} else {
cerr<< 警告:无法读取图片:
<< entryPath.string()<< endl;
}

}
}
}
}

/ **
* \brief递归遍历文件夹层次结构。为遇到的每个图像创建一个BoW描述符。
* /
void extractBOWDescriptor(const path& basepath,Mat& descriptor,Mat& labels){
for(directory_iterator iter = directory_iterator(basepath); iter
!= directory_iterator ); iter ++){
directory_entry entry = * iter;
if(is_directory(entry.path())){
cout<< 处理目录< entry.path()。string()<< endl;
extractBOWDescriptor(entry.path(),descriptors,labels);
} else {
path entryPath = entry.path();
if(entryPath.extension()==.jpg){
cout< 处理文件<< entryPath.string()<< endl;
Mat img = imread(entryPath.string());
if(!img.empty()){
vector< KeyPoint>关键点;
detect-> detect(img,keypoints);
if(keypoints.empty()){
cerr<< 警告:找不到图片中的关键点:
<< entryPath.string()<< endl;
} else {
Mat bowDescriptor;
bowDE.compute(img,keypoints,bowDescriptor);
descriptors.push_back(bowDescriptor);
float label = atof(entryPath.filename()。c_str());
labels.push_back(label);
}
} else {
cerr<< 警告:无法读取图片:
<< entryPath.string()<< endl;
}
}
}
}
}

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

cout<<创建字典...<< 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标签(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;
结果;
classifier.predict(evalData,& results);

double errorRate =(double)countNonZero(groundTruth - results)/ evalData.rows;
;
cout<< 错误率:< errorRate< endl;

}


解决方案

感觉现在你已经发布了代码。该0行向量被初始化为具有0行,但是它被递增地创建。



0行矩阵被传递给 extractBOWDescriptor(),它本身计算几个描述符并使用 cv :: Mat.push_back()添加行到矩阵。



它从0行开始,因为开始时我们没有填充矩阵的描述符。


I was looking at an example of the CvNormalBayesClassifier::train in which the input/output matrix is to be a 1D vector.

The example I was looking at achieved this by creating a cv::Mat matrix with 0 rows and 1000 columns using this line:

Mat trainingData(0, 1000, CV_32FC1);

Reading the basic data types in opencv documentation this is what I found for Mat:

There are many different ways to create Mat object. Here are the some popular ones:

using create(nrows, ncols, type) method or

    the similar constructor

Mat(nrows, ncols, type[, fill_value]) constructor.

In any way the first parameter is the rows. The way I look at it is even if we do create a 1000 column matrix it will atleast have 1 row. How can it have 0 rows?

Sorry if this is a very basic question.

update: upon request, here is the complete code.

    #include <vector>
#include <boost/filesystem.hpp>
#include <opencv2/opencv.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 "data/eval/"

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

//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.filename().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(); //descriptors from training images
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;

}

解决方案

It makes sense now that you've posted the code. This 0-row vector is initialized to have 0 rows, but it is created incrementally.

The 0-row matrix gets passed to extractBOWDescriptor(), which itself computes several descriptors and uses cv::Mat.push_back() to add rows to the matrix.

It begins with 0 rows because at the start we have no descriptors to populate the matrix.

这篇关于一个具有零行和1000列的矩阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆