Skip to content

Commit

Permalink
Rafael Munoz Salinas mar sep 6 07:45:49 CEST 2016
Browse files Browse the repository at this point in the history
  • Loading branch information
rmsalinas committed Sep 6, 2016
1 parent 7a5d97a commit b498a23
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ DBoW3

DBoW3 is an improved version of the DBow2 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. DBoW3 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 DBow2 library are:

* DBoW3 only requires OpenCV. DBoW2 dependency of DLIB is been removed.
* DBoW3 is able to use both binary and floating point descriptors out of the box. No need to reimplement any class for any descriptor.
* DBoW3 compiles both in linux and windows.
* Some pieces of code have been rewritten to optimize speed. The interface of DBoW3 has been simplified.
Expand Down
5 changes: 3 additions & 2 deletions utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src )
LINK_LIBRARIES(${PROJECT_NAME})
IF(OPENCV_VERSION_3)
ADD_EXECUTABLE(demo_general demo_general.cpp)
ADD_EXECUTABLE(create_voc create_voc.cpp)
INSTALL(TARGETS demo_general create_voc RUNTIME DESTINATION bin)
ADD_EXECUTABLE(create_voc_step0 create_voc_step0.cpp)
ADD_EXECUTABLE(create_voc_step1 create_voc_step1.cpp)
INSTALL(TARGETS demo_general create_voc_step0 create_voc_step1 RUNTIME DESTINATION bin)
ENDIF()
3 changes: 0 additions & 3 deletions utils/create_voc.cpp

This file was deleted.

131 changes: 131 additions & 0 deletions utils/create_voc_step0.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* Date: 2016
* Author: Rafael Muñoz Salinas
* Description: demo application of DBoW3
* License: see the LICENSE.txt file
*/

#include <iostream>
#include <vector>

// DBoW3
#include "DBoW3.h"

// OpenCV
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#ifdef USE_CONTRIB
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <opencv2/xfeatures2d.hpp>
#endif
#include "DescManip.h"

using namespace DBoW3;
using namespace std;


//command line parser
class CmdLineParser{int argc; char **argv; public: CmdLineParser(int _argc,char **_argv):argc(_argc),argv(_argv){} bool operator[] ( string param ) {int idx=-1; for ( int i=0; i<argc && idx==-1; i++ ) if ( string ( argv[i] ) ==param ) idx=i; return ( idx!=-1 ) ; } string operator()(string param,string defvalue="-1"){int idx=-1; for ( int i=0; i<argc && idx==-1; i++ ) if ( string ( argv[i] ) ==param ) idx=i; if ( idx==-1 ) return defvalue; else return ( argv[ idx+1] ); }};


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

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

void wait()
{
cout << endl << "Press enter to continue" << endl;
getchar();
}


vector<string> readImagePaths(int argc,char **argv,int start){
vector<string> paths;
for(int i=start;i<argc;i++) paths.push_back(argv[i]);
return paths;
}

vector< cv::Mat > loadFeatures( std::vector<string> path_to_images,string descriptor="") throw (std::exception){
//select detector
cv::Ptr<cv::Feature2D> fdetector;
if (descriptor=="orb") fdetector=cv::ORB::create();
else if (descriptor=="brisk") fdetector=cv::BRISK::create();
#ifdef OPENCV_VERSION_3
else if (descriptor=="akaze") fdetector=cv::AKAZE::create();
#endif
#ifdef USE_CONTRIB
else if(descriptor=="surf" ) fdetector=cv::xfeatures2d::SURF::create(400, 4, 2, EXTENDED_SURF);
#endif

else throw std::runtime_error("Invalid descriptor");
assert(!descriptor.empty());
vector<cv::Mat> features;


cout << "Extracting features..." << endl;
for(int i = 0; i < path_to_images.size(); ++i)
{
vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
cout<<"reading image: "<<path_to_images[i]<<endl;
cv::Mat image = cv::imread(path_to_images[i], 0);
if(image.empty())throw std::runtime_error("Could not open image"+path_to_images[i]);
cout<<"extracting features"<<endl;
fdetector->detectAndCompute(image, cv::Mat(), keypoints, descriptors);
features.push_back(descriptors);
cout<<"done detecting features"<<endl;
}
return features;
}

// ----------------------------------------------------------------------------
void saveToFile(string filename,const vector<cv::Mat> &features){

//test it is not created
std::ifstream ifile(filename);
if (ifile.is_open()){cerr<<"ERROR::: Output File "<<filename<<" already exists!!!!!"<<endl;exit(0);}
std::ofstream ofile(filename);
if (!ofile.is_open()){cerr<<"could not open output file"<<endl;exit(0);}
uint32_t size=features.size();
ofile.write((char*)&size,sizeof(size));
for(auto &f:features){
if( !f.isContinuous()){
cerr<<"Matrices should be continuous"<<endl;exit(0);
}
uint32_t aux=f.cols; ofile.write( (char*)&aux,sizeof(aux));
aux=f.rows; ofile.write( (char*)&aux,sizeof(aux));
aux=f.type(); ofile.write( (char*)&aux,sizeof(aux));
ofile.write( (char*)f.ptr<uchar>(0),f.total()*f.elemSize());
}
}

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

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

