This commit is contained in:
PodmogilnyjIvan
2021-12-03 03:34:31 -08:00
commit ff4acf84be
542 changed files with 136810 additions and 0 deletions

40
Thirdparty/DBoW2/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,40 @@
cmake_minimum_required(VERSION 2.8)
project(DBoW2)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native")
set(HDRS_DBOW2
DBoW2/BowVector.h
DBoW2/FORB.h
DBoW2/FClass.h
DBoW2/FeatureVector.h
DBoW2/ScoringObject.h
DBoW2/TemplatedVocabulary.h)
set(SRCS_DBOW2
DBoW2/BowVector.cpp
DBoW2/FORB.cpp
DBoW2/FeatureVector.cpp
DBoW2/ScoringObject.cpp)
set(HDRS_DUTILS
DUtils/Random.h
DUtils/Timestamp.h)
set(SRCS_DUTILS
DUtils/Random.cpp
DUtils/Timestamp.cpp)
find_package(OpenCV 4.0 QUIET)
if(NOT OpenCV_FOUND)
find_package(OpenCV 3.0 QUIET)
if(NOT OpenCV_FOUND)
message(FATAL_ERROR "OpenCV > 3.0 not found.")
endif()
endif()
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
include_directories(${OpenCV_INCLUDE_DIRS})
add_library(DBoW2 SHARED ${SRCS_DBOW2} ${SRCS_DUTILS})
target_link_libraries(DBoW2 ${OpenCV_LIBS})

130
Thirdparty/DBoW2/DBoW2/BowVector.cpp vendored Normal file
View File

@@ -0,0 +1,130 @@
/**
* File: BowVector.cpp
* Date: March 2011
* Author: Dorian Galvez-Lopez
* Description: bag of words vector
* License: see the LICENSE.txt file
*
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include "BowVector.h"
namespace DBoW2 {
// --------------------------------------------------------------------------
BowVector::BowVector(void)
{
}
// --------------------------------------------------------------------------
BowVector::~BowVector(void)
{
}
// --------------------------------------------------------------------------
void BowVector::addWeight(WordId id, WordValue v)
{
BowVector::iterator vit = this->lower_bound(id);
if(vit != this->end() && !(this->key_comp()(id, vit->first)))
{
vit->second += v;
}
else
{
this->insert(vit, BowVector::value_type(id, v));
}
}
// --------------------------------------------------------------------------
void BowVector::addIfNotExist(WordId id, WordValue v)
{
BowVector::iterator vit = this->lower_bound(id);
if(vit == this->end() || (this->key_comp()(id, vit->first)))
{
this->insert(vit, BowVector::value_type(id, v));
}
}
// --------------------------------------------------------------------------
void BowVector::normalize(LNorm norm_type)
{
double norm = 0.0;
BowVector::iterator it;
if(norm_type == DBoW2::L1)
{
for(it = begin(); it != end(); ++it)
norm += fabs(it->second);
}
else
{
for(it = begin(); it != end(); ++it)
norm += it->second * it->second;
norm = sqrt(norm);
}
if(norm > 0.0)
{
for(it = begin(); it != end(); ++it)
it->second /= norm;
}
}
// --------------------------------------------------------------------------
std::ostream& operator<< (std::ostream &out, const BowVector &v)
{
BowVector::const_iterator vit;
std::vector<unsigned int>::const_iterator iit;
unsigned int i = 0;
const unsigned int N = v.size();
for(vit = v.begin(); vit != v.end(); ++vit, ++i)
{
out << "<" << vit->first << ", " << vit->second << ">";
if(i < N-1) out << ", ";
}
return out;
}
// --------------------------------------------------------------------------
void BowVector::saveM(const std::string &filename, size_t W) const
{
std::fstream f(filename.c_str(), std::ios::out);
WordId last = 0;
BowVector::const_iterator bit;
for(bit = this->begin(); bit != this->end(); ++bit)
{
for(; last < bit->first; ++last)
{
f << "0 ";
}
f << bit->second << " ";
last = bit->first + 1;
}
for(; last < (WordId)W; ++last)
f << "0 ";
f.close();
}
// --------------------------------------------------------------------------
} // namespace DBoW2

119
Thirdparty/DBoW2/DBoW2/BowVector.h vendored Normal file
View File

@@ -0,0 +1,119 @@
/**
* File: BowVector.h
* Date: March 2011
* Author: Dorian Galvez-Lopez
* Description: bag of words vector
* License: see the LICENSE.txt file
*
*/
#ifndef __D_T_BOW_VECTOR__
#define __D_T_BOW_VECTOR__
#include <iostream>
#include <map>
#include <vector>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/map.hpp>
namespace DBoW2 {
/// Id of words
typedef unsigned int WordId;
/// Value of a word
typedef double WordValue;
/// Id of nodes in the vocabulary treee
typedef unsigned int NodeId;
/// L-norms for normalization
enum LNorm
{
L1,
L2
};
/// Weighting type
enum WeightingType
{
TF_IDF,
TF,
IDF,
BINARY
};
/// Scoring type
enum ScoringType
{
L1_NORM,
L2_NORM,
CHI_SQUARE,
KL,
BHATTACHARYYA,
DOT_PRODUCT,
};
/// Vector of words to represent images
class BowVector:
public std::map<WordId, WordValue>
{
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const int version)
{
ar & boost::serialization::base_object<std::map<WordId, WordValue> >(*this);
}
public:
/**
* Constructor
*/
BowVector(void);
/**
* Destructor
*/
~BowVector(void);
/**
* Adds a value to a word value existing in the vector, or creates a new
* word with the given value
* @param id word id to look for
* @param v value to create the word with, or to add to existing word
*/
void addWeight(WordId id, WordValue v);
/**
* Adds a word with a value to the vector only if this does not exist yet
* @param id word id to look for
* @param v value to give to the word if this does not exist
*/
void addIfNotExist(WordId id, WordValue v);
/**
* L1-Normalizes the values in the vector
* @param norm_type norm used
*/
void normalize(LNorm norm_type);
/**
* Prints the content of the bow vector
* @param out stream
* @param v
*/
friend std::ostream& operator<<(std::ostream &out, const BowVector &v);
/**
* Saves the bow vector as a vector in a matlab file
* @param filename
* @param W number of words in the vocabulary
*/
void saveM(const std::string &filename, size_t W) const;
};
} // namespace DBoW2
#endif

