10 #if ENABLE_FASTCLUSTER
11 #include <fastann/fastann.hpp>
12 #include <fastcluster/kmeans.hpp>
25 std::cerr <<
"Error reading bag of words from " << file_path << std::endl;
28 if(!this->
load(file_path)) {
29 std::cerr <<
"Error reading bag of words from " << file_path << std::endl;
34 std::cout <<
"Reading bag of words from " << file_path <<
"..." << std::endl;
37 std::cerr <<
"Failed to read vocabulary from " << file_path << std::endl;
41 std::cout <<
"Done reading bag of words." << std::endl;
48 std::cout <<
"Writing bag of words to " << file_path <<
"..." << std::endl;
52 std::cerr <<
"Failed to write vocabulary to " << file_path << std::endl;
56 std::cout <<
"Done writing bag of words." << std::endl;
59 #if ENABLE_FASTCLUSTER && ENABLE_MPI
60 void load_rows_in_mem(
void* p,
unsigned l,
unsigned r,
float* out) {
61 float *fp = (
float *)p;
62 memcpy(out, &fp[l * 128] ,
sizeof(
float) * 128 * (r - l));
65 void load_rows_out_mem(
void* p,
unsigned l,
unsigned r,
float* out) {
71 fastann::nn_obj<float>* build_nnobj(
void* p,
float* clusters,
unsigned K,
unsigned D) {
72 fastann::nn_obj<float>* kd_tree = fastann::nn_obj_build_kdtree(clusters, K, D, 8, 512);
77 bool BagOfWords::train(
Dataset &dataset,
const std::shared_ptr<const TrainParamsBase> ¶ms,
const std::vector< std::shared_ptr<const Image > > &examples) {
79 const std::shared_ptr<const TrainParams> &ii_params = std::static_pointer_cast<
const TrainParams>(params);
82 uint32_t n = ii_params->numFeatures;
84 std::vector<uint64_t> all_ids(examples.size());
85 for (uint64_t i = 0; i < examples.size(); i++) {
86 all_ids[i] = examples[i]->id;
88 std::random_shuffle(all_ids.begin(), all_ids.end());
90 std::vector<cv::Mat> all_descriptors;
91 uint64_t num_features = 0;
92 for (
size_t i = 0; i < all_ids.size(); i++) {
93 std::shared_ptr<Image> image = std::static_pointer_cast<
Image>(dataset.
image(all_ids[i]));
94 if (image ==
nullptr)
continue;
96 const std::string &descriptors_location = dataset.
location(image->feature_path(
"descriptors"));
99 cv::Mat descriptors, descriptorsf;
101 num_features += descriptors.rows;
102 if (n > 0 && num_features > n)
break;
103 descriptors.convertTo(descriptorsf, CV_32FC1);
104 all_descriptors.push_back(descriptorsf);
109 #if ENABLE_FASTCLUSTER && ENABLE_MPI
111 int rank = MPI::COMM_WORLD.Get_rank();
113 uint32_t D = merged_descriptor.cols;
114 float *dataf = (
float *)merged_descriptor.data;
120 std::vector<uint64_t> indices(num_features);
121 for(
size_t i=0; i<indices.size(); i++) {
124 std::random_shuffle(indices.begin(), indices.end());
125 for(
size_t i=0; i<k; i++) {
126 memcpy(&clusters[D * i], &dataf[D * indices[i]],
sizeof(
float) * D);
130 fastcluster::kmeans<float>(load_rows_in_mem, (
void *)merged_descriptor.data,
131 build_nnobj, (
void *)merged_descriptor.data,
132 (
float *)clusters, num_features, D, k, 16, 0, (
char *)0);
136 uint32_t attempts = 1;
137 cv::TermCriteria tc(cv::TermCriteria::COUNT | cv::TermCriteria::EPS, 16, 0.0001);
138 if (k > merged_descriptor.rows) {
139 std::cerr <<
"Warning: # clusters > # features, automatically setting #clusters = #features." << std::endl;
140 k = merged_descriptor.rows;
142 cv::kmeans(merged_descriptor, k, labels, tc, attempts, cv::KMEANS_PP_CENTERS,
vocabulary_matrix);
147 std::shared_ptr<MatchResultsBase>
BagOfWords::search(
Dataset &dataset,
const std::shared_ptr<const SearchParamsBase> ¶ms,
const std::shared_ptr<const Image > &example) {