视觉slam闭环检测之-DBoW2 -视觉词袋构建
Posted jason来自星星
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了视觉slam闭环检测之-DBoW2 -视觉词袋构建相关的知识,希望对你有一定的参考价值。
需要准备的知识点:http://www.cnblogs.com/zjiaxing/p/5616653.html
http://www.cnblogs.com/zjiaxing/p/5616664.html
http://www.cnblogs.com/zjiaxing/p/5616670.html
http://www.cnblogs.com/zjiaxing/p/5616679.html
#include <iostream> #include <vector> // DBoW2 #include "DBoW2.h" // defines Surf64Vocabulary and Surf64Database #include <DUtils/DUtils.h> #include <DVision/DVision.h> // OpenCV #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/xfeatures2d/nonfree.hpp> using namespace DBoW2; using namespace DUtils; using namespace std; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void loadFeatures(vector<vector<vector<float> > > &features); void changeStructure(const vector<float> &plain, vector<vector<float> > &out, int L); void testVocCreation(const vector<vector<vector<float> > > &features); void testDatabase(const vector<vector<vector<float> > > &features); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // number of training images const int NIMAGES = 4; // extended surf gives 128-dimensional vectors const bool EXTENDED_SURF = false; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void wait() { cout << endl << "Press enter to continue" << endl; getchar(); } // ---------------------------------------------------------------------------- int main() { vector<vector<vector<float> > > features; loadFeatures(features); testVocCreation(features); wait(); testDatabase(features); return 0; } // ---------------------------------------------------------------------------- void loadFeatures(vector<vector<vector<float> > > &features) { features.clear(); features.reserve(NIMAGES); cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create(400, 4, 2, EXTENDED_SURF); cout << "Extracting SURF features..." << endl; for(int i = 0; i < NIMAGES; ++i) { stringstream ss; ss << "images/image" << i << ".png"; cv::Mat image = cv::imread(ss.str(), 0); cv::Mat mask; vector<cv::KeyPoint> keypoints; vector<float> descriptors; surf->detectAndCompute(image, mask, keypoints, descriptors); features.push_back(vector<vector<float> >()); changeStructure(descriptors, features.back(), surf->descriptorSize()); } } // ---------------------------------------------------------------------------- void changeStructure(const vector<float> &plain, vector<vector<float> > &out, int L) { out.resize(plain.size() / L); unsigned int j = 0; for(unsigned int i = 0; i < plain.size(); i += L, ++j) { out[j].resize(L); std::copy(plain.begin() + i, plain.begin() + i + L, out[j].begin()); } } // ---------------------------------------------------------------------------- void testVocCreation(const vector<vector<vector<float> > > &features) { // Creates a vocabulary from the training features, setting the branching factor and the depth levels of the tree and the weighting and scoring schemes * Creates k clusters from the given descriptors with some seeding algorithm. const int k = 9; const int L = 3; const WeightingType weight = TF_IDF; const ScoringType score = L1_NORM; Surf64Vocabulary voc(k, L, weight, score); cout << "Creating a small " << k << "^" << L << " vocabulary..." << endl; voc.create(features); cout << "... done!" << endl; cout << "Vocabulary information: " << endl << voc << endl << endl; // lets do something with this vocabulary cout << "Matching images against themselves (0 low, 1 high): " << endl; BowVector v1, v2; for(int i = 0; i < NIMAGES; i++) { //Transforms a set of descriptores into a bow vector voc.transform(features[i], v1); for(int j = 0; j < NIMAGES; j++) { voc.transform(features[j], v2); double score = voc.score(v1, v2); cout << "Image " << i << " vs Image " << j << ": " << score << endl; } } // save the vocabulary to disk cout << endl << "Saving vocabulary..." << endl; voc.save("small_voc.yml.gz"); cout << "Done" << endl; } // ---------------------------------------------------------------------------- void testDatabase(const vector<vector<vector<float> > > &features) { cout << "Creating a small database..." << endl; // load the vocabulary from disk Surf64Vocabulary voc("small_voc.yml.gz"); Surf64Database db(voc, false, 0); // false = do not use direct index // (so ignore the last param) // The direct index is useful if we want to retrieve the features that // belong to some vocabulary node. // db creates a copy of the vocabulary, we may get rid of "voc" now // add images to the database for(int i = 0; i < NIMAGES; i++) { db.add(features[i]); } cout << "... done!" << endl; cout << "Database information: " << endl << db << endl; // and query the database cout << "Querying the database: " << endl; QueryResults ret; for(int i = 0; i < NIMAGES; i++) { db.query(features[i], ret, 4); // ret[0] is always the same image in this case, because we added it to the // database. ret[1] is the second best match. cout << "Searching for Image " << i << ". " << ret << endl; } cout << endl; // we can save the database. The created file includes the vocabulary // and the entries added cout << "Saving database..." << endl; db.save("small_db.yml.gz"); cout << "... done!" << endl; // once saved, we can load it again cout << "Retrieving database once again..." << endl; Surf64Database db2("small_db.yml.gz"); cout << "... done! This is: " << endl << db2 << endl; }
以上是关于视觉slam闭环检测之-DBoW2 -视觉词袋构建的主要内容,如果未能解决你的问题,请参考以下文章