包含零行和 1000 列的矩阵
A matrix with zero rows and 1000 columns?
我正在查看输入/输出矩阵为一维向量的CvNormalBayesClassifier::train
示例。
我正在查看的示例通过使用以下行创建一个包含 0 行和 1000 列的 cv::Mat 矩阵来实现这一点:
Mat trainingData(0, 1000, CV_32FC1);
阅读opencv文档中的基本数据类型,这是我为Mat找到的:
有许多不同的方法可以创建 Mat 对象。以下是一些 受欢迎的:
using create(nrows, ncols, type) method or the similar constructor Mat(nrows, ncols, type[, fill_value]) constructor.
无论如何,第一个参数是行。我看待它的方式是,即使我们确实创建了一个 1000 列矩阵,它也至少有 1 行。它怎么会有 0 行?
对不起,如果这是一个非常基本的问题。
更新:根据要求,这是完整的代码。
#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;
}
现在您已经发布了代码,这是有意义的。 此 0 行向量初始化为具有 0 行,但它是增量创建的。
0行矩阵被传递给extractBOWDescriptor()
,它本身计算几个描述符并使用cv::Mat.push_back()
将行添加到矩阵中。
它以 0 行开头,因为在开始时我们没有描述符来填充矩阵。
相关文章:
- 当回溯以零开始时,如何调试崩溃
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 编译包含字符串的代码时遇到问题
- 如果第一个元素包含任何零,则我的程序以不希望的方式运行
- 通过零参数构造函数创建的 glm::mat4 应该包含哪些值?
- 为什么 Wild 指针包含零地址而不是 garabge 地址?
- 如何正确地将规则 5(或零?)应用于包含带有字符串的自定义对象向量的类
- 在提升精神 x3 解析结果中包含前导零
- 如何在将秒转换为分钟且余数小于 10 秒时包含前导零
- 包含零行和 1000 列的矩阵
- 包含前导零的输入
- 为什么双空大括号 { { } } 创建一个<double>包含一个元素而不是零元素的 std::initializer_list?
- 当UDT包含大小为零的数组时,无法生成复制ctor或复制赋值运算符
- 如何输入包含少于1000个单词的带有空格和标点符号的文本
- 如何将包含其他结构和数组的整个结构对象数组清零
- C++:是否有一个包含各种函数的traits类来操作以零结尾的char*和wchar_t*字符串
- 如果我的向量不包含构造,如何将其设置为零
- 包含多个零的矩阵的数据结构
- a和b之间至少包含一个零的总数