Skip to content

Commit

Permalink
Surf replaced by ORB
Browse files Browse the repository at this point in the history
  • Loading branch information
dorian3d committed May 1, 2016
1 parent 405f931 commit 2bbc1a0
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 53 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ DBoW2
DBoW2 is an improved version of the DBow library, an open source C++ library for indexing and converting images into a bag-of-word representation. It implements a hierarchical tree for approximating nearest neighbours in the image feature space and creating a visual vocabulary. DBoW2 also implements an image database with inverted and direct files to index images and enabling quick queries and feature comparisons. The main differences with the previous DBow library are:

* DBoW2 classes are templated, so it can work with any type of descriptor.
* DBoW2 is shipped with classes to directly work with SURF64 or BRIEF descriptors.
* DBoW2 is shipped with classes to directly work with ORB or BRIEF descriptors.
* DBoW2 adds a direct file to the image database to do fast feature comparison. This is used by DLoopDetector.
* DBoW2 does not use a binary format any longer. On the other hand, it uses the OpenCV storage system to save vocabularies and databases. This means that these files can be stored as plain text in YAML format, making compatibility easier, or compressed in gunzip format (.gz) to reduce disk usage.
* Some pieces of code have been rewritten to optimize speed. The interface of DBoW2 has been simplified.
Expand Down Expand Up @@ -75,10 +75,10 @@ DBoW2 has two main classes: `TemplatedVocabulary` and `TemplatedDatabase`. These

Two classes must be provided: `TDescriptor` is the data type of a single descriptor vector, and `F`, a class with the functions to manipulate descriptors, derived from `FClass`.

For example, to work with SURF descriptors, `TDescriptor` is defined as `std::vector<float>`, where each vector contains 64 or 128 float values. When features are extracted from an image, a `std::vector<TDescriptor>` must be obtained. In the case of BRIEF, `TDescriptor` is defined as `boost::dynamic_bitset<>`.
For example, to work with ORB descriptors, `TDescriptor` is defined as `cv::Mat` (of type `CV_8UC1`), which is a single row that contains 32 8-bit values. When features are extracted from an image, a `std::vector<TDescriptor>` must be obtained. In the case of BRIEF, `TDescriptor` is defined as `boost::dynamic_bitset<>`.

The `F` parameter is the name of a class that implements the functions defined in `FClass`. These functions get `TDescriptor` data and compute some result. Classes to deal with SURF and BRIEF descriptors are already included in DBoW2. (`FSurf64`, `FBrief`).
The `F` parameter is the name of a class that implements the functions defined in `FClass`. These functions get `TDescriptor` data and compute some result. Classes to deal with ORB and BRIEF descriptors are already included in DBoW2. (`FORB`, `FBrief`).

### Predefined Vocabularies and Databases

To make it easier to use, DBoW2 defines two kinds of vocabularies and databases: `Surf64Vocabulary`, `Surf64Database`, `BriefVocabulary`, `BriefDatabase`. Please, check the demo application to see how they are created and used.
To make it easier to use, DBoW2 defines two kinds of vocabularies and databases: `OrbVocabulary`, `OrbDatabase`, `BriefVocabulary`, `BriefDatabase`. Please, check the demo application to see how they are created and used.
55 changes: 24 additions & 31 deletions demo/demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
#include <vector>

// DBoW2
#include "DBoW2.h" // defines Surf64Vocabulary and Surf64Database
#include "DBoW2.h" // defines OrbVocabulary and OrbDatabase

#include <DUtils/DUtils.h>
#include <DVision/DVision.h>

// OpenCV
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <opencv2/features2d.hpp>


using namespace DBoW2;
Expand All @@ -27,21 +27,17 @@ 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);
void loadFeatures(vector<vector<cv::Mat > > &features);
void changeStructure(const cv::Mat &plain, vector<cv::Mat> &out);
void testVocCreation(const vector<vector<cv::Mat > > &features);
void testDatabase(const vector<vector<cv::Mat > > &features);


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// number of training images
const int NIMAGES = 4;

// extended surf gives 128-dimensional vectors
const bool EXTENDED_SURF = false;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void wait()
Expand All @@ -54,7 +50,7 @@ void wait()

