Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load from and save text/binary function (for Orbslam2, orbslam3), cmake export target #64

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,46 @@ set(SRCS
src/BowVector.cpp src/FBrief.cpp src/FORB.cpp
src/FeatureVector.cpp src/QueryResults.cpp src/ScoringObject.cpp)

set(DEPENDENCY_DIR ${CMAKE_CURRENT_BINARY_DIR}/dependencies)
set(DEPENDENCY_INSTALL_DIR ${DEPENDENCY_DIR}/install)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

if(BUILD_DBoW2)
set(LIB_SHARED "SHARED")
if(WIN32)
set(LIB_SHARED "STATIC")
endif(WIN32)
add_library(${PROJECT_NAME} ${LIB_SHARED} ${SRCS})
target_include_directories(${PROJECT_NAME} PUBLIC include/DBoW2/ include/)
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/DBoW2>
$<INSTALL_INTERFACE:include/DBoW2>
$<INSTALL_INTERFACE:include/DBoW2/DBoW2>)
target_link_libraries(${PROJECT_NAME} PUBLIC ${OpenCV_LIBRARIES})
set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 11
POSITION_INDEPENDENT_CODE ON
DEBUG_POSTFIX _d
)
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
endif(BUILD_DBoW2)

if(BUILD_Demo)
add_executable(demo demo/demo.cpp)
target_link_libraries(demo ${PROJECT_NAME} ${OpenCV_LIBS})
target_link_libraries(demo ${PROJECT_NAME} ${OpenCV_LIBRARIES})
set_target_properties(demo PROPERTIES CXX_STANDARD 11)
file(COPY demo/images DESTINATION ${CMAKE_BINARY_DIR}/)
endif(BUILD_Demo)

configure_file(src/DBoW2.cmake.in
"${PROJECT_BINARY_DIR}/DBoW2Config.cmake" @ONLY)

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
if(BUILD_DBoW2)
install(DIRECTORY include/DBoW2 DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install(DIRECTORY include/DBoW2 DESTINATION ${CMAKE_INSTALL_PREFIX}/include/DBoW2)
endif()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/DBoW2Config.cmake"
DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME})
install(FILES "${PROJECT_BINARY_DIR}/DBoW2Config.cmake"
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/DBoW2/)
install(DIRECTORY ${DEPENDENCY_INSTALL_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX} OPTIONAL)