71
Thirdparty/DBoW2/DBoW2/FClass.h vendored Normal file
View File

@@ -0,0 +1,71 @@
/**
* File: FClass.h
* Date: November 2011
* Author: Dorian Galvez-Lopez
* Description: generic FClass to instantiate templated classes
* License: see the LICENSE.txt file
*
*/
#ifndef __D_T_FCLASS__
#define __D_T_FCLASS__
#include <opencv2/core/core.hpp>
#include <vector>
#include <string>
namespace DBoW2 {
/// Generic class to encapsulate functions to manage descriptors.
/**
* This class must be inherited. Derived classes can be used as the
* parameter F when creating Templated structures
* (TemplatedVocabulary, TemplatedDatabase, ...)
*/
class FClass
{
class TDescriptor;
typedef const TDescriptor *pDescriptor;
/**
* Calculates the mean value of a set of descriptors
* @param descriptors
* @param mean mean descriptor
*/
virtual void meanValue(const std::vector<pDescriptor> &descriptors,
TDescriptor &mean) = 0;
/**
* Calculates the distance between two descriptors
* @param a
* @param b
* @return distance
*/
static double distance(const TDescriptor &a, const TDescriptor &b);
/**
* Returns a string version of the descriptor
* @param a descriptor
* @return string version
*/
static std::string toString(const TDescriptor &a);
/**
* Returns a descriptor from a string
* @param a descriptor
* @param s string version
*/
static void fromString(TDescriptor &a, const std::string &s);
/**
* Returns a mat with the descriptors in float format
* @param descriptors
* @param mat (out) NxL 32F matrix
*/
static void toMat32F(const std::vector<TDescriptor> &descriptors,
cv::Mat &mat);
};
} // namespace DBoW2
#endif

193
Thirdparty/DBoW2/DBoW2/FORB.cpp vendored Normal file
View File