int main()
{
vector<vector<vector<float> > > features;
vector<vector<cv::Mat > > features;
loadFeatures(features);

testVocCreation(features);
Expand All @@ -68,14 +64,14 @@ int main()

// ----------------------------------------------------------------------------

void loadFeatures(vector<vector<vector<float> > > &features)
void loadFeatures(vector<vector<cv::Mat > > &features)
{
features.clear();
features.reserve(NIMAGES);

cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create(400, 4, 2, EXTENDED_SURF);
cv::Ptr<cv::ORB> orb = cv::ORB::create();

cout << "Extracting SURF features..." << endl;
cout << "Extracting ORB features..." << endl;
for(int i = 0; i < NIMAGES; ++i)
{
stringstream ss;
Expand All @@ -84,41 +80,38 @@ void loadFeatures(vector<vector<vector<float> > > &features)
cv::Mat image = cv::imread(ss.str(), 0);
cv::Mat mask;
vector<cv::KeyPoint> keypoints;
vector<float> descriptors;
cv::Mat descriptors;

surf->detectAndCompute(image, mask, keypoints, descriptors);
orb->detectAndCompute(image, mask, keypoints, descriptors);

features.push_back(vector<vector<float> >());
changeStructure(descriptors, features.back(), surf->descriptorSize());
features.push_back(vector<cv::Mat >());
changeStructure(descriptors, features.back());
}
}

// ----------------------------------------------------------------------------

void changeStructure(const vector<float> &plain, vector<vector<float> > &out,
int L)
void changeStructure(const cv::Mat &plain, vector<cv::Mat> &out)
{
out.resize(plain.size() / L);
out.resize(plain.rows);

unsigned int j = 0;
for(unsigned int i = 0; i < plain.size(); i += L, ++j)
for(int i = 0; i < plain.rows; ++i)
{
out[j].resize(L);
std::copy(plain.begin() + i, plain.begin() + i + L, out[j].begin());
out[i] = plain.row(i);
}
}

// ----------------------------------------------------------------------------

void testVocCreation(const vector<vector<vector<float> > > &features)
void testVocCreation(const vector<vector<cv::Mat > > &features)
{
// branching factor and depth levels
const int k = 9;
const int L = 3;
const WeightingType weight = TF_IDF;
const ScoringType score = L1_NORM;

Surf64Vocabulary voc(k, L, weight, score);
OrbVocabulary voc(k, L, weight, score);

cout << "Creating a small " << k << "^" << L << " vocabulary..." << endl;
voc.create(features);
Expand Down Expand Up @@ -150,14 +143,14 @@ void testVocCreation(const vector<vector<vector<float> > > &features)

// ----------------------------------------------------------------------------

void testDatabase(const vector<vector<vector<float> > > &features)
void testDatabase(const vector<vector<cv::Mat > > &features)
{
cout << "Creating a small database..." << endl;

// load the vocabulary from disk
Surf64Vocabulary voc("small_voc.yml.gz");
OrbVocabulary voc("small_voc.yml.gz");

Surf64Database db(voc, false, 0); // false = do not use direct index
OrbDatabase 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.
Expand Down Expand Up @@ -197,7 +190,7 @@ void testDatabase(const vector<vector<vector<float> > > &features)

// once saved, we can load it again
cout << "Retrieving database once again..." << endl;
Surf64Database db2("small_db.yml.gz");
OrbDatabase db2("small_db.yml.gz");
cout << "... done! This is: " << endl << db2 << endl;
}

Expand Down
24 changes: 6 additions & 18 deletions include/DBoW2/DBoW2.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@
}
</pre>
*
* \section license License
* This file is licensed under a Creative Commons
* Attribution-NonCommercial-ShareAlike 3.0 license.
* This file can be freely used and users can use, download and edit this file
* provided that credit is attributed to the original author. No users are
* permitted to use this file for commercial purposes unless explicit permission
* is given by the original author. Derivative works must be licensed using the
* same or similar license.
* Check http://creativecommons.org/licenses/by-nc-sa/3.0/ to obtain further
* details.
*
*/

#ifndef __D_T_DBOW2__
Expand All @@ -65,17 +54,16 @@ namespace DBoW2
#include "BowVector.h"
#include "FeatureVector.h"
#include "QueryResults.h"
#include "FSurf64.h"
#include "FBrief.h"
#include "FORB.h"

/// SURF64 Vocabulary
typedef DBoW2::TemplatedVocabulary<DBoW2::FSurf64::TDescriptor, DBoW2::FSurf64>
Surf64Vocabulary;
/// ORB Vocabulary
typedef DBoW2::TemplatedVocabulary<DBoW2::FORB::TDescriptor, DBoW2::FORB>
OrbVocabulary;

/// SURF64 Database
typedef DBoW2::TemplatedDatabase<DBoW2::FSurf64::TDescriptor, DBoW2::FSurf64>
Surf64Database;
/// FORB Database
typedef DBoW2::TemplatedDatabase<DBoW2::FORB::TDescriptor, DBoW2::FORB>
OrbDatabase;

/// BRIEF Vocabulary
typedef DBoW2::TemplatedVocabulary<DBoW2::FBrief::TDescriptor, DBoW2::FBrief>
Expand Down

0 comments on commit 2bbc1a0

Please sign in to comment.