install(EXPORT ${PROJECT_NAME}-targets DESTINATION lib/cmake/${PROJECT_NAME}
NAMESPACE ${PROJECT_NAME}::)
223 changes: 219 additions & 4 deletions include/DBoW2/TemplatedVocabulary.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <vector>
#include <numeric>
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm>
#include <opencv2/core.hpp>
Expand All @@ -30,9 +31,9 @@ namespace DBoW2 {
template<class TDescriptor, class F>
/// Generic Vocabulary
class TemplatedVocabulary
{
{
public:

/**
* Initiates an empty vocabulary
* @param k branching factor
Expand Down Expand Up @@ -227,13 +228,37 @@ class TemplatedVocabulary
* @param filename
*/
void save(const std::string &filename) const;


/**
* Saves the vocabulary into a text file
* @param filename
*/
void saveToTextFile(const std::string &filename) const;

/**
* Saves the vocabulary into a binary file
* @param filename
*/
void saveToBinaryFile(const std::string &filename) const;

/**
* Loads the vocabulary from a file
* @param filename
*/
void load(const std::string &filename);


/**
* Loads the vocabulary from a binary file
* @param filename
*/
void loadFromTextFile(const std::string &filename);

/**
* Loads the vocabulary from a text file
* @param filename
*/
void loadFromBinaryFile(const std::string &filename);

/**
* Saves the vocabulary to a file storage structure
* @param fn node in file storage
Expand Down Expand Up @@ -1343,6 +1368,61 @@ void TemplatedVocabulary<TDescriptor,F>::save(const std::string &filename) const

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

template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor,F>::saveToTextFile(const std::string &filename) const
{
std::fstream f;
f.open(filename.c_str(), std::ios_base::out);
f << m_k << " " << m_L << " " << " " << m_scoring << " " << m_weighting << std::endl;

for(size_t i=1; i<m_nodes.size();i++)
{
const Node& node = m_nodes[i];

f << node.parent << " ";
if(node.isLeaf())
f << 1 << " ";
else
f << 0 << " ";

f << F::toString(node.descriptor) << " " << (double)node.weight << std::endl;
}

f.close();
}

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

template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor,F>::saveToBinaryFile(const std::string &filename) const
{
std::ofstream vocabulary_bin(filename, std::ios::binary);
vocabulary_bin.write((char*)&m_k, sizeof(m_k));
vocabulary_bin.write((char*)&m_L, sizeof(m_L));
vocabulary_bin.write((char*)&m_weighting, sizeof(m_weighting));
vocabulary_bin.write((char*)&m_scoring, sizeof(m_scoring));
uint64_t vec_size = (uint64_t)m_nodes.size();
vocabulary_bin.write((char*)&vec_size, sizeof(uint64_t));
for (auto & node : m_nodes)
{
vocabulary_bin.write((char*)&node.id, sizeof(node.id));
vocabulary_bin.write((char*)&node.weight, sizeof(node.weight));
vocabulary_bin.write((char*)&node.parent, sizeof(node.parent));
vocabulary_bin.write((char*)&node.word_id, sizeof(node.word_id));
if (node.descriptor.total() > 0)
vocabulary_bin.write((char*)node.descriptor.ptr(), 32);
vec_size = (uint64_t)node.children.size();
vocabulary_bin.write((char*)&vec_size, sizeof(uint64_t));
if (vec_size > 0)
{
vocabulary_bin.write((char*)node.children.data(), sizeof(node.children[0]) * vec_size);
}
}
vocabulary_bin.close();
}

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

template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor,F>::load(const std::string &filename)
{
Expand All @@ -1354,6 +1434,141 @@ void TemplatedVocabulary<TDescriptor,F>::load(const std::string &filename)

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

template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor,F>::loadFromTextFile(const std::string &filename)
{
std::ifstream f;
f.open(filename.c_str());
if (!f.is_open())
throw std::string("Could not open file ") + filename;

m_words.clear();
m_nodes.clear();

std::string s;
getline(f,s);
std::stringstream ss;
ss << s;
ss >> m_k;
ss >> m_L;
int n1, n2;
ss >> n1;
ss >> n2;

if(m_k<0 || m_k>20 || m_L<1 || m_L>10 || n1<0 || n1>5 || n2<0 || n2>3)
{
throw std::string("Vocabulary loading failure: This is not a correct text file!") + filename;
}

m_scoring = (ScoringType)n1;
m_weighting = (WeightingType)n2;
createScoringObject();

// nodes
int expected_nodes =
(int)((pow((double)m_k, (double)m_L + 1) - 1)/(m_k - 1));
m_nodes.reserve(expected_nodes);

m_words.reserve(pow((double)m_k, (double)m_L + 1));

m_nodes.resize(1);
m_nodes[0].id = 0;
while(!f.eof())
{
std::string snode;
std::getline(f,snode);
std::stringstream ssnode;
ssnode << snode;

int nid = m_nodes.size();
m_nodes.resize(m_nodes.size()+1);
m_nodes[nid].id = nid;

int pid ;
ssnode >> pid;
m_nodes[nid].parent = pid;
m_nodes[pid].children.push_back(nid);

int nIsLeaf;
ssnode >> nIsLeaf;

std::stringstream ssd;
for(int iD=0;iD<32;iD++) // F::L
{
std::string sElement;
ssnode >> sElement;
ssd << sElement << " ";
}
F::fromString(m_nodes[nid].descriptor, ssd.str());

ssnode >> m_nodes[nid].weight;

if(nIsLeaf>0)
{
int wid = m_words.size();
m_words.resize(wid+1);

m_nodes[nid].word_id = wid;
m_words[wid] = &m_nodes[nid];
}
else
{
m_nodes[nid].children.reserve(m_k);
}
}
}

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

template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor, F>::loadFromBinaryFile(const std::string & filename)
{
std::ifstream vocabulary_bin(filename, std::ios::binary);
if (!vocabulary_bin.is_open())
throw std::string("Could not open file ") + filename;

vocabulary_bin.read((char*)&m_k, sizeof(m_k));
vocabulary_bin.read((char*)&m_L, sizeof(m_L));
vocabulary_bin.read((char*)&m_weighting, sizeof(m_weighting));
vocabulary_bin.read((char*)&m_scoring, sizeof(m_scoring));
createScoringObject();
uint64_t vec_size = 0;
vocabulary_bin.read((char*)&vec_size, sizeof(uint64_t));
m_nodes.resize(vec_size);
m_words.reserve(pow((double)m_k, (double)m_L + 1));

int nid = 0;
int wid = 0;
for (auto & node : m_nodes)
{
vocabulary_bin.read((char*)&node.id, sizeof(node.id));
vocabulary_bin.read((char*)&node.weight, sizeof(node.weight));
vocabulary_bin.read((char*)&node.parent, sizeof(node.parent));
vocabulary_bin.read((char*)&node.word_id, sizeof(node.word_id));
if (nid > 0)
{
node.descriptor.create(1, 32, CV_8UC1);
vocabulary_bin.read((char*)node.descriptor.ptr(), 32);
}
vec_size = 0;
vocabulary_bin.read((char*)&vec_size, sizeof(uint64_t));
if (vec_size > 0)
{
node.children.resize(vec_size);
vocabulary_bin.read((char*)node.children.data(), sizeof(node.children[0]) * vec_size);
}
++nid;
if (node.weight != 0)
{
m_words.resize(node.word_id + 1);
m_words[node.word_id] = &node;
}
}
vocabulary_bin.close();
}

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

template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor,F>::save(cv::FileStorage &f,
const std::string &name) const
Expand Down
8 changes: 7 additions & 1 deletion src/DBoW2.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ FIND_LIBRARY(DBoW2_LIBRARY DBoW2
PATHS "@CMAKE_INSTALL_PREFIX@/lib"
)
FIND_PATH(DBoW2_INCLUDE_DIR DBoW2.h
PATHS "@CMAKE_INSTALL_PREFIX@/include/@PROJECT_NAME@"
PATHS "@CMAKE_INSTALL_PREFIX@/include/@PROJECT_NAME@"
PATH_SUFFIXES @PROJECT_NAME@
)
LIST(APPEND DBoW2_INCLUDE_DIR ${DBoW2_INCLUDE_DIR}/../)
SET(DBoW2_LIBRARIES ${DBoW2_LIBRARY})
SET(DBoW2_LIBS ${DBoW2_LIBRARY})
SET(DBoW2_INCLUDE_DIRS ${DBoW2_INCLUDE_DIR})

#laod dbow targets
include(CMakeFindDependencyMacro)
find_dependency(OpenCV @OpenCV_VERSION@ EXACT)
include(${CMAKE_CURRENT_LIST_DIR}/@[email protected])