zoukankan      html  css  js  c++  java
  • 视觉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;
    }
  • 相关阅读:
    Android-MediaProvider数据库模式
    java String.getBytes()编码问题——String.getBytes(charset)
    设置Eclipse中的tab键为4个空格的完整方法
    linux下的zip命令
    关于facebook infer 静态代码审查工具
    关于软件测试人员能力模型的建立(from知乎)
    [ 转] 漫谈iOS Crash收集框架
    iOS开发如何提高(from 唐巧的博客)
    c++ web服务器
    小米开源监控系统的说明文档
  • 原文地址:https://www.cnblogs.com/zjiaxing/p/5616701.html
Copyright © 2011-2022 走看看