generic_tree.cpp
Go to the documentation of this file.
00001 #include <vocabulary_tree/generic_tree.h>
00002 #include <stdexcept>
00003 #include <boost/format.hpp>
00004 
00005 namespace vt {
00006 
00007 GenericTree::GenericTree()
00008 {
00009 }
00010 
00011 GenericTree::GenericTree(const std::string& file)
00012 {
00013   load(file);
00014 }
00015 
00017 // Kinda sucks that we need to wrap these functions.
00018 void GenericTree::save(const std::string& file) const
00019 {
00020   assert( initialized() );
00021 
00022   std::ofstream out(file.c_str(), std::ios_base::binary);
00023   out.write((char*)(&k_), sizeof(uint32_t));
00024   out.write((char*)(&levels_), sizeof(uint32_t));
00025   uint32_t size = centers_.size();
00026   out.write((char*)(&size), sizeof(uint32_t));
00027   // This is pretty hacky! Retrieve the start and end of the block of data.
00028   const uchar* start = centers_[0].datastart;
00029   const uchar* end = centers_[0].dataend;
00030   out.write((const char*)start, end - start);
00031   out.write((const char*)(&valid_centers_[0]), valid_centers_.size());
00032 }
00033 
00034 void GenericTree::load(const std::string& file)
00035 {
00036   clear();
00037 
00038   std::ifstream in;
00039   in.exceptions(std::ifstream::eofbit | std::ifstream::failbit | std::ifstream::badbit);
00040 
00041   uint32_t size;
00042   try {
00043     in.open(file.c_str(), std::ios_base::binary);
00044     in.read((char*)(&k_), sizeof(uint32_t));
00045     in.read((char*)(&levels_), sizeof(uint32_t));
00046     in.read((char*)(&size), sizeof(uint32_t));
00047 
00048     // Use arithmetic on file size to get the descriptor length, ugh. Assuming float.
00049     in.seekg(0, std::ios::end);
00050     int length = in.tellg();
00051     int dimension = ((length - 12)/size - sizeof(uint8_t)) / sizeof(float);
00052     in.seekg(12, std::ios::beg);
00053 
00054     // Read in centers as one big cv::Mat to preserve data locality.
00055     cv::Mat all(size, dimension, cv::DataType<float>::type);
00056     assert(all.isContinuous());
00057     in.read((char*)all.data, size * dimension * sizeof(float));
00058     // Now add cv::Mat centers that point into the big block of data.
00059     centers_.reserve(size);
00060     for (int i = 0; i < all.rows; ++i)
00061       centers_.push_back(all.row(i));
00062 
00063     // Read in valid centers as usual
00064     valid_centers_.resize(size);
00065     in.read((char*)(&valid_centers_[0]), valid_centers_.size());
00066     assert(in.tellg() == length);
00067   }
00068   catch (std::ifstream::failure& e) {
00069     throw std::runtime_error( (boost::format("Failed to load vocabulary tree file '%s'") % file).str() );
00070   }
00071 
00072   setNodeCounts();
00073   assert(size == num_words_ + word_start_);
00074 }
00075 
00076 size_t GenericTree::dimension() const
00077 {
00078   assert( initialized() );
00079   return centers_[0].cols;
00080 }
00081 
00082 } //namespace vt


vocabulary_tree
Author(s): Patrick Mihelich
autogenerated on Thu Jan 2 2014 12:12:26