@@ -0,0 +1,193 @@
/**
* File: FORB.cpp
* Date: June 2012
* Author: Dorian Galvez-Lopez
* Description: functions for ORB descriptors
* License: see the LICENSE.txt file
*
* Distance function has been modified
*
*/
#include <vector>
#include <string>
#include <sstream>
#include <stdint.h>
#include "FORB.h"
using namespace std;
namespace DBoW2 {
// --------------------------------------------------------------------------
const int FORB::L=32;
void FORB::meanValue(const std::vector<FORB::pDescriptor> &descriptors,
FORB::TDescriptor &mean)
{
if(descriptors.empty())
{
mean.release();
return;
}
else if(descriptors.size() == 1)
{
mean = descriptors[0]->clone();
}
else
{
vector<int> sum(FORB::L * 8, 0);
for(size_t i = 0; i < descriptors.size(); ++i)
{
const cv::Mat &d = *descriptors[i];
const unsigned char *p = d.ptr<unsigned char>();
for(int j = 0; j < d.cols; ++j, ++p)
{
if(*p & (1 << 7)) ++sum[ j*8 ];
if(*p & (1 << 6)) ++sum[ j*8 + 1 ];
if(*p & (1 << 5)) ++sum[ j*8 + 2 ];
if(*p & (1 << 4)) ++sum[ j*8 + 3 ];
if(*p & (1 << 3)) ++sum[ j*8 + 4 ];
if(*p & (1 << 2)) ++sum[ j*8 + 5 ];
if(*p & (1 << 1)) ++sum[ j*8 + 6 ];
if(*p & (1)) ++sum[ j*8 + 7 ];
}
}
mean = cv::Mat::zeros(1, FORB::L, CV_8U);
unsigned char *p = mean.ptr<unsigned char>();
const int N2 = (int)descriptors.size() / 2 + descriptors.size() % 2;
for(size_t i = 0; i < sum.size(); ++i)
{
if(sum[i] >= N2)
{
// set bit
*p |= 1 << (7 - (i % 8));
}
if(i % 8 == 7) ++p;
}
}
}
// --------------------------------------------------------------------------
int FORB::distance(const FORB::TDescriptor &a,
const FORB::TDescriptor &b)
{
// Bit set count operation from
// http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
const int *pa = a.ptr<int32_t>();
const int *pb = b.ptr<int32_t>();
int dist=0;
for(int i=0; i<8; i++, pa++, pb++)
{
unsigned int v = *pa ^ *pb;
v = v - ((v >> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
dist += (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
}
return dist;
}
// --------------------------------------------------------------------------
std::string FORB::toString(const FORB::TDescriptor &a)
{
stringstream ss;
const unsigned char *p = a.ptr<unsigned char>();
for(int i = 0; i < a.cols; ++i, ++p)
{
ss << (int)*p << " ";
}
return ss.str();
}
// --------------------------------------------------------------------------
void FORB::fromString(FORB::TDescriptor &a, const std::string &s)
{
a.create(1, FORB::L, CV_8U);
unsigned char *p = a.ptr<unsigned char>();
stringstream ss(s);
for(int i = 0; i < FORB::L; ++i, ++p)
{
int n;
ss >> n;
if(!ss.fail())
*p = (unsigned char)n;
}
}
// --------------------------------------------------------------------------
void FORB::toMat32F(const std::vector<TDescriptor> &descriptors,
cv::Mat &mat)
{
if(descriptors.empty())
{
mat.release();
return;
}
const size_t N = descriptors.size();
mat.create(N, FORB::L*8, CV_32F);
float *p = mat.ptr<float>();
for(size_t i = 0; i < N; ++i)
{
const int C = descriptors[i].cols;
const unsigned char *desc = descriptors[i].ptr<unsigned char>();
for(int j = 0; j < C; ++j, p += 8)
{
p[0] = (desc[j] & (1 << 7) ? 1 : 0);
p[1] = (desc[j] & (1 << 6) ? 1 : 0);
p[2] = (desc[j] & (1 << 5) ? 1 : 0);
p[3] = (desc[j] & (1 << 4) ? 1 : 0);
p[4] = (desc[j] & (1 << 3) ? 1 : 0);
p[5] = (desc[j] & (1 << 2) ? 1 : 0);
p[6] = (desc[j] & (1 << 1) ? 1 : 0);
p[7] = desc[j] & (1);
}
}
}
// --------------------------------------------------------------------------
void FORB::toMat8U(const std::vector<TDescriptor> &descriptors,
cv::Mat &mat)
{
mat.create(descriptors.size(), 32, CV_8U);
unsigned char *p = mat.ptr<unsigned char>();
for(size_t i = 0; i < descriptors.size(); ++i, p += 32)
{
const unsigned char *d = descriptors[i].ptr<unsigned char>();
std::copy(d, d+32, p);
}
}
// --------------------------------------------------------------------------
} // namespace DBoW2

79
Thirdparty/DBoW2/DBoW2/FORB.h vendored Normal file
View File

@@ -0,0 +1,79 @@
/**
* File: FORB.h
* Date: June 2012
* Author: Dorian Galvez-Lopez
* Description: functions for ORB descriptors
* License: see the LICENSE.txt file
*
*/
#ifndef __D_T_F_ORB__
#define __D_T_F_ORB__
#include <opencv2/core/core.hpp>
#include <vector>
#include <string>
#include "FClass.h"
namespace DBoW2 {
/// Functions to manipulate ORB descriptors
class FORB: protected FClass
{
public:
/// Descriptor type
typedef cv::Mat TDescriptor; // CV_8U
/// Pointer to a single descriptor
typedef const TDescriptor *pDescriptor;
/// Descriptor length (in bytes)
static const int L;
/**
* Calculates the mean value of a set of descriptors
* @param descriptors
* @param mean mean descriptor
*/
static void meanValue(const std::vector<pDescriptor> &descriptors,
TDescriptor &mean);
/**
* Calculates the distance between two descriptors
* @param a
* @param b
* @return distance
*/
static int distance(const TDescriptor &a, const TDescriptor &b);
/**
* Returns a string version of the descriptor
* @param a descriptor
* @return string version
*/
static std::string toString(const TDescriptor &a);
/**
* Returns a descriptor from a string
* @param a descriptor
* @param s string version
*/
static void fromString(TDescriptor &a, const std::string &s);
/**
* Returns a mat with the descriptors in float format
* @param descriptors
* @param mat (out) NxL 32F matrix
*/
static void toMat32F(const std::vector<TDescriptor> &descriptors,
cv::Mat &mat);
static void toMat8U(const std::vector<TDescriptor> &descriptors,
cv::Mat &mat);
};
} // namespace DBoW2
#endif

View File

@@ -0,0 +1,85 @@
/**
* File: FeatureVector.cpp
* Date: November 2011
* Author: Dorian Galvez-Lopez
* Description: feature vector
* License: see the LICENSE.txt file
*
*/
#include "FeatureVector.h"
#include <map>
#include <vector>
#include <iostream>
namespace DBoW2 {
// ---------------------------------------------------------------------------
FeatureVector::FeatureVector(void)
{
}
// ---------------------------------------------------------------------------
FeatureVector::~FeatureVector(void)
{
}
// ---------------------------------------------------------------------------
void FeatureVector::addFeature(NodeId id, unsigned int i_feature)
{
FeatureVector::iterator vit = this->lower_bound(id);
if(vit != this->end() && vit->first == id)
{
vit->second.push_back(i_feature);
}
else
{
vit = this->insert(vit, FeatureVector::value_type(id,
std::vector<unsigned int>() ));
vit->second.push_back(i_feature);
}
}
// ---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream &out,
const FeatureVector &v)
{
if(!v.empty())
{
FeatureVector::const_iterator vit = v.begin();
const std::vector<unsigned int>* f = &vit->second;
out << "<" << vit->first << ": [";
if(!f->empty()) out << (*f)[0];
for(unsigned int i = 1; i < f->size(); ++i)
{
out << ", " << (*f)[i];
}
out << "]>";
for(++vit; vit != v.end(); ++vit)
{
f = &vit->second;
out << ", <" << vit->first << ": [";
if(!f->empty()) out << (*f)[0];
for(unsigned int i = 1; i < f->size(); ++i)
{
out << ", " << (*f)[i];
}
out << "]>";
}
}
return out;
}
// ---------------------------------------------------------------------------
} // namespace DBoW2

66
Thirdparty/DBoW2/DBoW2/FeatureVector.h vendored Normal file
View File

@@ -0,0 +1,66 @@
/**
* File: FeatureVector.h
* Date: November 2011
* Author: Dorian Galvez-Lopez
* Description: feature vector
* License: see the LICENSE.txt file
*
*/
#ifndef __D_T_FEATURE_VECTOR__
#define __D_T_FEATURE_VECTOR__
#include "BowVector.h"
#include <map>
#include <vector>
#include <iostream>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/map.hpp>
namespace DBoW2 {
/// Vector of nodes with indexes of local features
class FeatureVector:
public std::map<NodeId, std::vector<unsigned int> >
{
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const int version)
{
ar & boost::serialization::base_object<std::map<NodeId, std::vector<unsigned int> > >(*this);
}
public:
/**
* Constructor
*/
FeatureVector(void);
/**
* Destructor
*/
~FeatureVector(void);
/**
* Adds a feature to an existing node, or adds a new node with an initial
* feature
* @param id node id to add or to modify
* @param i_feature index of feature to add to the given node
*/
void addFeature(NodeId id, unsigned int i_feature);
/**
* Sends a string versions of the feature vector through the stream
* @param out stream
* @param v feature vector
*/
friend std::ostream& operator<<(std::ostream &out, const FeatureVector &v);
};
} // namespace DBoW2
#endif

315
Thirdparty/DBoW2/DBoW2/ScoringObject.cpp vendored Normal file
View File

@@ -0,0 +1,315 @@
/**
* File: ScoringObject.cpp
* Date: November 2011
* Author: Dorian Galvez-Lopez
* Description: functions to compute bow scores
* License: see the LICENSE.txt file
*
*/
#include <cfloat>
#include "TemplatedVocabulary.h"
#include "BowVector.h"
using namespace DBoW2;
// If you change the type of WordValue, make sure you change also the
// epsilon value (this is needed by the KL method)
const double GeneralScoring::LOG_EPS = log(DBL_EPSILON); // FLT_EPSILON
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
double L1Scoring::score(const BowVector &v1, const BowVector &v2) const
{
BowVector::const_iterator v1_it, v2_it;
const BowVector::const_iterator v1_end = v1.end();
const BowVector::const_iterator v2_end = v2.end();
v1_it = v1.begin();
v2_it = v2.begin();
double score = 0;
while(v1_it != v1_end && v2_it != v2_end)
{
const WordValue& vi = v1_it->second;
const WordValue& wi = v2_it->second;
if(v1_it->first == v2_it->first)
{
score += fabs(vi - wi) - fabs(vi) - fabs(wi);
// move v1 and v2 forward
++v1_it;
++v2_it;
}
else if(v1_it->first < v2_it->first)
{
// move v1 forward
v1_it = v1.lower_bound(v2_it->first);
// v1_it = (first element >= v2_it.id)
}
else
{
// move v2 forward
v2_it = v2.lower_bound(v1_it->first);
// v2_it = (first element >= v1_it.id)
}
}
// ||v - w||_{L1} = 2 + Sum(|v_i - w_i| - |v_i| - |w_i|)
// for all i | v_i != 0 and w_i != 0
// (Nister, 2006)
// scaled_||v - w||_{L1} = 1 - 0.5 * ||v - w||_{L1}
score = -score/2.0;
return score; // [0..1]
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
double L2Scoring::score(const BowVector &v1, const BowVector &v2) const
{
BowVector::const_iterator v1_it, v2_it;
const BowVector::const_iterator v1_end = v1.end();
const BowVector::const_iterator v2_end = v2.end();
v1_it = v1.begin();
v2_it = v2.begin();
double score = 0;
while(v1_it != v1_end && v2_it != v2_end)
{
const WordValue& vi = v1_it->second;
const WordValue& wi = v2_it->second;
if(v1_it->first == v2_it->first)
{
score += vi * wi;
// move v1 and v2 forward
++v1_it;
++v2_it;
}
else if(v1_it->first < v2_it->first)
{
// move v1 forward
v1_it = v1.lower_bound(v2_it->first);
// v1_it = (first element >= v2_it.id)
}
else
{
// move v2 forward
v2_it = v2.lower_bound(v1_it->first);
// v2_it = (first element >= v1_it.id)
}
}
// ||v - w||_{L2} = sqrt( 2 - 2 * Sum(v_i * w_i) )
// for all i | v_i != 0 and w_i != 0 )
// (Nister, 2006)
if(score >= 1) // rounding errors
score = 1.0;
else
score = 1.0 - sqrt(1.0 - score); // [0..1]
return score;
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
double ChiSquareScoring::score(const BowVector &v1, const BowVector &v2)
const
{
BowVector::const_iterator v1_it, v2_it;
const BowVector::const_iterator v1_end = v1.end();
const BowVector::const_iterator v2_end = v2.end();
v1_it = v1.begin();
v2_it = v2.begin();
double score = 0;
// all the items are taken into account
while(v1_it != v1_end && v2_it != v2_end)
{
const WordValue& vi = v1_it->second;
const WordValue& wi = v2_it->second;
if(v1_it->first == v2_it->first)
{
// (v-w)^2/(v+w) - v - w = -4 vw/(v+w)
// we move the -4 out
if(vi + wi != 0.0) score += vi * wi / (vi + wi);
// move v1 and v2 forward
++v1_it;
++v2_it;
}
else if(v1_it->first < v2_it->first)
{
// move v1 forward
v1_it = v1.lower_bound(v2_it->first);
}
else
{
// move v2 forward
v2_it = v2.lower_bound(v1_it->first);
}
}
// this takes the -4 into account
score = 2. * score; // [0..1]
return score;
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
double KLScoring::score(const BowVector &v1, const BowVector &v2) const
{
BowVector::const_iterator v1_it, v2_it;
const BowVector::const_iterator v1_end = v1.end();
const BowVector::const_iterator v2_end = v2.end();
v1_it = v1.begin();
v2_it = v2.begin();
double score = 0;
// all the items or v are taken into account
while(v1_it != v1_end && v2_it != v2_end)
{
const WordValue& vi = v1_it->second;
const WordValue& wi = v2_it->second;
if(v1_it->first == v2_it->first)
{
if(vi != 0 && wi != 0) score += vi * log(vi/wi);
// move v1 and v2 forward
++v1_it;
++v2_it;
}
else if(v1_it->first < v2_it->first)
{
// move v1 forward
score += vi * (log(vi) - LOG_EPS);
++v1_it;
}
else
{
// move v2_it forward, do not add any score
v2_it = v2.lower_bound(v1_it->first);
// v2_it = (first element >= v1_it.id)
}
}
// sum rest of items of v
for(; v1_it != v1_end; ++v1_it)
if(v1_it->second != 0)
score += v1_it->second * (log(v1_it->second) - LOG_EPS);
return score; // cannot be scaled
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
double BhattacharyyaScoring::score(const BowVector &v1,
const BowVector &v2) const
{
BowVector::const_iterator v1_it, v2_it;
const BowVector::const_iterator v1_end = v1.end();
const BowVector::const_iterator v2_end = v2.end();
v1_it = v1.begin();
v2_it = v2.begin();
double score = 0;
while(v1_it != v1_end && v2_it != v2_end)
{
const WordValue& vi = v1_it->second;
const WordValue& wi = v2_it->second;
if(v1_it->first == v2_it->first)
{
score += sqrt(vi * wi);
// move v1 and v2 forward
++v1_it;
++v2_it;
}
else if(v1_it->first < v2_it->first)
{
// move v1 forward
v1_it = v1.lower_bound(v2_it->first);
// v1_it = (first element >= v2_it.id)
}
else
{
// move v2 forward
v2_it = v2.lower_bound(v1_it->first);
// v2_it = (first element >= v1_it.id)
}
}
return score; // already scaled
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
double DotProductScoring::score(const BowVector &v1,
const BowVector &v2) const
{
BowVector::const_iterator v1_it, v2_it;
const BowVector::const_iterator v1_end = v1.end();
const BowVector::const_iterator v2_end = v2.end();
v1_it = v1.begin();
v2_it = v2.begin();
double score = 0;
while(v1_it != v1_end && v2_it != v2_end)
{
const WordValue& vi = v1_it->second;
const WordValue& wi = v2_it->second;
if(v1_it->first == v2_it->first)
{
score += vi * wi;
// move v1 and v2 forward
++v1_it;
++v2_it;
}
else if(v1_it->first < v2_it->first)
{
// move v1 forward
v1_it = v1.lower_bound(v2_it->first);
// v1_it = (first element >= v2_it.id)
}
else
{
// move v2 forward
v2_it = v2.lower_bound(v1_it->first);
// v2_it = (first element >= v1_it.id)
}
}
return score; // cannot scale
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------

96
Thirdparty/DBoW2/DBoW2/ScoringObject.h vendored Normal file
View File

@@ -0,0 +1,96 @@
/**
* File: ScoringObject.h
* Date: November 2011
* Author: Dorian Galvez-Lopez
* Description: functions to compute bow scores
* License: see the LICENSE.txt file
*
*/
#ifndef __D_T_SCORING_OBJECT__
#define __D_T_SCORING_OBJECT__
#include "BowVector.h"
namespace DBoW2 {
/// Base class of scoring functions
class GeneralScoring
{
public:
/**
* Computes the score between two vectors. Vectors must be sorted and
* normalized if necessary
* @param v (in/out)
* @param w (in/out)
* @return score
*/
virtual double score(const BowVector &v, const BowVector &w) const = 0;
/**
* Returns whether a vector must be normalized before scoring according
* to the scoring scheme
* @param norm norm to use
* @return true iff must normalize
*/
virtual bool mustNormalize(LNorm &norm) const = 0;
/// Log of epsilon
static const double LOG_EPS;
// If you change the type of WordValue, make sure you change also the
// epsilon value (this is needed by the KL method)
virtual ~GeneralScoring() {} //!< Required for virtual base classes
};
/**
* Macro for defining Scoring classes
* @param NAME name of class
* @param MUSTNORMALIZE if vectors must be normalized to compute the score
* @param NORM type of norm to use when MUSTNORMALIZE
*/
#define __SCORING_CLASS(NAME, MUSTNORMALIZE, NORM) \
NAME: public GeneralScoring \
{ public: \
/** \
* Computes score between two vectors \
* @param v \
* @param w \
* @return score between v and w \
*/ \
virtual double score(const BowVector &v, const BowVector &w) const; \
\
/** \
* Says if a vector must be normalized according to the scoring function \
* @param norm (out) if true, norm to use
* @return true iff vectors must be normalized \
*/ \
virtual inline bool mustNormalize(LNorm &norm) const \
{ norm = NORM; return MUSTNORMALIZE; } \
}
/// L1 Scoring object
class __SCORING_CLASS(L1Scoring, true, L1);
/// L2 Scoring object
class __SCORING_CLASS(L2Scoring, true, L2);
/// Chi square Scoring object
class __SCORING_CLASS(ChiSquareScoring, true, L1);
/// KL divergence Scoring object
class __SCORING_CLASS(KLScoring, true, L1);
/// Bhattacharyya Scoring object
class __SCORING_CLASS(BhattacharyyaScoring, true, L1);
/// Dot product Scoring object
class __SCORING_CLASS(DotProductScoring, false, L1);
#undef __SCORING_CLASS
} // namespace DBoW2
#endif

File diff suppressed because it is too large Load Diff

129
Thirdparty/DBoW2/DUtils/Random.cpp vendored Normal file
View File

@@ -0,0 +1,129 @@
/*
* File: Random.cpp
* Project: DUtils library
* Author: Dorian Galvez-Lopez
* Date: April 2010
* Description: manages pseudo-random numbers
* License: see the LICENSE.txt file
*
*/
#include "Random.h"
#include "Timestamp.h"
#include <cstdlib>
using namespace std;
bool DUtils::Random::m_already_seeded = false;
void DUtils::Random::SeedRand(){
Timestamp time;
time.setToCurrentTime();
srand((unsigned)time.getFloatTime());
}
void DUtils::Random::SeedRandOnce()
{
if(!m_already_seeded)
{
DUtils::Random::SeedRand();
m_already_seeded = true;
}
}
void DUtils::Random::SeedRand(int seed)
{
srand(seed);
}
void DUtils::Random::SeedRandOnce(int seed)
{
if(!m_already_seeded)
{
DUtils::Random::SeedRand(seed);
m_already_seeded = true;
}
}
int DUtils::Random::RandomInt(int min, int max){
int d = max - min + 1;
return int(((double)rand()/((double)RAND_MAX + 1.0)) * d) + min;
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
DUtils::Random::UnrepeatedRandomizer::UnrepeatedRandomizer(int min, int max)
{
if(min <= max)
{
m_min = min;
m_max = max;
}
else
{
m_min = max;
m_max = min;
}
createValues();
}
// ---------------------------------------------------------------------------
DUtils::Random::UnrepeatedRandomizer::UnrepeatedRandomizer
(const DUtils::Random::UnrepeatedRandomizer& rnd)
{
*this = rnd;
}
// ---------------------------------------------------------------------------
int DUtils::Random::UnrepeatedRandomizer::get()
{
if(empty()) createValues();
DUtils::Random::SeedRandOnce();
int k = DUtils::Random::RandomInt(0, m_values.size()-1);
int ret = m_values[k];
m_values[k] = m_values.back();
m_values.pop_back();
return ret;
}
// ---------------------------------------------------------------------------
void DUtils::Random::UnrepeatedRandomizer::createValues()
{
int n = m_max - m_min + 1;
m_values.resize(n);
for(int i = 0; i < n; ++i) m_values[i] = m_min + i;
}
// ---------------------------------------------------------------------------
void DUtils::Random::UnrepeatedRandomizer::reset()
{
if((int)m_values.size() != m_max - m_min + 1) createValues();
}
// ---------------------------------------------------------------------------
DUtils::Random::UnrepeatedRandomizer&
DUtils::Random::UnrepeatedRandomizer::operator=
(const DUtils::Random::UnrepeatedRandomizer& rnd)
{
if(this != &rnd)
{
this->m_min = rnd.m_min;
this->m_max = rnd.m_max;
this->m_values = rnd.m_values;
}
return *this;
}
// ---------------------------------------------------------------------------

184
Thirdparty/DBoW2/DUtils/Random.h vendored Normal file
View File

@@ -0,0 +1,184 @@
/*
* File: Random.h
* Project: DUtils library
* Author: Dorian Galvez-Lopez
* Date: April 2010, November 2011
* Description: manages pseudo-random numbers
* License: see the LICENSE.txt file
*
*/
#pragma once
#ifndef __D_RANDOM__
#define __D_RANDOM__
#include <cstdlib>
#include <vector>
namespace DUtils {
/// Functions to generate pseudo-random numbers
class Random
{
public:
class UnrepeatedRandomizer;
public:
/**
* Sets the random number seed to the current time
*/
static void SeedRand();
/**
* Sets the random number seed to the current time only the first
* time this function is called
*/
static void SeedRandOnce();
/**
* Sets the given random number seed
* @param seed
*/
static void SeedRand(int seed);
/**
* Sets the given random number seed only the first time this function
* is called
* @param seed
*/
static void SeedRandOnce(int seed);
/**
* Returns a random number in the range [0..1]
* @return random T number in [0..1]
*/
template <class T>
static T RandomValue(){
return (T)rand()/(T)RAND_MAX;
}
/**
* Returns a random number in the range [min..max]
* @param min
* @param max
* @return random T number in [min..max]
*/
template <class T>
static T RandomValue(T min, T max){
return Random::RandomValue<T>() * (max - min) + min;
}
/**
* Returns a random int in the range [min..max]
* @param min
* @param max
* @return random int in [min..max]
*/
static int RandomInt(int min, int max);
/**
* Returns a random number from a gaussian distribution
* @param mean
* @param sigma standard deviation
*/
template <class T>
static T RandomGaussianValue(T mean, T sigma)
{
// Box-Muller transformation
T x1, x2, w, y1;
do {
x1 = (T)2. * RandomValue<T>() - (T)1.;
x2 = (T)2. * RandomValue<T>() - (T)1.;
w = x1 * x1 + x2 * x2;
} while ( w >= (T)1. || w == (T)0. );
w = sqrt( ((T)-2.0 * log( w ) ) / w );
y1 = x1 * w;
return( mean + y1 * sigma );
}
private:
/// If SeedRandOnce() or SeedRandOnce(int) have already been called
static bool m_already_seeded;
};
// ---------------------------------------------------------------------------
/// Provides pseudo-random numbers with no repetitions
class Random::UnrepeatedRandomizer
{
public:
/**
* Creates a randomizer that returns numbers in the range [min, max]
* @param min
* @param max
*/
UnrepeatedRandomizer(int min, int max);
~UnrepeatedRandomizer(){}
/**
* Copies a randomizer
* @param rnd
*/
UnrepeatedRandomizer(const UnrepeatedRandomizer& rnd);
/**
* Copies a randomizer
* @param rnd
*/
UnrepeatedRandomizer& operator=(const UnrepeatedRandomizer& rnd);
/**
* Returns a random number not given before. If all the possible values
* were already given, the process starts again
* @return unrepeated random number
*/
int get();
/**
* Returns whether all the possible values between min and max were
* already given. If get() is called when empty() is true, the behaviour
* is the same than after creating the randomizer
* @return true iff all the values were returned
*/
inline bool empty() const { return m_values.empty(); }
/**
* Returns the number of values still to be returned
* @return amount of values to return
*/
inline unsigned int left() const { return m_values.size(); }
/**
* Resets the randomizer as it were just created
*/
void reset();
protected:
/**
* Creates the vector with available values
*/
void createValues();
protected:
/// Min of range of values
int m_min;
/// Max of range of values
int m_max;
/// Available values
std::vector<int> m_values;
};
}
#endif

246
Thirdparty/DBoW2/DUtils/Timestamp.cpp vendored Normal file
View File

@@ -0,0 +1,246 @@
/*
* File: Timestamp.cpp
* Author: Dorian Galvez-Lopez
* Date: March 2009
* Description: timestamping functions
*
* Note: in windows, this class has a 1ms resolution
*
* License: see the LICENSE.txt file
*
*/
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <sstream>
#include <iomanip>
#ifdef _WIN32
#ifndef WIN32
#define WIN32
#endif
#endif
#ifdef WIN32
#include <sys/timeb.h>
#define sprintf sprintf_s
#else
#include <sys/time.h>
#endif
#include "Timestamp.h"
using namespace std;
using namespace DUtils;
Timestamp::Timestamp(Timestamp::tOptions option)
{
if(option & CURRENT_TIME)
setToCurrentTime();
else if(option & ZERO)
setTime(0.);
}
Timestamp::~Timestamp(void)
{
}
bool Timestamp::empty() const
{
return m_secs == 0 && m_usecs == 0;
}
void Timestamp::setToCurrentTime(){
#ifdef WIN32
struct __timeb32 timebuffer;
_ftime32_s( &timebuffer ); // C4996
// Note: _ftime is deprecated; consider using _ftime_s instead
m_secs = timebuffer.time;
m_usecs = timebuffer.millitm * 1000;
#else
struct timeval now;
gettimeofday(&now, NULL);
m_secs = now.tv_sec;
m_usecs = now.tv_usec;
#endif
}
void Timestamp::setTime(const string &stime){
string::size_type p = stime.find('.');
if(p == string::npos){
m_secs = atol(stime.c_str());
m_usecs = 0;
}else{
m_secs = atol(stime.substr(0, p).c_str());
string s_usecs = stime.substr(p+1, 6);
m_usecs = atol(stime.substr(p+1).c_str());
m_usecs *= (unsigned long)pow(10.0, double(6 - s_usecs.length()));
}
}
void Timestamp::setTime(double s)
{
m_secs = (unsigned long)s;
m_usecs = (s - (double)m_secs) * 1e6;
}
double Timestamp::getFloatTime() const {
return double(m_secs) + double(m_usecs)/1000000.0;
}
string Timestamp::getStringTime() const {
char buf[32];
sprintf(buf, "%.6lf", this->getFloatTime());
return string(buf);
}
double Timestamp::operator- (const Timestamp &t) const {
return this->getFloatTime() - t.getFloatTime();
}
Timestamp& Timestamp::operator+= (double s)
{
*this = *this + s;
return *this;
}
Timestamp& Timestamp::operator-= (double s)
{
*this = *this - s;
return *this;
}
Timestamp Timestamp::operator+ (double s) const
{
unsigned long secs = (long)floor(s);
unsigned long usecs = (long)((s - (double)secs) * 1e6);
return this->plus(secs, usecs);
}
Timestamp Timestamp::plus(unsigned long secs, unsigned long usecs) const
{
Timestamp t;
const unsigned long max = 1000000ul;
if(m_usecs + usecs >= max)
t.setTime(m_secs + secs + 1, m_usecs + usecs - max);
else
t.setTime(m_secs + secs, m_usecs + usecs);
return t;
}
Timestamp Timestamp::operator- (double s) const
{
unsigned long secs = (long)floor(s);
unsigned long usecs = (long)((s - (double)secs) * 1e6);
return this->minus(secs, usecs);
}
Timestamp Timestamp::minus(unsigned long secs, unsigned long usecs) const
{
Timestamp t;
const unsigned long max = 1000000ul;
if(m_usecs < usecs)
t.setTime(m_secs - secs - 1, max - (usecs - m_usecs));
else
t.setTime(m_secs - secs, m_usecs - usecs);
return t;
}
bool Timestamp::operator> (const Timestamp &t) const
{
if(m_secs > t.m_secs) return true;
else if(m_secs == t.m_secs) return m_usecs > t.m_usecs;
else return false;
}
bool Timestamp::operator>= (const Timestamp &t) const
{
if(m_secs > t.m_secs) return true;
else if(m_secs == t.m_secs) return m_usecs >= t.m_usecs;
else return false;
}
bool Timestamp::operator< (const Timestamp &t) const
{
if(m_secs < t.m_secs) return true;
else if(m_secs == t.m_secs) return m_usecs < t.m_usecs;
else return false;
}
bool Timestamp::operator<= (const Timestamp &t) const
{
if(m_secs < t.m_secs) return true;
else if(m_secs == t.m_secs) return m_usecs <= t.m_usecs;
else return false;
}
bool Timestamp::operator== (const Timestamp &t) const
{
return(m_secs == t.m_secs && m_usecs == t.m_usecs);
}
string Timestamp::Format(bool machine_friendly) const
{
struct tm tm_time;
time_t t = (time_t)getFloatTime();
#ifdef WIN32
localtime_s(&tm_time, &t);
#else
localtime_r(&t, &tm_time);
#endif
char buffer[128];
if(machine_friendly)
{
strftime(buffer, 128, "%Y%m%d_%H%M%S", &tm_time);
}
else
{
strftime(buffer, 128, "%c", &tm_time); // Thu Aug 23 14:55:02 2001
}
return string(buffer);
}
string Timestamp::Format(double s) {
int days = int(s / (24. * 3600.0));
s -= days * (24. * 3600.0);
int hours = int(s / 3600.0);
s -= hours * 3600;
int minutes = int(s / 60.0);
s -= minutes * 60;
int seconds = int(s);
int ms = int((s - seconds)*1e6);
stringstream ss;
ss.fill('0');
bool b;
if((b = (days > 0))) ss << days << "d ";
if((b = (b || hours > 0))) ss << setw(2) << hours << ":";
if((b = (b || minutes > 0))) ss << setw(2) << minutes << ":";
if(b) ss << setw(2);
ss << seconds;
if(!b) ss << "." << setw(6) << ms;
return ss.str();
}

204
Thirdparty/DBoW2/DUtils/Timestamp.h vendored Normal file
View File

@@ -0,0 +1,204 @@
/*
* File: Timestamp.h
* Author: Dorian Galvez-Lopez
* Date: March 2009
* Description: timestamping functions
* License: see the LICENSE.txt file
*
*/
#ifndef __D_TIMESTAMP__
#define __D_TIMESTAMP__
#include <iostream>
using namespace std;
namespace DUtils {
/// Timestamp
class Timestamp
{
public:
/// Options to initiate a timestamp
enum tOptions
{
NONE = 0,
CURRENT_TIME = 0x1,
ZERO = 0x2
};
public:
/**
* Creates a timestamp
* @param option option to set the initial time stamp
*/
Timestamp(Timestamp::tOptions option = NONE);
/**
* Destructor
*/
virtual ~Timestamp(void);
/**
* Says if the timestamp is "empty": seconds and usecs are both 0, as
* when initiated with the ZERO flag
* @return true iif secs == usecs == 0
*/
bool empty() const;
/**
* Sets this instance to the current time
*/
void setToCurrentTime();
/**
* Sets the timestamp from seconds and microseconds
* @param secs: seconds
* @param usecs: microseconds
*/
inline void setTime(unsigned long secs, unsigned long usecs){
m_secs = secs;
m_usecs = usecs;
}
/**
* Returns the timestamp in seconds and microseconds
* @param secs seconds
* @param usecs microseconds
*/
inline void getTime(unsigned long &secs, unsigned long &usecs) const
{
secs = m_secs;
usecs = m_usecs;
}
/**
* Sets the timestamp from a string with the time in seconds
* @param stime: string such as "1235603336.036609"
*/
void setTime(const string &stime);
/**
* Sets the timestamp from a number of seconds from the epoch
* @param s seconds from the epoch
*/
void setTime(double s);
/**
* Returns this timestamp as the number of seconds in (long) float format
*/
double getFloatTime() const;
/**
* Returns this timestamp as the number of seconds in fixed length string format
*/
string getStringTime() const;
/**
* Returns the difference in seconds between this timestamp (greater) and t (smaller)
* If the order is swapped, a negative number is returned
* @param t: timestamp to subtract from this timestamp
* @return difference in seconds
*/
double operator- (const Timestamp &t) const;
/**
* Returns a copy of this timestamp + s seconds + us microseconds
* @param s seconds
* @param us microseconds
*/
Timestamp plus(unsigned long s, unsigned long us) const;
/**
* Returns a copy of this timestamp - s seconds - us microseconds
* @param s seconds
* @param us microseconds
*/
Timestamp minus(unsigned long s, unsigned long us) const;
/**
* Adds s seconds to this timestamp and returns a reference to itself
* @param s seconds
* @return reference to this timestamp
*/
Timestamp& operator+= (double s);
/**
* Substracts s seconds to this timestamp and returns a reference to itself
* @param s seconds
* @return reference to this timestamp
*/
Timestamp& operator-= (double s);
/**
* Returns a copy of this timestamp + s seconds
* @param s: seconds
*/
Timestamp operator+ (double s) const;
/**
* Returns a copy of this timestamp - s seconds
* @param s: seconds
*/
Timestamp operator- (double s) const;
/**
* Returns whether this timestamp is at the future of t
* @param t
*/
bool operator> (const Timestamp &t) const;
/**
* Returns whether this timestamp is at the future of (or is the same as) t
* @param t
*/
bool operator>= (const Timestamp &t) const;
/**
* Returns whether this timestamp and t represent the same instant
* @param t
*/
bool operator== (const Timestamp &t) const;
/**
* Returns whether this timestamp is at the past of t
* @param t
*/
bool operator< (const Timestamp &t) const;
/**
* Returns whether this timestamp is at the past of (or is the same as) t
* @param t
*/
bool operator<= (const Timestamp &t) const;
/**
* Returns the timestamp in a human-readable string
* @param machine_friendly if true, the returned string is formatted
* to yyyymmdd_hhmmss, without weekday or spaces
* @note This has not been tested under Windows
* @note The timestamp is truncated to seconds
*/
string Format(bool machine_friendly = false) const;
/**
* Returns a string version of the elapsed time in seconds, with the format
* xd hh:mm:ss, hh:mm:ss, mm:ss or s.us
* @param s: elapsed seconds (given by getFloatTime) to format
*/
static string Format(double s);
protected:
/// Seconds
unsigned long m_secs; // seconds
/// Microseconds
unsigned long m_usecs; // microseconds
};
}
#endif

7
Thirdparty/DBoW2/README.txt vendored Normal file
View File

@@ -0,0 +1,7 @@
You should have received this DBoW2 version along with ORB-SLAM2 (https://github.com/raulmur/ORB_SLAM2).
See the original DBoW2 library at: https://github.com/dorian3d/DBoW2
All files included in this version are BSD, see LICENSE.txt
We also use Random.h, Random.cpp, Timestamp.pp and Timestamp.h from DLib/DUtils.
See the original DLib library at: https://github.com/dorian3d/DLib
All files included in this version are BSD, see LICENSE.txt