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
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
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
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
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
00059 centers_.reserve(size);
00060 for (int i = 0; i < all.rows; ++i)
00061 centers_.push_back(all.row(i));
00062
00063
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 }