try{
CmdLineParser cml(argc,argv);
if (cml["-h"] || argc==1){
cerr<<"Usage: descriptor_name output image0 image1 ... \n\t descriptors:brisk,surf,orb(default),akaze(only if using opencv 3)"<<endl;
return -1;
}

string descriptor=argv[1];
string output=argv[2];

auto images=readImagePaths(argc,argv,3);
vector< cv::Mat > features= loadFeatures(images,descriptor);

//save features to file
saveToFile(argv[2],features);

}catch(std::exception &ex){
cerr<<ex.what()<<endl;
}

return 0;
}
77 changes: 77 additions & 0 deletions utils/create_voc_step1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Date: 2016
* Author: Rafael Muñoz Salinas
* Description: demo application of DBoW3
* License: see the LICENSE.txt file
*/

#include <iostream>
#include <vector>

// DBoW3
#include "DBoW3.h"

// OpenCV
#include <opencv2/core/core.hpp>
using namespace DBoW3;
using namespace std;

//command line parser
class CmdLineParser{int argc; char **argv; public: CmdLineParser(int _argc,char **_argv):argc(_argc),argv(_argv){} bool operator[] ( string param ) {int idx=-1; for ( int i=0; i<argc && idx==-1; i++ ) if ( string ( argv[i] ) ==param ) idx=i; return ( idx!=-1 ) ; } string operator()(string param,string defvalue="-1"){int idx=-1; for ( int i=0; i<argc && idx==-1; i++ ) if ( string ( argv[i] ) ==param ) idx=i; if ( idx==-1 ) return defvalue; else return ( argv[ idx+1] ); }};

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

// ----------------------------------------------------------------------------
vector<cv::Mat> readFeaturesFromFile(string filename){
vector<cv::Mat> features;
//test it is not created
std::ifstream ifile(filename);
if (!ifile.is_open()){cerr<<"could not open input file"<<endl;exit(0);}
uint32_t size;
ifile.read((char*)&size,sizeof(size));
features.resize(size);
for(int i=0;i<size;i++){

uint32_t cols,rows,type;
ifile.read( (char*)&cols,sizeof(cols));
ifile.read( (char*)&rows,sizeof(rows));
ifile.read( (char*)&type,sizeof(type));
features[i].create(rows,cols,type);
ifile.read( (char*)features[i].ptr<uchar>(0),features[i].total()*features[i].elemSize());
}
return features;
}

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

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

try{
CmdLineParser cml(argc,argv);
if (cml["-h"] || argc!=3){
cerr<<"Usage: features output_voc.yml[.gz]"<<endl;
return -1;
}


auto features=readFeaturesFromFile(argv[1]);

const int k = 9;
const int L = 3;
const WeightingType weight = TF_IDF;
const ScoringType score = L1_NORM;
DBoW3::Vocabulary voc (k, L, weight, score);

cout << "Creating a small " << k << "^" << L << " vocabulary..." << endl;
voc.create(features);
cerr<<"Saving "<<argv[2]<<endl;
voc.save(argv[2]);


}catch(std::exception &ex){
cerr<<ex.what()<<endl;
}

return 0;
}
11 changes: 8 additions & 3 deletions utils/demo_general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ void testDatabase(const vector<cv::Mat > &features)

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

void saveFeatures(const vector< cv::Mat > &features){

}

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

Expand All @@ -183,14 +186,16 @@ int main(int argc,char **argv)
try{
CmdLineParser cml(argc,argv);
if (cml["-h"] || argc==1){
cerr<<"Usage: descriptor_name image0 image1 ... \n\t descriptors:brisk,surf,orb(default),akaze(only if using opencv 3)"<<endl;
cerr<<"Usage: descriptor_name action output image0 image1 ... \n\t descriptors:brisk,surf,orb(default),akaze(only if using opencv 3)"<<endl;
cerr<<"actions:\n\t0 : compute and save features\n\t1:create voc from features"<<endl;
return -1;
}

string path_to_images=cml("-i","");//read param -i if present. If not, returns emtpy string
string descriptor=argv[1];
string out_features=argv[2];
string out_voc=argv[3];

auto images=readImagePaths(argc,argv,2);
auto images=readImagePaths(argc,argv,4);
vector< cv::Mat > features= loadFeatures(images,descriptor);
testVocCreation(features);

Expand Down

0 comments on commit b498a23

Please sign in to comment.