vocabtree  0.0.1
bench_bow.cxx
Go to the documentation of this file.
1 #include "bench_config.hpp"
2 
3 #include <config.hpp>
4 
5 #include <utils/filesystem.hpp>
6 #include <utils/numerics.hpp>
7 #include <utils/dataset.hpp>
8 #include <utils/vision.hpp>
9 #include <utils/logger.hpp>
11 
12 #include <iostream>
13 #include <sstream>
14 
15 #if ENABLE_MULTITHREADING && ENABLE_OPENMP
16 #include <omp.h>
17 #endif
18 #if ENABLE_MULTITHREADING && ENABLE_MPI
19 #include <mpi.h>
20 #endif
21 
22 _INITIALIZE_EASYLOGGINGPP
23 
24 void compute_bow(SimpleDataset &dataset, int num_clusters, int num_images, int num_features) {
25 #if ENABLE_FASTCLUSTER && ENABLE_MPI
26  int rank = MPI::COMM_WORLD.Get_rank();
27 #else
28  int rank = 0;
29 #endif
30  if(rank == 0) {
31  LINFO << dataset;
32  }
33 
34  BagOfWords bow;
35  std::shared_ptr<BagOfWords::TrainParams> train_params = std::make_shared<BagOfWords::TrainParams>();
36  train_params->numClusters = num_clusters;
37  train_params->numFeatures = num_features;
38 
39  std::stringstream vocab_output_file;
40  vocab_output_file << dataset.location() << "/vocabulary/" << train_params->numClusters << ".vocab";
41 
42  if(filesystem::file_exists(vocab_output_file.str())) {
43  bow.load(vocab_output_file.str());
44  } else {
45  const std::vector< std::shared_ptr<const Image> > &random_images = dataset.random_images(num_images);
46  bow.train(dataset, train_params, random_images);
47 #if ENABLE_FASTCLUSTER && ENABLE_MPI
48  if(rank == 0) {
49 #endif
50  bow.save(vocab_output_file.str());
51 #if ENABLE_FASTCLUSTER && ENABLE_MPI
52  }
53 #endif
54  }
55 
56 #if ENABLE_MULTITHREADING && ENABLE_MPI
57  if(rank == 0) {
58 #endif
59 
60  const std::vector< std::shared_ptr<const Image> > &all_images = dataset.all_images();
61 
62 #if ENABLE_MULTITHREADING && ENABLE_OPENMP
63  uint32_t num_threads = omp_get_max_threads();
64  std::vector< cv::Ptr<cv::DescriptorMatcher> > matchers;
65  for(uint32_t i=0; i<num_threads; i++) {
66  matchers.push_back(vision::construct_descriptor_matcher(bow.vocabulary()));
67  }
68 #pragma omp parallel for schedule(dynamic)
69 #else
70  const cv::Ptr<cv::DescriptorMatcher> &matcher = vision::construct_descriptor_matcher(bow.vocabulary());
71 #endif
72  for (int64_t i = 0; i < (int64_t)all_images.size(); i++) {
73 
74 #if ENABLE_MULTITHREADING && ENABLE_OPENMP
75  const cv::Ptr<cv::DescriptorMatcher> &matcher = matchers[omp_get_thread_num()];
76 #endif
77  const std::string &sift_descriptor_location = dataset.location(all_images[i]->feature_path("descriptors"));
78  const std::string &bow_descriptor_location = dataset.location(all_images[i]->feature_path("bow_descriptors"));
79 
80  cv::Mat descriptors, bow_descriptors, descriptorsf;
81  if (!filesystem::file_exists(sift_descriptor_location)) continue;
82  if (!filesystem::load_cvmat(sift_descriptor_location, descriptors)) continue;
83  descriptors.convertTo(descriptorsf, CV_32FC1);
84  filesystem::create_file_directory(bow_descriptor_location);
85 
86  if (!vision::compute_bow_feature(descriptorsf, matcher, bow_descriptors, nullptr)) continue;
87  const std::vector< std::pair<uint32_t, float> > &bow_descriptors_sparse = numerics::sparsify(bow_descriptors);
88  filesystem::write_sparse_vector(bow_descriptor_location, bow_descriptors_sparse);
89  LINFO << "Wrote " << bow_descriptor_location;
90  }
91 #if ENABLE_MULTITHREADING && ENABLE_MPI
92  }
93 #endif
94 }
95 
96 int main(int argc, char *argv[]) {
97 
98 #if ENABLE_MULTITHREADING && ENABLE_MPI
99  MPI::Init(argc, argv);
100 #endif
101 
102  // {
103  // SimpleDataset oxford_dataset(s_oxford_data_dir, s_oxford_database_location);
104  // compute_bow(oxford_dataset, s_oxford_num_clusters, 1024, 0);
105  // }
106 
107  {
109  compute_bow(oxford100k_dataset, s_oxford100k_num_clusters, 2048, 0);
110  }
111 
112 #if ENABLE_MULTITHREADING && ENABLE_MPI
113  MPI::Finalize();
114 #endif
115  return 0;
116 }